value.go 15.4 KB
Newer Older
Rob Pike's avatar
Rob Pike committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Reflection library.
// Handling values.

package reflect

import (
	"reflect";
)

type Addr uint64	// TODO: where are ptrint/intptr etc?

16
// Conversion functions, implemented in assembler
Russ Cox's avatar
Russ Cox committed
17
type RuntimeArray struct
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
func AddrToPtrAddr(Addr) *Addr
func AddrToPtrInt(Addr) *int
func AddrToPtrInt8(Addr) *int8
func AddrToPtrInt16(Addr) *int16
func AddrToPtrInt32(Addr) *int32
func AddrToPtrInt64(Addr) *int64
func AddrToPtrUint(Addr) *uint
func AddrToPtrUint8(Addr) *uint8
func PtrUint8ToAddr(*uint8) Addr
func AddrToPtrUint16(Addr) *uint16
func AddrToPtrUint32(Addr) *uint32
func AddrToPtrUint64(Addr) *uint64
func PtrUint64ToAddr(*uint64) Addr
func AddrToPtrFloat(Addr) *float
func AddrToPtrFloat32(Addr) *float32
func AddrToPtrFloat64(Addr) *float64
func AddrToPtrFloat80(Addr) *float80
func AddrToPtrString(Addr) *string
func AddrToPtrBool(Addr) *bool
Russ Cox's avatar
Russ Cox committed
37 38
func AddrToPtrRuntimeArray(Addr) *RuntimeArray
func PtrRuntimeArrayToAddr(*RuntimeArray) Addr
39
func AddrToPtrInterface(Addr) *interface{}
40

Rob Pike's avatar
Rob Pike committed
41 42 43
export type Value interface {
	Kind()	int;
	Type()	Type;
44
	Addr()	Addr;
45
	Interface()	interface {};
Rob Pike's avatar
Rob Pike committed
46 47
}

48 49
// Common fields and functionality for all values

Russ Cox's avatar
Russ Cox committed
50
type Common struct {
51 52 53 54 55
	kind	int;
	typ	Type;
	addr	Addr;
}

Russ Cox's avatar
Russ Cox committed
56
func (c *Common) Kind() int {
57 58 59
	return c.kind
}

Russ Cox's avatar
Russ Cox committed
60
func (c *Common) Type() Type {
61 62 63
	return c.typ
}

64 65 66 67
func (c *Common) Addr() Addr {
	return c.addr
}

68
func (c *Common) Interface() interface {} {
69 70 71
	return sys.unreflect(*AddrToPtrAddr(c.addr), c.typ.String());
}

Rob Pike's avatar
Rob Pike committed
72 73 74 75 76
func NewValueAddr(typ Type, addr Addr) Value

type Creator *(typ Type, addr Addr) Value


77 78 79 80 81 82 83 84
// -- Missing

export type MissingValue interface {
	Kind()	int;
	Type()	Type;
}

type MissingValueStruct struct {
Russ Cox's avatar
Russ Cox committed
85
	Common
86 87 88
}

func MissingCreator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
89
	return &MissingValueStruct{ Common{IntKind, typ, addr} }
90 91
}

92 93 94 95 96
// -- Int

export type IntValue interface {
	Kind()	int;
	Get()	int;
Russ Cox's avatar
Russ Cox committed
97
	Set(int);
98 99 100 101
	Type()	Type;
}

type IntValueStruct struct {
Russ Cox's avatar
Russ Cox committed
102
	Common
103 104 105
}

func IntCreator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
106
	return &IntValueStruct{ Common{IntKind, typ, addr} }
107 108 109 110 111 112
}

func (v *IntValueStruct) Get() int {
	return *AddrToPtrInt(v.addr)
}

Russ Cox's avatar
Russ Cox committed
113
func (v *IntValueStruct) Set(i int) {
114 115 116
	*AddrToPtrInt(v.addr) = i
}

Rob Pike's avatar
Rob Pike committed
117 118 119 120 121
// -- Int8

export type Int8Value interface {
	Kind()	int;
	Get()	int8;
Russ Cox's avatar
Russ Cox committed
122
	Set(int8);
Rob Pike's avatar
Rob Pike committed
123 124 125 126
	Type()	Type;
}

type Int8ValueStruct struct {
Russ Cox's avatar
Russ Cox committed
127
	Common
Rob Pike's avatar
Rob Pike committed
128 129
}

