mirror of
https://github.com/golang/go
synced 2024-09-25 13:20:13 -06:00
beginnings of reflection values.
R=rsc DELTA=421 (357 added, 17 deleted, 47 changed) OCL=17388 CL=17401
This commit is contained in:
parent
35eebcacc8
commit
265e73ee14
@ -3,7 +3,7 @@
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
# DO NOT EDIT. Automatically generated by gobuild.
|
||||
# gobuild -m reflect tostring.go type.go
|
||||
# gobuild -m reflect tostring.go type.go value.go cast_amd64.s
|
||||
O=6
|
||||
GC=$(O)g
|
||||
CC=$(O)c -w
|
||||
@ -32,16 +32,23 @@ clean:
|
||||
|
||||
O1=\
|
||||
type.$O\
|
||||
cast_amd64.$O\
|
||||
|
||||
O2=\
|
||||
value.$O\
|
||||
|
||||
O3=\
|
||||
tostring.$O\
|
||||
|
||||
$(PKG): a1 a2
|
||||
$(PKG): a1 a2 a3
|
||||
a1: $(O1)
|
||||
$(AR) grc $(PKG) $(O1)
|
||||
a2: $(O2)
|
||||
$(AR) grc $(PKG) $(O2)
|
||||
a3: $(O3)
|
||||
$(AR) grc $(PKG) $(O3)
|
||||
|
||||
$(O1): nuke
|
||||
$(O2): a1
|
||||
$(O3): a2
|
||||
|
||||
|
133
usr/r/reflect/cast_amd64.s
Normal file
133
usr/r/reflect/cast_amd64.s
Normal file
@ -0,0 +1,133 @@
|
||||
// Conversion operators - really just casts
|
||||
// *** Created by gencast.sh - Do Not Edit ***
|
||||
|
||||
TEXT reflect·AddrToPtrAddr(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·PtrAddrToAddr(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·AddrToPtrInt8(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·PtrInt8ToAddr(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·AddrToPtrInt16(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·PtrInt16ToAddr(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·AddrToPtrInt32(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·PtrInt32ToAddr(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·AddrToPtrInt64(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·PtrInt64ToAddr(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·AddrToPtrUint8(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·PtrUint8ToAddr(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·AddrToPtrUint16(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·PtrUint16ToAddr(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·AddrToPtrUint32(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·PtrUint32ToAddr(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·AddrToPtrUint64(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·PtrUint64ToAddr(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·AddrToPtrFloat32(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·PtrFloat32ToAddr(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·AddrToPtrFloat64(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·PtrFloat64ToAddr(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·AddrToPtrFloat80(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·PtrFloat80ToAddr(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·AddrToPtrString(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
||||
TEXT reflect·PtrStringToAddr(SB),7,$-8
|
||||
MOVQ 8(SP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
RET
|
||||
|
36
usr/r/reflect/gencast.sh
Executable file
36
usr/r/reflect/gencast.sh
Executable file
@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
# 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.
|
||||
|
||||
awk '
|
||||
BEGIN {
|
||||
print("// Conversion operators - really just casts")
|
||||
print("// *** Created by gencast.sh - Do Not Edit ***\n")}
|
||||
{
|
||||
print("TEXT reflect·AddrToPtr" $0 "(SB),7,$-8")
|
||||
print("\tMOVQ 8(SP), AX")
|
||||
print("\tMOVQ AX, 16(SP)")
|
||||
print("\tRET")
|
||||
print("")
|
||||
print("TEXT reflect·Ptr" $0 "ToAddr(SB),7,$-8")
|
||||
print("\tMOVQ 8(SP), AX")
|
||||
print("\tMOVQ AX, 16(SP)")
|
||||
print("\tRET")
|
||||
print("")
|
||||
}
|
||||
' > cast_$GOARCH.s << '!'
|
||||
Addr
|
||||
Int8
|
||||
Int16
|
||||
Int32
|
||||
Int64
|
||||
Uint8
|
||||
Uint16
|
||||
Uint32
|
||||
Uint64
|
||||
Float32
|
||||
Float64
|
||||
Float80
|
||||
String
|
||||
!
|
@ -8,37 +8,79 @@ import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func typedump(s string) {
|
||||
t := reflect.ParseTypeString(s);
|
||||
print(reflect.TypeToString(t),"; size = ", t.Size(), "\n");
|
||||
}
|
||||
|
||||
func valuedump(s string) {
|
||||
t := reflect.ParseTypeString(s);
|
||||
v := reflect.NewInitValue(t);
|
||||
switch v.Kind() {
|
||||
case reflect.Int8Kind:
|
||||
v.(reflect.Int8Value).Put(8);
|
||||
case reflect.Int16Kind:
|
||||
v.(reflect.Int16Value).Put(16);
|
||||
case reflect.Int32Kind:
|
||||
v.(reflect.Int32Value).Put(32);
|
||||
case reflect.Int64Kind:
|
||||
v.(reflect.Int64Value).Put(64);
|
||||
case reflect.Uint8Kind:
|
||||
v.(reflect.Uint8Value).Put(8);
|
||||
case reflect.Uint16Kind:
|
||||
v.(reflect.Uint16Value).Put(16);
|
||||
case reflect.Uint32Kind:
|
||||
v.(reflect.Uint32Value).Put(32);
|
||||
case reflect.Uint64Kind:
|
||||
v.(reflect.Uint64Value).Put(64);
|
||||
case reflect.Float32Kind:
|
||||
v.(reflect.Float32Value).Put(320.0);
|
||||
case reflect.Float64Kind:
|
||||
v.(reflect.Float32Value).Put(640.0);
|
||||
case reflect.StringKind:
|
||||
v.(reflect.StringValue).Put("stringy cheese");
|
||||
}
|
||||
print(s, " value = ", reflect.ValueToString(v), "\n");
|
||||
}
|
||||
|
||||
func main() {
|
||||
var s string;
|
||||
var t reflect.Type;
|
||||
|
||||
t = reflect.ParseTypeString("int8");
|
||||
s = reflect.ToString(t); print(s, "\n");
|
||||
|
||||
t = reflect.ParseTypeString("**int8");
|
||||
s = reflect.ToString(t); print(s, "\n");
|
||||
|
||||
t = reflect.ParseTypeString("**P.integer");
|
||||
s = reflect.ToString(t); print(s, "\n");
|
||||
|
||||
t = reflect.ParseTypeString("[32]int32");
|
||||
s = reflect.ToString(t); print(s, "\n");
|
||||
|
||||
t = reflect.ParseTypeString("[]int8");
|
||||
s = reflect.ToString(t); print(s, "\n");
|
||||
|
||||
t = reflect.ParseTypeString("map[string]int32");
|
||||
s = reflect.ToString(t); print(s, "\n");
|
||||
|
||||
t = reflect.ParseTypeString("*chan<-string");
|
||||
s = reflect.ToString(t); print(s, "\n");
|
||||
|
||||
t = reflect.ParseTypeString("struct {c *chan *int32; d float32}");
|
||||
s = reflect.ToString(t); print(s, "\n");
|
||||
|
||||
t = reflect.ParseTypeString("*(a int8, b int32)");
|
||||
s = reflect.ToString(t); print(s, "\n");
|
||||
|
||||
t = reflect.ParseTypeString("struct {c *(? *chan *P.integer, ? *int8)}");
|
||||
s = reflect.ToString(t); print(s, "\n");
|
||||
|
||||
typedump("int8");
|
||||
typedump("int16");
|
||||
typedump("int32");
|
||||
typedump("int64");
|
||||
typedump("uint8");
|
||||
typedump("uint16");
|
||||
typedump("uint32");
|
||||
typedump("uint64");
|
||||
typedump("float32");
|
||||
typedump("float64");
|
||||
typedump("float80");
|
||||
typedump("int8");
|
||||
typedump("**int8");
|
||||
typedump("**P.integer");
|
||||
typedump("[32]int32");
|
||||
typedump("[]int8");
|
||||
typedump("*map[string]int32");
|
||||
typedump("*chan<-string");
|
||||
typedump("struct {c *chan *int32; d float32}");
|
||||
typedump("*(a int8, b int32)");
|
||||
typedump("struct {c *(? *chan *P.integer, ? *int8)}");
|
||||
typedump("struct {a int8; b int32}");
|
||||
typedump("struct {a int8; b int8; b int32}");
|
||||
typedump("struct {a int8; b int8; c int8; b int32}");
|
||||
typedump("struct {a int8; b int8; c int8; d int8; b int32}");
|
||||
typedump("struct {a int8; b int8; c int8; d int8; e int8; b int32}");
|
||||
|
||||
valuedump("int8");
|
||||
valuedump("int16");
|
||||
valuedump("int32");
|
||||
valuedump("int64");
|
||||
valuedump("uint8");
|
||||
valuedump("uint16");
|
||||
valuedump("uint32");
|
||||
valuedump("uint64");
|
||||
valuedump("string");
|
||||
}
|
||||
|
@ -12,14 +12,15 @@ import (
|
||||
"strings";
|
||||
)
|
||||
|
||||
export func ToString(typ Type) string
|
||||
export func TypeToString(typ Type) string
|
||||
export func ValueToString(val Value) string
|
||||
|
||||
func FieldsToString(t Type, sep string) string {
|
||||
func TypeFieldsToString(t Type, sep string) string {
|
||||
s := t.(StructType);
|
||||
var str string;
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
str1, t := s.Field(i);
|
||||
str1 += " " + ToString(t);
|
||||
str1 += " " + TypeToString(t);
|
||||
if i < s.Len() - 1 {
|
||||
str1 += sep + " ";
|
||||
}
|
||||
@ -28,7 +29,7 @@ func FieldsToString(t Type, sep string) string {
|
||||
return str;
|
||||
}
|
||||
|
||||
func ToString(typ Type) string {
|
||||
func TypeToString(typ Type) string {
|
||||
var str string;
|
||||
switch(typ.Kind()) {
|
||||
case MissingKind:
|
||||
@ -59,7 +60,7 @@ func ToString(typ Type) string {
|
||||
return "string";
|
||||
case PtrKind:
|
||||
p := typ.(PtrType);
|
||||
return "*" + ToString(p.Sub());
|
||||
return "*" + TypeToString(p.Sub());
|
||||
case ArrayKind:
|
||||
a := typ.(ArrayType);
|
||||
if a.Len() < 0 {
|
||||
@ -67,11 +68,11 @@ func ToString(typ Type) string {
|
||||
} else {
|
||||
str = "[" + strings.itoa(a.Len()) + "]"
|
||||
}
|
||||
return str + ToString(a.Elem());
|
||||
return str + TypeToString(a.Elem());
|
||||
case MapKind:
|
||||
m := typ.(MapType);
|
||||
str = "map[" + ToString(m.Key()) + "]";
|
||||
return str + ToString(m.Elem());
|
||||
str = "map[" + TypeToString(m.Key()) + "]";
|
||||
return str + TypeToString(m.Elem());
|
||||
case ChanKind:
|
||||
c := typ.(ChanType);
|
||||
switch c.Dir() {
|
||||
@ -82,23 +83,67 @@ func ToString(typ Type) string {
|
||||
case BothDir:
|
||||
str = "chan";
|
||||
default:
|
||||
panicln("reflect.ToString: unknown chan direction");
|
||||
panicln("reflect.TypeToString: unknown chan direction");
|
||||
}
|
||||
return str + ToString(c.Elem());
|
||||
return str + TypeToString(c.Elem());
|
||||
case StructKind:
|
||||
return "struct{" + FieldsToString(typ, ";") + "}";
|
||||
return "struct{" + TypeFieldsToString(typ, ";") + "}";
|
||||
case InterfaceKind:
|
||||
return "interface{" + FieldsToString(typ, ";") + "}";
|
||||
return "interface{" + TypeFieldsToString(typ, ";") + "}";
|
||||
case FuncKind:
|
||||
f := typ.(FuncType);
|
||||
str = "func";
|
||||
str += "(" + FieldsToString(f.In(), ",") + ")";
|
||||
str += "(" + TypeFieldsToString(f.In(), ",") + ")";
|
||||
if f.Out() != nil {
|
||||
str += "(" + FieldsToString(f.Out(), ",") + ")";
|
||||
str += "(" + TypeFieldsToString(f.Out(), ",") + ")";
|
||||
}
|
||||
return str;
|
||||
default:
|
||||
panicln("reflect.ToString: can't print type ", typ.Kind());
|
||||
panicln("reflect.TypeToString: can't print type ", typ.Kind());
|
||||
}
|
||||
return "reflect.ToString: can't happen";
|
||||
return "reflect.TypeToString: can't happen";
|
||||
}
|
||||
|
||||
// TODO: want an unsigned one too
|
||||
func integer(v int64) string {
|
||||
return strings.itol(v);
|
||||
}
|
||||
|
||||
func ValueToString(val Value) string {
|
||||
var str string;
|
||||
typ := val.Type();
|
||||
switch(val.Kind()) {
|
||||
case MissingKind:
|
||||
return "missing";
|
||||
case Int8Kind:
|
||||
return integer(int64(val.(Int8Value).Get()));
|
||||
case Int16Kind:
|
||||
return integer(int64(val.(Int16Value).Get()));
|
||||
case Int32Kind:
|
||||
return integer(int64(val.(Int32Value).Get()));
|
||||
case Int64Kind:
|
||||
return integer(int64(val.(Int64Value).Get()));
|
||||
case Uint8Kind:
|
||||
return integer(int64(val.(Uint8Value).Get()));
|
||||
case Uint16Kind:
|
||||
return integer(int64(val.(Uint16Value).Get()));
|
||||
case Uint32Kind:
|
||||
return integer(int64(val.(Uint32Value).Get()));
|
||||
case Uint64Kind:
|
||||
return integer(int64(val.(Uint64Value).Get()));
|
||||
case Float32Kind:
|
||||
return "float32";
|
||||
case Float64Kind:
|
||||
return "float64";
|
||||
case Float80Kind:
|
||||
return "float80";
|
||||
case StringKind:
|
||||
return val.(StringValue).Get();
|
||||
case PtrKind:
|
||||
p := typ.(PtrType);
|
||||
return ValueToString(p.Sub());
|
||||
default:
|
||||
panicln("reflect.ValueToString: can't print type ", val.Kind());
|
||||
}
|
||||
return "reflect.ValueToString: can't happen";
|
||||
}
|
||||
|
@ -36,45 +36,58 @@ export const (
|
||||
Uint8Kind;
|
||||
)
|
||||
|
||||
var ptrsize int
|
||||
var interfacesize int
|
||||
|
||||
var MissingString = "missing" // syntactic name for undefined type names
|
||||
|
||||
type Type interface {
|
||||
export type Type interface {
|
||||
Kind() int;
|
||||
Size() int;
|
||||
}
|
||||
|
||||
// -- Basic
|
||||
|
||||
type BasicType struct{
|
||||
kind int
|
||||
kind int;
|
||||
size int;
|
||||
}
|
||||
|
||||
func (t *BasicType) Kind() int {
|
||||
return t.kind
|
||||
}
|
||||
|
||||
func NewBasicType(k int) Type {
|
||||
func (t *BasicType) Size() int {
|
||||
return t.size
|
||||
}
|
||||
|
||||
func NewBasicType(k, size int) Type {
|
||||
t := new(BasicType);
|
||||
t.kind = k;
|
||||
t.size = size;
|
||||
return t;
|
||||
}
|
||||
|
||||
// Basic types
|
||||
// Prebuilt basic types
|
||||
export var (
|
||||
Missing = NewBasicType(MissingKind);
|
||||
Int8 = NewBasicType(Int8Kind);
|
||||
Int16 = NewBasicType(Int16Kind);
|
||||
Int32 = NewBasicType(Int32Kind);
|
||||
Int64 = NewBasicType(Int64Kind);
|
||||
Uint8 = NewBasicType(Uint8Kind);
|
||||
Uint16 = NewBasicType(Uint16Kind);
|
||||
Uint32 = NewBasicType(Uint32Kind);
|
||||
Uint64 = NewBasicType(Uint64Kind);
|
||||
Float32 = NewBasicType(Float32Kind);
|
||||
Float64 = NewBasicType(Float64Kind);
|
||||
Float80 = NewBasicType(Float80Kind);
|
||||
String = NewBasicType(StringKind);
|
||||
Missing = NewBasicType(MissingKind, 1);
|
||||
Int8 = NewBasicType(Int8Kind, 1);
|
||||
Int16 = NewBasicType(Int16Kind, 2);
|
||||
Int32 = NewBasicType(Int32Kind, 4);
|
||||
Int64 = NewBasicType(Int64Kind, 8);
|
||||
Uint8 = NewBasicType(Uint8Kind, 1);
|
||||
Uint16 = NewBasicType(Uint16Kind, 2);
|
||||
Uint32 = NewBasicType(Uint32Kind, 4);
|
||||
Uint64 = NewBasicType(Uint64Kind, 8);
|
||||
Float32 = NewBasicType(Float32Kind, 4);
|
||||
Float64 = NewBasicType(Float64Kind, 8);
|
||||
Float80 = NewBasicType(Float80Kind, 10); // TODO: strange size?
|
||||
String = NewBasicType(StringKind, 8); // implemented as a pointer
|
||||
)
|
||||
|
||||
// Stub types allow us to defer evaluating type names until needed.
|
||||
// If the name is empty, the type must be non-nil.
|
||||
|
||||
type StubType struct {
|
||||
name string;
|
||||
typ Type;
|
||||
@ -99,6 +112,8 @@ func NewNamedStubType(n string) *StubType {
|
||||
return s;
|
||||
}
|
||||
|
||||
// -- Pointer
|
||||
|
||||
export type PtrType interface {
|
||||
Sub() Type
|
||||
}
|
||||
@ -111,6 +126,10 @@ func (t *PtrTypeStruct) Kind() int {
|
||||
return PtrKind
|
||||
}
|
||||
|
||||
func (t *PtrTypeStruct) Size() int {
|
||||
return ptrsize
|
||||
}
|
||||
|
||||
func (t *PtrTypeStruct) Sub() Type {
|
||||
return t.sub.Get()
|
||||
}
|
||||
@ -121,6 +140,8 @@ func NewPtrTypeStruct(sub *StubType) *PtrTypeStruct {
|
||||
return t;
|
||||
}
|
||||
|
||||
// -- Array
|
||||
|
||||
export type ArrayType interface {
|
||||
Len() int;
|
||||
Elem() Type;
|
||||
@ -135,6 +156,13 @@ func (t *ArrayTypeStruct) Kind() int {
|
||||
return ArrayKind
|
||||
}
|
||||
|
||||
func (t *ArrayTypeStruct) Size() int {
|
||||
if t.len < 0 {
|
||||
return ptrsize // open arrays are pointers to structures
|
||||
}
|
||||
return t.len * t.elem.Get().Size();
|
||||
}
|
||||
|
||||
func (t *ArrayTypeStruct) Len() int {
|
||||
// -1 is open array? TODO
|
||||
return t.len
|
||||
@ -151,6 +179,8 @@ func NewArrayTypeStruct(len int, elem *StubType) *ArrayTypeStruct {
|
||||
return t;
|
||||
}
|
||||
|
||||
// -- Map
|
||||
|
||||
export type MapType interface {
|
||||
Key() Type;
|
||||
Elem() Type;
|
||||
@ -165,6 +195,11 @@ func (t *MapTypeStruct) Kind() int {
|
||||
return MapKind
|
||||
}
|
||||
|
||||
func (t *MapTypeStruct) Size() int {
|
||||
panic("reflect.type: map.Size(): cannot happen");
|
||||
return 0
|
||||
}
|
||||
|
||||
func (t *MapTypeStruct) Key() Type {
|
||||
return t.key.Get()
|
||||
}
|
||||
@ -180,6 +215,8 @@ func NewMapTypeStruct(key, elem *StubType) *MapTypeStruct {
|
||||
return t;
|
||||
}
|
||||
|
||||
// -- Chan
|
||||
|
||||
export type ChanType interface {
|
||||
Dir() int;
|
||||
Elem() Type;
|
||||
@ -199,6 +236,11 @@ type ChanTypeStruct struct {
|
||||
func (t *ChanTypeStruct) Kind() int {
|
||||
return ChanKind
|
||||
}
|
||||
|
||||
func (t *ChanTypeStruct) Size() int {
|
||||
panic("reflect.type: chan.Size(): cannot happen");
|
||||
return 0
|
||||
}
|
||||
|
||||
func (t *ChanTypeStruct) Dir() int {
|
||||
// -1 is open array? TODO
|
||||
@ -216,6 +258,8 @@ func NewChanTypeStruct(dir int, elem *StubType) *ChanTypeStruct {
|
||||
return t;
|
||||
}
|
||||
|
||||
// -- Struct
|
||||
|
||||
export type StructType interface {
|
||||
Field(int) (name string, typ Type);
|
||||
Len() int;
|
||||
@ -224,6 +268,7 @@ export type StructType interface {
|
||||
type Field struct {
|
||||
name string;
|
||||
typ *StubType;
|
||||
size int;
|
||||
}
|
||||
|
||||
type StructTypeStruct struct {
|
||||
@ -234,6 +279,25 @@ func (t *StructTypeStruct) Kind() int {
|
||||
return StructKind
|
||||
}
|
||||
|
||||
// TODO: not portable; depends on 6g
|
||||
func (t *StructTypeStruct) Size() int {
|
||||
size := 0;
|
||||
for i := 0; i < len(t.field); i++ {
|
||||
elemsize := t.field[i].typ.Get().Size();
|
||||
// pad until at (elemsize mod 8) boundary
|
||||
align := elemsize - 1;
|
||||
if align > 7 { // BUG: we know structs are at 8-aligned
|
||||
align = 7
|
||||
}
|
||||
if align > 0 {
|
||||
size = (size + align) & ^align;
|
||||
}
|
||||
size += elemsize;
|
||||
}
|
||||
size = (size + 7) & ^7;
|
||||
return size;
|
||||
}
|
||||
|
||||
func (t *StructTypeStruct) Field(i int) (name string, typ Type) {
|
||||
return t.field[i].name, t.field[i].typ.Get()
|
||||
}
|
||||
@ -248,6 +312,8 @@ func NewStructTypeStruct(field *[]Field) *StructTypeStruct {
|
||||
return t;
|
||||
}
|
||||
|
||||
// -- Interface
|
||||
|
||||
export type InterfaceType interface {
|
||||
Field(int) (name string, typ Type);
|
||||
Len() int;
|
||||
@ -275,6 +341,12 @@ func (t *InterfaceTypeStruct) Kind() int {
|
||||
return InterfaceKind
|
||||
}
|
||||
|
||||
func (t *InterfaceTypeStruct) Size() int {
|
||||
return interfacesize
|
||||
}
|
||||
|
||||
// -- Func
|
||||
|
||||
export type FuncType interface {
|
||||
In() StructType;
|
||||
Out() StructType;
|
||||
@ -289,6 +361,11 @@ func (t *FuncTypeStruct) Kind() int {
|
||||
return FuncKind
|
||||
}
|
||||
|
||||
func (t *FuncTypeStruct) Size() int {
|
||||
panic("reflect.type: func.Size(): cannot happen");
|
||||
return 0
|
||||
}
|
||||
|
||||
func (t *FuncTypeStruct) In() StructType {
|
||||
return t.in
|
||||
}
|
||||
@ -330,6 +407,9 @@ func Unlock() {
|
||||
}
|
||||
|
||||
func init() {
|
||||
ptrsize = 8; // TODO: compute this
|
||||
interfacesize = 2*ptrsize; // TODO: compute this
|
||||
|
||||
lockchan = new(chan bool, 1); // unlocked at creation - buffer is empty
|
||||
Lock(); // not necessary because of init ordering but be safe.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user