1  
     2  
     3  
     4  
     5  
     6  
     7  
     8  
     9  
    10  
    11  
    12  package rttype
    13  
    14  import (
    15  	"cmd/compile/internal/base"
    16  	"cmd/compile/internal/objw"
    17  	"cmd/compile/internal/types"
    18  	"cmd/internal/obj"
    19  	"internal/abi"
    20  	"reflect"
    21  )
    22  
    23  
    24  var Type *types.Type
    25  
    26  var ArrayType *types.Type
    27  var ChanType *types.Type
    28  var FuncType *types.Type
    29  var InterfaceType *types.Type
    30  var OldMapType *types.Type
    31  var SwissMapType *types.Type
    32  var PtrType *types.Type
    33  var SliceType *types.Type
    34  var StructType *types.Type
    35  
    36  
    37  var IMethod *types.Type
    38  var Method *types.Type
    39  var StructField *types.Type
    40  var UncommonType *types.Type
    41  
    42  
    43  var InterfaceSwitch *types.Type
    44  var TypeAssert *types.Type
    45  
    46  
    47  var ITab *types.Type
    48  
    49  func Init() {
    50  	
    51  	
    52  	
    53  	Type = FromReflect(reflect.TypeOf(abi.Type{}))
    54  	ArrayType = FromReflect(reflect.TypeOf(abi.ArrayType{}))
    55  	ChanType = FromReflect(reflect.TypeOf(abi.ChanType{}))
    56  	FuncType = FromReflect(reflect.TypeOf(abi.FuncType{}))
    57  	InterfaceType = FromReflect(reflect.TypeOf(abi.InterfaceType{}))
    58  	OldMapType = FromReflect(reflect.TypeOf(abi.OldMapType{}))
    59  	SwissMapType = FromReflect(reflect.TypeOf(abi.SwissMapType{}))
    60  	PtrType = FromReflect(reflect.TypeOf(abi.PtrType{}))
    61  	SliceType = FromReflect(reflect.TypeOf(abi.SliceType{}))
    62  	StructType = FromReflect(reflect.TypeOf(abi.StructType{}))
    63  
    64  	IMethod = FromReflect(reflect.TypeOf(abi.Imethod{}))
    65  	Method = FromReflect(reflect.TypeOf(abi.Method{}))
    66  	StructField = FromReflect(reflect.TypeOf(abi.StructField{}))
    67  	UncommonType = FromReflect(reflect.TypeOf(abi.UncommonType{}))
    68  
    69  	InterfaceSwitch = FromReflect(reflect.TypeOf(abi.InterfaceSwitch{}))
    70  	TypeAssert = FromReflect(reflect.TypeOf(abi.TypeAssert{}))
    71  
    72  	ITab = FromReflect(reflect.TypeOf(abi.ITab{}))
    73  
    74  	
    75  	
    76  	
    77  	ptrSize := types.PtrSize
    78  	if got, want := int64(abi.CommonSize(ptrSize)), Type.Size(); got != want {
    79  		base.Fatalf("abi.CommonSize() == %d, want %d", got, want)
    80  	}
    81  	if got, want := int64(abi.StructFieldSize(ptrSize)), StructField.Size(); got != want {
    82  		base.Fatalf("abi.StructFieldSize() == %d, want %d", got, want)
    83  	}
    84  	if got, want := int64(abi.UncommonSize()), UncommonType.Size(); got != want {
    85  		base.Fatalf("abi.UncommonSize() == %d, want %d", got, want)
    86  	}
    87  	if got, want := int64(abi.TFlagOff(ptrSize)), Type.OffsetOf("TFlag"); got != want {
    88  		base.Fatalf("abi.TFlagOff() == %d, want %d", got, want)
    89  	}
    90  	if got, want := int64(abi.ITabTypeOff(ptrSize)), ITab.OffsetOf("Type"); got != want {
    91  		base.Fatalf("abi.ITabTypeOff() == %d, want %d", got, want)
    92  	}
    93  }
    94  
    95  
    96  func FromReflect(rt reflect.Type) *types.Type {
    97  	t := reflectToType(rt)
    98  	types.CalcSize(t)
    99  	return t
   100  }
   101  
   102  
   103  
   104  
   105  func reflectToType(rt reflect.Type) *types.Type {
   106  	switch rt.Kind() {
   107  	case reflect.Bool:
   108  		return types.Types[types.TBOOL]
   109  	case reflect.Int:
   110  		return types.Types[types.TINT]
   111  	case reflect.Int8:
   112  		return types.Types[types.TINT8]
   113  	case reflect.Int16:
   114  		return types.Types[types.TINT16]
   115  	case reflect.Int32:
   116  		return types.Types[types.TINT32]
   117  	case reflect.Uint8:
   118  		return types.Types[types.TUINT8]
   119  	case reflect.Uint16:
   120  		return types.Types[types.TUINT16]
   121  	case reflect.Uint32:
   122  		return types.Types[types.TUINT32]
   123  	case reflect.Float32:
   124  		return types.Types[types.TFLOAT32]
   125  	case reflect.Float64:
   126  		return types.Types[types.TFLOAT64]
   127  	case reflect.Uintptr:
   128  		return types.Types[types.TUINTPTR]
   129  	case reflect.Ptr:
   130  		return types.NewPtr(reflectToType(rt.Elem()))
   131  	case reflect.Func, reflect.UnsafePointer:
   132  		
   133  		
   134  		return types.Types[types.TUNSAFEPTR]
   135  	case reflect.Slice:
   136  		return types.NewSlice(reflectToType(rt.Elem()))
   137  	case reflect.Array:
   138  		return types.NewArray(reflectToType(rt.Elem()), int64(rt.Len()))
   139  	case reflect.Struct:
   140  		fields := make([]*types.Field, rt.NumField())
   141  		for i := 0; i < rt.NumField(); i++ {
   142  			f := rt.Field(i)
   143  			ft := reflectToType(f.Type)
   144  			fields[i] = &types.Field{Sym: &types.Sym{Name: f.Name}, Type: ft}
   145  		}
   146  		return types.NewStruct(fields)
   147  	case reflect.Chan:
   148  		return types.NewChan(reflectToType(rt.Elem()), types.ChanDir(rt.ChanDir()))
   149  	case reflect.String:
   150  		return types.Types[types.TSTRING]
   151  	case reflect.Complex128:
   152  		return types.Types[types.TCOMPLEX128]
   153  	default:
   154  		base.Fatalf("unhandled kind %s", rt.Kind())
   155  		return nil
   156  	}
   157  }
   158  
   159  
   160  
   161  type Cursor struct {
   162  	lsym   *obj.LSym
   163  	offset int64
   164  	typ    *types.Type
   165  }
   166  
   167  
   168  func NewCursor(lsym *obj.LSym, off int64, t *types.Type) Cursor {
   169  	return Cursor{lsym: lsym, offset: off, typ: t}
   170  }
   171  
   172  
   173  func (c Cursor) WritePtr(target *obj.LSym) {
   174  	if c.typ.Kind() != types.TUNSAFEPTR && c.typ.Kind() != types.TPTR {
   175  		base.Fatalf("can't write ptr, it has kind %s", c.typ.Kind())
   176  	}
   177  	if target == nil {
   178  		objw.Uintptr(c.lsym, int(c.offset), 0)
   179  	} else {
   180  		objw.SymPtr(c.lsym, int(c.offset), target, 0)
   181  	}
   182  }
   183  func (c Cursor) WritePtrWeak(target *obj.LSym) {
   184  	if c.typ.Kind() != types.TUINTPTR {
   185  		base.Fatalf("can't write ptr, it has kind %s", c.typ.Kind())
   186  	}
   187  	objw.SymPtrWeak(c.lsym, int(c.offset), target, 0)
   188  }
   189  func (c Cursor) WriteUintptr(val uint64) {
   190  	if c.typ.Kind() != types.TUINTPTR {
   191  		base.Fatalf("can't write uintptr, it has kind %s", c.typ.Kind())
   192  	}
   193  	objw.Uintptr(c.lsym, int(c.offset), val)
   194  }
   195  func (c Cursor) WriteUint32(val uint32) {
   196  	if c.typ.Kind() != types.TUINT32 {
   197  		base.Fatalf("can't write uint32, it has kind %s", c.typ.Kind())
   198  	}
   199  	objw.Uint32(c.lsym, int(c.offset), val)
   200  }
   201  func (c Cursor) WriteUint16(val uint16) {
   202  	if c.typ.Kind() != types.TUINT16 {
   203  		base.Fatalf("can't write uint16, it has kind %s", c.typ.Kind())
   204  	}
   205  	objw.Uint16(c.lsym, int(c.offset), val)
   206  }
   207  func (c Cursor) WriteUint8(val uint8) {
   208  	if c.typ.Kind() != types.TUINT8 {
   209  		base.Fatalf("can't write uint8, it has kind %s", c.typ.Kind())
   210  	}
   211  	objw.Uint8(c.lsym, int(c.offset), val)
   212  }
   213  func (c Cursor) WriteInt(val int64) {
   214  	if c.typ.Kind() != types.TINT {
   215  		base.Fatalf("can't write int, it has kind %s", c.typ.Kind())
   216  	}
   217  	objw.Uintptr(c.lsym, int(c.offset), uint64(val))
   218  }
   219  func (c Cursor) WriteInt32(val int32) {
   220  	if c.typ.Kind() != types.TINT32 {
   221  		base.Fatalf("can't write int32, it has kind %s", c.typ.Kind())
   222  	}
   223  	objw.Uint32(c.lsym, int(c.offset), uint32(val))
   224  }
   225  func (c Cursor) WriteBool(val bool) {
   226  	if c.typ.Kind() != types.TBOOL {
   227  		base.Fatalf("can't write bool, it has kind %s", c.typ.Kind())
   228  	}
   229  	objw.Bool(c.lsym, int(c.offset), val)
   230  }
   231  
   232  
   233  
   234  func (c Cursor) WriteSymPtrOff(target *obj.LSym, weak bool) {
   235  	if c.typ.Kind() != types.TINT32 && c.typ.Kind() != types.TUINT32 {
   236  		base.Fatalf("can't write SymPtr, it has kind %s", c.typ.Kind())
   237  	}
   238  	if target == nil {
   239  		objw.Uint32(c.lsym, int(c.offset), 0)
   240  	} else if weak {
   241  		objw.SymPtrWeakOff(c.lsym, int(c.offset), target)
   242  	} else {
   243  		objw.SymPtrOff(c.lsym, int(c.offset), target)
   244  	}
   245  }
   246  
   247  
   248  func (c Cursor) WriteSlice(target *obj.LSym, off, len, cap int64) {
   249  	if c.typ.Kind() != types.TSLICE {
   250  		base.Fatalf("can't write slice, it has kind %s", c.typ.Kind())
   251  	}
   252  	objw.SymPtr(c.lsym, int(c.offset), target, int(off))
   253  	objw.Uintptr(c.lsym, int(c.offset)+types.PtrSize, uint64(len))
   254  	objw.Uintptr(c.lsym, int(c.offset)+2*types.PtrSize, uint64(cap))
   255  	
   256  	
   257  	if len != cap {
   258  		base.Fatalf("len != cap (%d != %d)", len, cap)
   259  	}
   260  }
   261  
   262  
   263  
   264  func (c Cursor) Reloc(rel obj.Reloc) {
   265  	rel.Off = int32(c.offset)
   266  	rel.Siz = uint8(c.typ.Size())
   267  	c.lsym.AddRel(base.Ctxt, rel)
   268  }
   269  
   270  
   271  func (c Cursor) Field(name string) Cursor {
   272  	if c.typ.Kind() != types.TSTRUCT {
   273  		base.Fatalf("can't call Field on non-struct %v", c.typ)
   274  	}
   275  	for _, f := range c.typ.Fields() {
   276  		if f.Sym.Name == name {
   277  			return Cursor{lsym: c.lsym, offset: c.offset + f.Offset, typ: f.Type}
   278  		}
   279  	}
   280  	base.Fatalf("couldn't find field %s in %v", name, c.typ)
   281  	return Cursor{}
   282  }
   283  
   284  func (c Cursor) Elem(i int64) Cursor {
   285  	if c.typ.Kind() != types.TARRAY {
   286  		base.Fatalf("can't call Elem on non-array %v", c.typ)
   287  	}
   288  	if i < 0 || i >= c.typ.NumElem() {
   289  		base.Fatalf("element access out of bounds [%d] in [0:%d]", i, c.typ.NumElem())
   290  	}
   291  	elem := c.typ.Elem()
   292  	return Cursor{lsym: c.lsym, offset: c.offset + i*elem.Size(), typ: elem}
   293  }
   294  
   295  type ArrayCursor struct {
   296  	c Cursor 
   297  	n int    
   298  }
   299  
   300  
   301  func NewArrayCursor(lsym *obj.LSym, off int64, t *types.Type, n int) ArrayCursor {
   302  	return ArrayCursor{
   303  		c: NewCursor(lsym, off, t),
   304  		n: n,
   305  	}
   306  }
   307  
   308  
   309  func (a ArrayCursor) Elem(i int) Cursor {
   310  	if i < 0 || i >= a.n {
   311  		base.Fatalf("element index %d out of range [0:%d]", i, a.n)
   312  	}
   313  	return Cursor{lsym: a.c.lsym, offset: a.c.offset + int64(i)*a.c.typ.Size(), typ: a.c.typ}
   314  }
   315  
   316  
   317  
   318  
   319  func (c Cursor) ModifyArray(n int) (ArrayCursor, int64) {
   320  	if c.typ.Kind() != types.TARRAY {
   321  		base.Fatalf("can't call ModifyArray on non-array %v", c.typ)
   322  	}
   323  	k := c.typ.NumElem()
   324  	return ArrayCursor{c: Cursor{lsym: c.lsym, offset: c.offset, typ: c.typ.Elem()}, n: n}, (int64(n) - k) * c.typ.Elem().Size()
   325  }
   326  
View as plain text