130
func Int8Creator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
131
	return &Int8ValueStruct{ Common{Int8Kind, typ, addr} }
Rob Pike's avatar
Rob Pike committed
132 133 134
}

func (v *Int8ValueStruct) Get() int8 {
Rob Pike's avatar
Rob Pike committed
135
	return *AddrToPtrInt8(v.addr)
Rob Pike's avatar
Rob Pike committed
136 137
}

Russ Cox's avatar
Russ Cox committed
138
func (v *Int8ValueStruct) Set(i int8) {
Rob Pike's avatar
Rob Pike committed
139
	*AddrToPtrInt8(v.addr) = i
Rob Pike's avatar
Rob Pike committed
140 141 142 143 144 145 146
}

// -- Int16

export type Int16Value interface {
	Kind()	int;
	Get()	int16;
Russ Cox's avatar
Russ Cox committed
147
	Set(int16);
Rob Pike's avatar
Rob Pike committed
148 149 150 151
	Type()	Type;
}

type Int16ValueStruct struct {
Russ Cox's avatar
Russ Cox committed
152
	Common
Rob Pike's avatar
Rob Pike committed
153 154
}

155
func Int16Creator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
156
	return &Int16ValueStruct{ Common{Int16Kind, typ, addr} }
Rob Pike's avatar
Rob Pike committed
157 158 159
}

func (v *Int16ValueStruct) Get() int16 {
Rob Pike's avatar
Rob Pike committed
160
	return *AddrToPtrInt16(v.addr)
Rob Pike's avatar
Rob Pike committed
161 162
}

Russ Cox's avatar
Russ Cox committed
163
func (v *Int16ValueStruct) Set(i int16) {
Rob Pike's avatar
Rob Pike committed
164
	*AddrToPtrInt16(v.addr) = i
Rob Pike's avatar
Rob Pike committed
165 166 167 168 169 170 171
}

// -- Int32

export type Int32Value interface {
	Kind()	int;
	Get()	int32;
Russ Cox's avatar
Russ Cox committed
172
	Set(int32);
Rob Pike's avatar
Rob Pike committed
173 174 175 176
	Type()	Type;
}

type Int32ValueStruct struct {
Russ Cox's avatar
Russ Cox committed
177
	Common
Rob Pike's avatar
Rob Pike committed
178 179
}

180
func Int32Creator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
181
	return &Int32ValueStruct{ Common{Int32Kind, typ, addr} }
Rob Pike's avatar
Rob Pike committed
182 183 184
}

func (v *Int32ValueStruct) Get() int32 {
Rob Pike's avatar
Rob Pike committed
185
	return *AddrToPtrInt32(v.addr)
Rob Pike's avatar
Rob Pike committed
186 187
}

Russ Cox's avatar
Russ Cox committed
188
func (v *Int32ValueStruct) Set(i int32) {
Rob Pike's avatar
Rob Pike committed
189
	*AddrToPtrInt32(v.addr) = i
Rob Pike's avatar
Rob Pike committed
190 191 192 193 194 195 196
}

// -- Int64

export type Int64Value interface {
	Kind()	int;
	Get()	int64;
Russ Cox's avatar
Russ Cox committed
197
	Set(int64);
Rob Pike's avatar
Rob Pike committed
198 199 200 201
	Type()	Type;
}

type Int64ValueStruct struct {
Russ Cox's avatar
Russ Cox committed
202
	Common
Rob Pike's avatar
Rob Pike committed
203 204
}

Rob Pike's avatar
Rob Pike committed
205
func Int64Creator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
206
	return &Int64ValueStruct{ Common{Int64Kind, typ, addr} }
Rob Pike's avatar
Rob Pike committed
207 208 209
}

func (v *Int64ValueStruct) Get() int64 {
Rob Pike's avatar
Rob Pike committed
210
	return *AddrToPtrInt64(v.addr)
Rob Pike's avatar
Rob Pike committed
211 212
}

Russ Cox's avatar
Russ Cox committed
213
func (v *Int64ValueStruct) Set(i int64) {
Rob Pike's avatar
Rob Pike committed
214
	*AddrToPtrInt64(v.addr) = i
Rob Pike's avatar
Rob Pike committed
215 216
}

217 218 219 220 221
// -- Uint

