Commit a7b4e9f0 authored by Russ Cox's avatar Russ Cox

new reflect type.go implementation

R=r
DELTA=179  (172 added, 6 deleted, 1 changed)
OCL=31215
CL=31220
parent 769919c4
...@@ -39,7 +39,7 @@ type commonType struct { ...@@ -39,7 +39,7 @@ type commonType struct {
type method struct { type method struct {
hash uint32; hash uint32;
name *string; name *string;
PkgPath *string; pkgPath *string;
typ *runtime.Type; typ *runtime.Type;
ifn unsafe.Pointer; ifn unsafe.Pointer;
tfn unsafe.Pointer; tfn unsafe.Pointer;
...@@ -149,12 +149,6 @@ type ArrayType struct { ...@@ -149,12 +149,6 @@ type ArrayType struct {
len uintptr; len uintptr;
} }
// SliceType represents a slice type.
type SliceType struct {
commonType;
elem *runtime.Type;
}
// ChanDir represents a channel type's direction. // ChanDir represents a channel type's direction.
type ChanDir int type ChanDir int
const ( const (
...@@ -205,6 +199,12 @@ type PtrType struct { ...@@ -205,6 +199,12 @@ type PtrType struct {
elem *runtime.Type; elem *runtime.Type;
} }
// SliceType represents a slice type.
type SliceType struct {
commonType;
elem *runtime.Type;
}
// Struct field // Struct field
type structField struct { type structField struct {
name *string; name *string;
...@@ -279,83 +279,168 @@ type Type interface { ...@@ -279,83 +279,168 @@ type Type interface {
func toType(i interface{}) Type func toType(i interface{}) Type
func (t *uncommonType) Name() (pkgPath string, name string) { func (t *uncommonType) Name() (pkgPath string, name string) {
if t == nil {
return;
}
if t.pkgPath != nil {
pkgPath = *t.pkgPath;
}
if t.name != nil {
name = *t.name;
}
return;
} }
func (t *commonType) String() string { func (t *commonType) String() string {
return *t.string;
} }
func (t *commonType) Size() uintptr { func (t *commonType) Size() uintptr {
return t.size;
} }
func (t *commonType) Align() int { func (t *commonType) Align() int {
return int(t.align);
} }
func (t *commonType) FieldAlign() int { func (t *commonType) FieldAlign() int {
return int(t.fieldAlign);
} }
func (t *uncommonType) Method(i int) (m Method) { func (t *uncommonType) Method(i int) (m Method) {
if t == nil || i < 0 || i >= len(t.methods) {
return;
}
p := &t.methods[i];
if p.name != nil {
m.Name = *p.name;
}
if p.pkgPath != nil {
m.PkgPath = *p.pkgPath;
}
m.Type = toType(*p.typ).(*FuncType);
fn := p.tfn;
m.Func = newFuncValue(m.Type, addr(&fn));
return;
} }
func (t *uncommonType) NumMethod() int { func (t *uncommonType) NumMethod() int {
if t == nil {
return 0;
}
return len(t.methods);
}
// TODO(rsc): 6g supplies these, but they are not
// as efficient as they could be: they have commonType
// as the receiver instead of *commonType.
func (t *commonType) NumMethod() int {
return t.uncommonType.NumMethod();
}
func (t *commonType) Method(i int) (m Method) {
return t.uncommonType.Method(i);
}
func (t *commonType) Name() (pkgPath string, name string) {
return t.uncommonType.Name();
} }
// Len returns the number of elements in the array. // Len returns the number of elements in the array.
func (t *ArrayType) Len() int { func (t *ArrayType) Len() int {
return int(t.len);
} }
// Elem returns the type of the array's elements. // Elem returns the type of the array's elements.
func (t *ArrayType) Elem() Type { func (t *ArrayType) Elem() Type {
return toType(*t.elem);
} }
// Dir returns the channel direction. // Dir returns the channel direction.
func (t *ChanType) Dir() ChanDir { func (t *ChanType) Dir() ChanDir {
return ChanDir(t.dir);
} }
// Elem returns the channel's element type. // Elem returns the channel's element type.
func (t *ChanType) Elem() Type { func (t *ChanType) Elem() Type {
return toType(*t.elem);
} }
func (d ChanDir) String() string { func (d ChanDir) String() string {
switch d {
case SendDir:
return "chan<-";
case RecvDir:
return "<-chan";
case BothDir:
return "chan";
}
return "ChanDir" + strconv.Itoa(int(d));
} }
// In returns the type of the i'th function input parameter. // In returns the type of the i'th function input parameter.
func (t *FuncType) In(i int) Type { func (t *FuncType) In(i int) Type {
if i < 0 || i >= len(t.in) {
return nil;
}
return toType(*t.in[i]);
} }
// NumIn returns the number of input parameters. // NumIn returns the number of input parameters.
func (t *FuncType) NumIn() int { func (t *FuncType) NumIn() int {
return len(t.in);
} }
// Out returns the type of the i'th function output parameter. // Out returns the type of the i'th function output parameter.
func (t *FuncType) Out(i int) Type { func (t *FuncType) Out(i int) Type {
if i < 0 || i >= len(t.out) {
return nil;
}
return toType(*t.out[i]);
} }
// NumOut returns the number of function output parameters. // NumOut returns the number of function output parameters.
func (t *FuncType) NumOut() int { func (t *FuncType) NumOut() int {
return len(t.out);
} }
// Method returns the i'th interface method. // Method returns the i'th interface method.
func (t *InterfaceType) Method(i int) (m Method) { func (t *InterfaceType) Method(i int) (m Method) {
if i < 0 || i >= len(t.methods) {
return;
}
p := t.methods[i];
m.Name = *p.name;
if p.pkgPath != nil {
m.PkgPath = *p.pkgPath;
}
m.Type = toType(*p.typ).(*FuncType);
return;
} }
// NumMethod returns the number of interface methods. // NumMethod returns the number of interface methods.
func (t *InterfaceType) NumMethod() int { func (t *InterfaceType) NumMethod() int {
return len(t.methods);
} }
// Key returns the map key type. // Key returns the map key type.
func (t *MapType) Key() Type { func (t *MapType) Key() Type {
return toType(*t.key);
} }
// Elem returns the map element type. // Elem returns the map element type.
func (t *MapType) Elem() Type { func (t *MapType) Elem() Type {
return toType(*t.elem);
} }
// Elem returns the pointer element type. // Elem returns the pointer element type.
func (t *PtrType) Elem() Type { func (t *PtrType) Elem() Type {
return toType(*t.elem);
} }
// Elem returns the type of the slice's elements. // Elem returns the type of the slice's elements.
func (t *SliceType) Elem() Type { func (t *SliceType) Elem() Type {
return toType(*t.elem);
} }
type StructField struct { type StructField struct {
...@@ -369,10 +454,91 @@ type StructField struct { ...@@ -369,10 +454,91 @@ type StructField struct {
// Field returns the i'th struct field. // Field returns the i'th struct field.
func (t *StructType) Field(i int) (f StructField) { func (t *StructType) Field(i int) (f StructField) {
if i < 0 || i >= len(t.fields) {
return;
}
p := t.fields[i];
f.Type = toType(*p.typ);
if p.name != nil {
f.Name = *p.name;
} else {
nam, pkg := f.Type.Name();
f.Name = nam;
f.Anonymous = true;
}
if p.pkgPath != nil {
f.PkgPath = *p.pkgPath;
}
if p.tag != nil {
f.Tag = *p.tag;
}
f.Offset = p.offset;
return;
} }
// NumField returns the number of struct fields. // NumField returns the number of struct fields.
func (t *StructType) NumField() int { func (t *StructType) NumField() int {
return len(t.fields);
}
// Convert runtime type to reflect type.
// Same memory layouts, different method sets.
func toType(i interface{}) Type {
switch v := i.(type) {
case *runtime.BoolType:
return (*BoolType)(unsafe.Pointer(v));
case *runtime.DotDotDotType:
return (*DotDotDotType)(unsafe.Pointer(v));
case *runtime.FloatType:
return (*FloatType)(unsafe.Pointer(v));
case *runtime.Float32Type:
return (*Float32Type)(unsafe.Pointer(v));
case *runtime.Float64Type:
return (*Float64Type)(unsafe.Pointer(v));
case *runtime.IntType:
return (*IntType)(unsafe.Pointer(v));
case *runtime.Int8Type:
return (*Int8Type)(unsafe.Pointer(v));
case *runtime.Int16Type:
return (*Int16Type)(unsafe.Pointer(v));
case *runtime.Int32Type:
return (*Int32Type)(unsafe.Pointer(v));
case *runtime.Int64Type:
return (*Int64Type)(unsafe.Pointer(v));
case *runtime.StringType:
return (*StringType)(unsafe.Pointer(v));
case *runtime.UintType:
return (*UintType)(unsafe.Pointer(v));
case *runtime.Uint8Type:
return (*Uint8Type)(unsafe.Pointer(v));
case *runtime.Uint16Type:
return (*Uint16Type)(unsafe.Pointer(v));
case *runtime.Uint32Type:
return (*Uint32Type)(unsafe.Pointer(v));
case *runtime.Uint64Type:
return (*Uint64Type)(unsafe.Pointer(v));
case *runtime.UintptrType:
return (*UintptrType)(unsafe.Pointer(v));
case *runtime.UnsafePointerType:
return (*UnsafePointerType)(unsafe.Pointer(v));
case *runtime.ArrayType:
return (*ArrayType)(unsafe.Pointer(v));
case *runtime.ChanType:
return (*ChanType)(unsafe.Pointer(v));
case *runtime.FuncType:
return (*FuncType)(unsafe.Pointer(v));
case *runtime.InterfaceType:
return (*InterfaceType)(unsafe.Pointer(v));
case *runtime.MapType:
return (*MapType)(unsafe.Pointer(v));
case *runtime.PtrType:
return (*PtrType)(unsafe.Pointer(v));
case *runtime.SliceType:
return (*SliceType)(unsafe.Pointer(v));
case *runtime.StructType:
return (*StructType)(unsafe.Pointer(v));
}
panicln("toType", i);
} }
// ArrayOrSliceType is the common interface implemented // ArrayOrSliceType is the common interface implemented
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment