// _ [4]byte
// fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
// }
- o := objw.SymPtr(lsym, 0, writeType(iface), 0)
- o = objw.SymPtr(lsym, o, writeType(typ), 0)
- o = objw.Uint32(lsym, o, types.TypeHash(typ)) // copy of type hash
- o += 4 // skip unused field
+ c := rttype.NewCursor(lsym, 0, rttype.ITab)
+ c.Field("Inter").WritePtr(writeType(iface))
+ c.Field("Type").WritePtr(writeType(typ))
+ c.Field("Hash").WriteUint32(types.TypeHash(typ)) // copy of type hash
+
+ var delta int64
+ c = c.Field("Fun")
if !completeItab {
// If typ doesn't implement iface, make method entries be zero.
- o = objw.Uintptr(lsym, o, 0)
- entries = entries[:0]
- }
- for _, fn := range entries {
- o = objw.SymPtrWeak(lsym, o, fn, 0) // method pointer for each method
+ c.Elem(0).WriteUintptr(0)
+ } else {
+ var a rttype.ArrayCursor
+ a, delta = c.ModifyArray(len(entries))
+ for i, fn := range entries {
+ a.Elem(i).WritePtrWeak(fn) // method pointer for each method
+ }
}
// Nothing writes static itabs, so they are read only.
- objw.Global(lsym, int32(o), int16(obj.DUPOK|obj.RODATA))
+ objw.Global(lsym, int32(rttype.ITab.Size()+delta), int16(obj.DUPOK|obj.RODATA))
lsym.Set(obj.AttrContentAddressable, true)
}
var InterfaceSwitch *types.Type
var TypeAssert *types.Type
+// Interface tables (itabs)
+var ITab *types.Type
+
func Init() {
// Note: this has to be called explicitly instead of being
// an init function so it runs after the types package has
InterfaceSwitch = fromReflect(reflect.TypeOf(abi.InterfaceSwitch{}))
TypeAssert = fromReflect(reflect.TypeOf(abi.TypeAssert{}))
+ ITab = fromReflect(reflect.TypeOf(abi.ITab{}))
+
// Make sure abi functions are correct. These functions are used
// by the linker which doesn't have the ability to do type layout,
// so we check the functions it uses here.
objw.SymPtr(c.lsym, int(c.offset), target, 0)
}
}
+func (c Cursor) WritePtrWeak(target *obj.LSym) {
+ if c.typ.Kind() != types.TUINTPTR {
+ base.Fatalf("can't write ptr, it has kind %s", c.typ.Kind())
+ }
+ objw.SymPtrWeak(c.lsym, int(c.offset), target, 0)
+}
func (c Cursor) WriteUintptr(val uint64) {
if c.typ.Kind() != types.TUINTPTR {
base.Fatalf("can't write uintptr, it has kind %s", c.typ.Kind())
return Cursor{}
}
+func (c Cursor) Elem(i int64) Cursor {
+ if c.typ.Kind() != types.TARRAY {
+ base.Fatalf("can't call Elem on non-array %v", c.typ)
+ }
+ if i < 0 || i >= c.typ.NumElem() {
+ base.Fatalf("element access out of bounds [%d] in [0:%d]", i, c.typ.NumElem())
+ }
+ elem := c.typ.Elem()
+ return Cursor{lsym: c.lsym, offset: c.offset + i*elem.Size(), typ: elem}
+}
+
type ArrayCursor struct {
c Cursor // cursor pointing at first element
n int // number of elements