export type UintValue interface {
	Kind()	int;
	Get()	uint;
Russ Cox's avatar
Russ Cox committed
222
	Set(uint);
223 224 225 226
	Type()	Type;
}

type UintValueStruct struct {
Russ Cox's avatar
Russ Cox committed
227
	Common
228 229 230
}

func UintCreator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
231
	return &UintValueStruct{ Common{UintKind, typ, addr} }
232 233 234 235 236 237
}

func (v *UintValueStruct) Get() uint {
	return *AddrToPtrUint(v.addr)
}

Russ Cox's avatar
Russ Cox committed
238
func (v *UintValueStruct) Set(i uint) {
239 240 241
	*AddrToPtrUint(v.addr) = i
}

Rob Pike's avatar
Rob Pike committed
242 243 244 245 246
// -- Uint8

export type Uint8Value interface {
	Kind()	int;
	Get()	uint8;
Russ Cox's avatar
Russ Cox committed
247
	Set(uint8);
Rob Pike's avatar
Rob Pike committed
248 249 250 251
	Type()	Type;
}

type Uint8ValueStruct struct {
Russ Cox's avatar
Russ Cox committed
252
	Common
Rob Pike's avatar
Rob Pike committed
253 254
}

255
func Uint8Creator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
256
	return &Uint8ValueStruct{ Common{Uint8Kind, typ, addr} }
Rob Pike's avatar
Rob Pike committed
257 258 259
}

func (v *Uint8ValueStruct) Get() uint8 {
Rob Pike's avatar
Rob Pike committed
260
	return *AddrToPtrUint8(v.addr)
Rob Pike's avatar
Rob Pike committed
261 262
}

Russ Cox's avatar
Russ Cox committed
263
func (v *Uint8ValueStruct) Set(i uint8) {
Rob Pike's avatar
Rob Pike committed
264
	*AddrToPtrUint8(v.addr) = i
Rob Pike's avatar
Rob Pike committed
265 266 267 268 269 270 271
}

// -- Uint16

export type Uint16Value interface {
	Kind()	int;
	Get()	uint16;
Russ Cox's avatar
Russ Cox committed
272
	Set(uint16);
Rob Pike's avatar
Rob Pike committed
273 274 275 276
	Type()	Type;
}

type Uint16ValueStruct struct {
Russ Cox's avatar
Russ Cox committed
277
	Common
Rob Pike's avatar
Rob Pike committed
278 279
}

280
func Uint16Creator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
281
	return &Uint16ValueStruct{ Common{Uint16Kind, typ, addr} }
Rob Pike's avatar
Rob Pike committed
282 283 284
}

func (v *Uint16ValueStruct) Get() uint16 {
Rob Pike's avatar
Rob Pike committed
285
	return *AddrToPtrUint16(v.addr)
Rob Pike's avatar
Rob Pike committed
286 287
}

Russ Cox's avatar
Russ Cox committed
288
func (v *Uint16ValueStruct) Set(i uint16) {
Rob Pike's avatar
Rob Pike committed
289
	*AddrToPtrUint16(v.addr) = i
Rob Pike's avatar
Rob Pike committed
290 291 292 293 294 295 296
}

// -- Uint32

export type Uint32Value interface {
	Kind()	int;
	Get()	uint32;
Russ Cox's avatar
Russ Cox committed
297
	Set(uint32);
Rob Pike's avatar
Rob Pike committed
298 299 300 301
	Type()	Type;
}

type Uint32ValueStruct struct {
Russ Cox's avatar
Russ Cox committed
302
	Common
Rob Pike's avatar
Rob Pike committed
303 304
}

305
func Uint32Creator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
306
	return &Uint32ValueStruct{ Common{Uint32Kind, typ, addr} }
Rob Pike's avatar
Rob Pike committed
307 308 309
}

func (v *Uint32ValueStruct) Get() uint32 {
Rob Pike's avatar
Rob Pike committed
310
	return *AddrToPtrUint32(v.addr)
Rob Pike's avatar
Rob Pike committed
311 312
}

Russ Cox's avatar
Russ Cox committed
313
func (v *Uint32ValueStruct) Set(i uint32) {
Rob Pike's avatar
Rob Pike committed
314
	*AddrToPtrUint32(v.addr) = i
Rob Pike's avatar
Rob Pike committed
315 316 317 318 319 320 321
}

// -- Uint64

export type Uint64Value interface {
	Kind()	int;
	Get()	uint64;
Russ Cox's avatar
Russ Cox committed
322
	Set(uint64);
Rob Pike's avatar
Rob Pike committed
323 324 325 326
	Type()	Type;
}

type Uint64ValueStruct struct {
Russ Cox's avatar
Russ Cox committed
327
	Common
Rob Pike's avatar
Rob Pike committed
328 329
}

330
func Uint64Creator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
331
	return &Uint64ValueStruct{ Common{Uint64Kind, typ, addr} }
Rob Pike's avatar
Rob Pike committed
332 333 334
}

func (v *Uint64ValueStruct) Get() uint64 {
Rob Pike's avatar
Rob Pike committed
335
	return *AddrToPtrUint64(v.addr)
Rob Pike's avatar
Rob Pike committed
336 337
}

Russ Cox's avatar
Russ Cox committed
338
func (v *Uint64ValueStruct) Set(i uint64) {
Rob Pike's avatar
Rob Pike committed
339
	*AddrToPtrUint64(v.addr) = i
Rob Pike's avatar
Rob Pike committed
340 341
}

342 343 344 345 346
// -- Float

export type FloatValue interface {
	Kind()	int;
	Get()	float;
Russ Cox's avatar
Russ Cox committed
347
	Set(float);
348 349 350 351
	Type()	Type;
}

type FloatValueStruct struct {
Russ Cox's avatar
Russ Cox committed
352
	Common
353 354 355
}

func FloatCreator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
356
	return &FloatValueStruct{ Common{FloatKind, typ, addr} }
357 358 359 360 361 362
}

func (v *FloatValueStruct) Get() float {
	return *AddrToPtrFloat(v.addr)
}

Russ Cox's avatar
Russ Cox committed
363
func (v *FloatValueStruct) Set(f float) {
364 365 366
	*AddrToPtrFloat(v.addr) = f
}

Rob Pike's avatar
Rob Pike committed
367 368 369 370 371
// -- Float32

export type Float32Value interface {
	Kind()	int;
	Get()	float32;
Russ Cox's avatar
Russ Cox committed
372
	Set(float32);
Rob Pike's avatar
Rob Pike committed
373 374 375 376
	Type()	Type;
}

type Float32ValueStruct struct {
Russ Cox's avatar
Russ Cox committed
377
	Common
Rob Pike's avatar
Rob Pike committed
378 379
}

380
func Float32Creator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
381
	return &Float32ValueStruct{ Common{Float32Kind, typ, addr} }
Rob Pike's avatar
Rob Pike committed
382 383 384
}

func (v *Float32ValueStruct) Get() float32 {
Rob Pike's avatar
Rob Pike committed
385
	return *AddrToPtrFloat32(v.addr)
Rob Pike's avatar
Rob Pike committed
386 387
}

Russ Cox's avatar
Russ Cox committed
388
func (v *Float32ValueStruct) Set(f float32) {
Rob Pike's avatar
Rob Pike committed
389
	*AddrToPtrFloat32(v.addr) = f
Rob Pike's avatar
Rob Pike committed
390 391 392 393 394 395 396
}

// -- Float64

export type Float64Value interface {
	Kind()	int;
	Get()	float64;
Russ Cox's avatar
Russ Cox committed
397
	Set(float64);
Rob Pike's avatar
Rob Pike committed
398 399 400 401
	Type()	Type;
}

type Float64ValueStruct struct {
Russ Cox's avatar
Russ Cox committed
402
	Common
Rob Pike's avatar
Rob Pike committed
403 404
}

405
func Float64Creator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
406
	return &Float64ValueStruct{ Common{Float64Kind, typ, addr} }
Rob Pike's avatar
Rob Pike committed
407 408 409
}

func (v *Float64ValueStruct) Get() float64 {
Rob Pike's avatar
Rob Pike committed
410
	return *AddrToPtrFloat64(v.addr)
Rob Pike's avatar
Rob Pike committed
411 412
}

Russ Cox's avatar
Russ Cox committed
413
func (v *Float64ValueStruct) Set(f float64) {
Rob Pike's avatar
Rob Pike committed
414
	*AddrToPtrFloat64(v.addr) = f
Rob Pike's avatar
Rob Pike committed
415 416 417 418 419 420 421
}

// -- Float80

export type Float80Value interface {
	Kind()	int;
	Get()	float80;
Russ Cox's avatar
Russ Cox committed
422
	Set(float80);
Rob Pike's avatar
Rob Pike committed
423 424 425 426
	Type()	Type;
}

type Float80ValueStruct struct {
Russ Cox's avatar
Russ Cox committed
427
	Common
Rob Pike's avatar
Rob Pike committed
428 429
}

430
func Float80Creator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
431
	return &Float80ValueStruct{ Common{Float80Kind, typ, addr} }
Rob Pike's avatar
Rob Pike committed
432 433 434 435 436
}

/*
BUG: can't gen code for float80s
func (v *Float80ValueStruct) Get() float80 {
Rob Pike's avatar
Rob Pike committed
437
	return *AddrToPtrFloat80(v.addr)
Rob Pike's avatar
Rob Pike committed
438 439 440
	return 0;
}

Russ Cox's avatar
Russ Cox committed
441
func (v *Float80ValueStruct) Set(f float80) {
Rob Pike's avatar
Rob Pike committed
442
	*AddrToPtrFloat80(v.addr) = f
Rob Pike's avatar
Rob Pike committed
443 444 445 446 447 448 449 450
}
*/

// -- String

export type StringValue interface {
	Kind()	int;
	Get()	string;
Russ Cox's avatar
Russ Cox committed
451
	Set(string);
Rob Pike's avatar
Rob Pike committed
452 453 454 455
	Type()	Type;
}

type StringValueStruct struct {
Russ Cox's avatar
Russ Cox committed
456
	Common
Rob Pike's avatar
Rob Pike committed
457 458
}

459
func StringCreator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
460
	return &StringValueStruct{ Common{StringKind, typ, addr} }
Rob Pike's avatar
Rob Pike committed
461 462 463
}

func (v *StringValueStruct) Get() string {
Rob Pike's avatar
Rob Pike committed
464
	return *AddrToPtrString(v.addr)
Rob Pike's avatar
Rob Pike committed
465 466
}

Russ Cox's avatar
Russ Cox committed
467
func (v *StringValueStruct) Set(s string) {
Rob Pike's avatar
Rob Pike committed
468
	*AddrToPtrString(v.addr) = s
Rob Pike's avatar
Rob Pike committed
469 470
}

471 472 473 474 475
// -- Bool

export type BoolValue interface {
	Kind()	int;
	Get()	bool;
Russ Cox's avatar
Russ Cox committed
476
	Set(bool);
477 478 479 480
	Type()	Type;
}

type BoolValueStruct struct {
Russ Cox's avatar
Russ Cox committed
481
	Common
482 483 484
}

func BoolCreator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
485
	return &BoolValueStruct{ Common{BoolKind, typ, addr} }
486 487 488 489 490 491
}

func (v *BoolValueStruct) Get() bool {
	return *AddrToPtrBool(v.addr)
}

Russ Cox's avatar
Russ Cox committed
492
func (v *BoolValueStruct) Set(b bool) {
493 494 495
	*AddrToPtrBool(v.addr) = b
}

Rob Pike's avatar
Rob Pike committed
496 497 498 499 500
// -- Pointer

export type PtrValue interface {
	Kind()	int;
	Type()	Type;
Rob Pike's avatar
Rob Pike committed
501 502
	Sub()	Value;
	Get()	Addr;
503
	SetSub(Value);
Rob Pike's avatar
Rob Pike committed
504 505 506
}

type PtrValueStruct struct {
Russ Cox's avatar
Russ Cox committed
507
	Common
Rob Pike's avatar
Rob Pike committed
508 509
}

Rob Pike's avatar
Rob Pike committed
510
func (v *PtrValueStruct) Get() Addr {
Rob Pike's avatar
Rob Pike committed
511
	return *AddrToPtrAddr(v.addr)
Rob Pike's avatar
Rob Pike committed
512 513
}

Rob Pike's avatar
Rob Pike committed
514
func (v *PtrValueStruct) Sub() Value {
Rob Pike's avatar
Rob Pike committed
515
	return NewValueAddr(v.typ.(PtrType).Sub(), v.Get());
Rob Pike's avatar
Rob Pike committed
516 517
}

518
func (v *PtrValueStruct) SetSub(subv Value)  {
519 520 521 522 523
	a := v.typ.(PtrType).Sub().String();
	b := subv.Type().String();
	if a != b {
		panicln("reflect: incompatible types in PtrValue.SetSub:", a, b);
	}
524 525 526
	*AddrToPtrAddr(v.addr) = subv.Addr();
}

Rob Pike's avatar
Rob Pike committed
527
func PtrCreator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
528
	return &PtrValueStruct{ Common{PtrKind, typ, addr} };
Rob Pike's avatar
Rob Pike committed
529 530
}

531
// -- Array
Rob Pike's avatar
Rob Pike committed
532 533 534 535 536

export type ArrayValue interface {
	Kind()	int;
	Type()	Type;
	Open()	bool;
537
	Len()	int;
Russ Cox's avatar
Russ Cox committed
538
	Cap() int;
539
	Elem(i int)	Value;
Russ Cox's avatar
Russ Cox committed
540
	SetLen(len int);
Rob Pike's avatar
Rob Pike committed
541
}
542

Rob Pike's avatar
Rob Pike committed
543 544 545 546 547
/*
	Run-time representation of open arrays looks like this:
		struct	Array {
			byte*	array;		// actual data
			uint32	nel;		// number of elements
Russ Cox's avatar
Russ Cox committed
548
			uint32	cap;
Rob Pike's avatar
Rob Pike committed
549 550
		};
*/
Russ Cox's avatar
Russ Cox committed
551 552 553 554 555 556 557 558 559 560 561 562
type RuntimeArray struct {
	data	Addr;
	len	uint32;
	cap	uint32;
}

type OpenArrayValueStruct struct {
	Common;
	elemtype	Type;
	elemsize	int;
	array *RuntimeArray;
}
Rob Pike's avatar
Rob Pike committed
563 564 565 566 567

func (v *OpenArrayValueStruct) Open() bool {
	return true
}

568
func (v *OpenArrayValueStruct) Len() int {
Russ Cox's avatar
Russ Cox committed
569 570 571 572 573 574 575 576 577 578 579 580
	return int(v.array.len);
}

func (v *OpenArrayValueStruct) Cap() int {
	return int(v.array.cap);
}

func (v *OpenArrayValueStruct) SetLen(len int) {
	if len > v.Cap() {
		panicln("reflect: OpenArrayValueStruct.SetLen", len, v.Cap());
	}
	v.array.len = uint32(len);
Rob Pike's avatar
Rob Pike committed
581 582
}

583
func (v *OpenArrayValueStruct) Elem(i int) Value {
Russ Cox's avatar
Russ Cox committed
584
	return NewValueAddr(v.elemtype, v.array.data + Addr(i * v.elemsize));
Rob Pike's avatar
Rob Pike committed
585 586 587
}

type FixedArrayValueStruct struct {
Russ Cox's avatar
Russ Cox committed
588
	Common;
Rob Pike's avatar
Rob Pike committed
589
	elemtype	Type;
590 591
	elemsize	int;
	len	int;
Rob Pike's avatar
Rob Pike committed
592 593 594 595 596 597
}

func (v *FixedArrayValueStruct) Open() bool {
	return false
}

598
func (v *FixedArrayValueStruct) Len() int {
Rob Pike's avatar
Rob Pike committed
599 600 601
	return v.len
}

Russ Cox's avatar
Russ Cox committed
602 603 604 605 606 607 608
func (v *FixedArrayValueStruct) Cap() int {
	return v.len
}

func (v *FixedArrayValueStruct) SetLen(len int) {
}

609 610
func (v *FixedArrayValueStruct) Elem(i int) Value {
	return NewValueAddr(v.elemtype, v.addr + Addr(i * v.elemsize));
Rob Pike's avatar
Rob Pike committed
611 612 613 614 615 616 617
	return nil
}

func ArrayCreator(typ Type, addr Addr) Value {
	arraytype := typ.(ArrayType);
	if arraytype.Open() {
		v := new(OpenArrayValueStruct);
618
		v.kind = ArrayKind;
Rob Pike's avatar
Rob Pike committed
619
		v.addr = addr;
Rob Pike's avatar
Rob Pike committed
620
		v.typ = typ;
Rob Pike's avatar
Rob Pike committed
621 622
		v.elemtype = arraytype.Elem();
		v.elemsize = v.elemtype.Size();
Russ Cox's avatar
Russ Cox committed
623
		v.array = AddrToPtrRuntimeArray(addr);
Rob Pike's avatar
Rob Pike committed
624 625 626
		return v;
	}
	v := new(FixedArrayValueStruct);
627
	v.kind = ArrayKind;
Rob Pike's avatar
Rob Pike committed
628
	v.addr = addr;
Rob Pike's avatar
Rob Pike committed
629 630
	v.typ = typ;
	v.elemtype = arraytype.Elem();
Rob Pike's avatar
Rob Pike committed
631 632
	v.elemsize = v.elemtype.Size();
	v.len = arraytype.Len();
Rob Pike's avatar
Rob Pike committed
633 634 635 636 637 638 639 640 641 642 643 644 645
	return v;
}

// -- Map	TODO: finish and test

export type MapValue interface {
	Kind()	int;
	Type()	Type;
	Len()	int;
	Elem(key Value)	Value;
}

type MapValueStruct struct {
Russ Cox's avatar
Russ Cox committed
646
	Common
647 648 649
}

func MapCreator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
650
	return &MapValueStruct{ Common{MapKind, typ, addr} }
Rob Pike's avatar
Rob Pike committed
651 652 653
}

func (v *MapValueStruct) Len() int {
654
	return 0	// TODO: probably want this to be dynamic
Rob Pike's avatar
Rob Pike committed
655 656 657 658 659 660 661 662 663 664 665 666 667 668 669
}

func (v *MapValueStruct) Elem(key Value) Value {
	panic("map value element");
	return nil
}

// -- Chan

export type ChanValue interface {
	Kind()	int;
	Type()	Type;
}

type ChanValueStruct struct {
Russ Cox's avatar
Russ Cox committed
670
	Common
671 672 673
}

func ChanCreator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
674
	return &ChanValueStruct{ Common{ChanKind, typ, addr} }
Rob Pike's avatar
Rob Pike committed
675 676 677 678 679 680 681 682 683 684 685 686
}

// -- Struct

export type StructValue interface {
	Kind()	int;
	Type()	Type;
	Len()	int;
	Field(i int)	Value;
}

type StructValueStruct struct {
Russ Cox's avatar
Russ Cox committed
687
	Common;
Rob Pike's avatar
Rob Pike committed
688 689 690 691 692 693 694 695 696 697 698 699 700 701
	field	*[]Value;
}

func (v *StructValueStruct) Len() int {
	return len(v.field)
}

func (v *StructValueStruct) Field(i int) Value {
	return v.field[i]
}

func StructCreator(typ Type, addr Addr) Value {
	t := typ.(StructType);
	nfield := t.Len();
Russ Cox's avatar
Russ Cox committed
702
	v := &StructValueStruct{ Common{StructKind, typ, addr}, new([]Value, nfield) };
Rob Pike's avatar
Rob Pike committed
703
	for i := 0; i < nfield; i++ {
704
		name, ftype, str, offset := t.Field(i);
705
		v.field[i] = NewValueAddr(ftype, addr + Addr(offset));
Rob Pike's avatar
Rob Pike committed
706 707 708 709 710 711 712 713 714 715
	}
	v.typ = typ;
	return v;
}

// -- Interface

export type InterfaceValue interface {
	Kind()	int;
	Type()	Type;
716
	Get()	interface {};
Rob Pike's avatar
Rob Pike committed
717 718
}

719
type InterfaceValueStruct struct {
Russ Cox's avatar
Russ Cox committed
720
	Common
Rob Pike's avatar
Rob Pike committed
721 722
}

723 724 725 726
func (v *InterfaceValueStruct) Get() interface{} {
	return *AddrToPtrInterface(v.addr);
}

727
func InterfaceCreator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
728
	return &InterfaceValueStruct{ Common{InterfaceKind, typ, addr} }
Rob Pike's avatar
Rob Pike committed
729 730 731 732 733 734 735 736 737
}

// -- Func

export type FuncValue interface {
	Kind()	int;
	Type()	Type;
}

738
type FuncValueStruct struct {
Russ Cox's avatar
Russ Cox committed
739
	Common
Rob Pike's avatar
Rob Pike committed
740 741
}

742
func FuncCreator(typ Type, addr Addr) Value {
Russ Cox's avatar
Russ Cox committed
743
	return &FuncValueStruct{ Common{FuncKind, typ, addr} }
Rob Pike's avatar
Rob Pike committed
744 745 746
}

var creator *map[int] Creator
747
var typecache *map[string] *Type
Rob Pike's avatar
Rob Pike committed
748 749 750

func init() {
	creator = new(map[int] Creator);
751
	creator[MissingKind] = &MissingCreator;
752
	creator[IntKind] = &IntCreator;
Rob Pike's avatar
Rob Pike committed
753 754 755 756
	creator[Int8Kind] = &Int8Creator;
	creator[Int16Kind] = &Int16Creator;
	creator[Int32Kind] = &Int32Creator;
	creator[Int64Kind] = &Int64Creator;
757
	creator[UintKind] = &UintCreator;
Rob Pike's avatar
Rob Pike committed
758 759 760 761
	creator[Uint8Kind] = &Uint8Creator;
	creator[Uint16Kind] = &Uint16Creator;
	creator[Uint32Kind] = &Uint32Creator;
	creator[Uint64Kind] = &Uint64Creator;
762
	creator[FloatKind] = &FloatCreator;
Rob Pike's avatar
Rob Pike committed
763 764 765 766
	creator[Float32Kind] = &Float32Creator;
	creator[Float64Kind] = &Float64Creator;
	creator[Float80Kind] = &Float80Creator;
	creator[StringKind] = &StringCreator;
767
	creator[BoolKind] = &BoolCreator;
Rob Pike's avatar
Rob Pike committed
768 769 770 771 772 773 774
	creator[PtrKind] = &PtrCreator;
	creator[ArrayKind] = &ArrayCreator;
	creator[MapKind] = &MapCreator;
	creator[ChanKind] = &ChanCreator;
	creator[StructKind] = &StructCreator;
	creator[InterfaceKind] = &InterfaceCreator;
	creator[FuncKind] = &FuncCreator;
775 776

	typecache = new(map[string] *Type);
Rob Pike's avatar
Rob Pike committed
777 778 779 780 781 782 783 784 785 786 787
}

func NewValueAddr(typ Type, addr Addr) Value {
	c, ok := creator[typ.Kind()];
	if !ok {
		panicln("no creator for type" , typ.Kind());
	}
	return c(typ, addr);
}

export func NewInitValue(typ Type) Value {
Rob Pike's avatar
Rob Pike committed
788 789 790 791 792 793 794 795 796
	// Some values cannot be made this way.
	switch typ.Kind() {
	case FuncKind, ChanKind, MapKind:	// must be pointers, at least for now (TODO?)
		return nil;
	case ArrayKind:
		if typ.(ArrayType).Open() {
			return nil
		}
	}
Rob Pike's avatar
Rob Pike committed
797 798 799 800 801 802 803 804
	size := typ.Size();
	if size == 0 {
		size = 1;
	}
	data := new([]uint8, size);
	return NewValueAddr(typ, PtrUint8ToAddr(&data[0]));
}

Russ Cox's avatar
Russ Cox committed
805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830
/*
	Run-time representation of open arrays looks like this:
		struct	Array {
			byte*	array;		// actual data
			uint32	nel;		// number of elements
			uint32	cap;		// allocated number of elements
		};
*/
export func NewOpenArrayValue(typ ArrayType, len, cap int) ArrayValue {
	if !typ.Open() {
		return nil
	}

	array := new(RuntimeArray);
	size := typ.Elem().Size() * cap;
	if size == 0 {
		size = 1;
	}
	data := new([]uint8, size);
	array.data = PtrUint8ToAddr(&data[0]);
	array.len = uint32(len);
	array.cap = uint32(cap);

	return NewValueAddr(typ, PtrRuntimeArrayToAddr(array));
}

831
export func NewValue(e interface {}) Value {
Rob Pike's avatar
Rob Pike committed
832
	value, typestring  := sys.reflect(e);
833 834 835 836 837 838 839
	p, ok := typecache[typestring];
	if !ok {
		typ := ParseTypeString("", typestring);
		p = new(Type);
		*p = typ;
		typecache[typestring] = p;
	}
Rob Pike's avatar
Rob Pike committed
840 841 842 843
	// Content of interface is a value; need a permanent copy to take its address
	// so we can modify the contents. Values contain pointers to 'values'.
	ap := new(uint64);
	*ap = value;
844
	return NewValueAddr(*p, PtrUint64ToAddr(ap));
Rob Pike's avatar
Rob Pike committed
845
}