mirror of
https://github.com/golang/go
synced 2024-11-17 00:34:48 -07:00
cmd/compile: generate itabs using rttype mechanism
Change-Id: I9a85704c57e978c8c6303b21da3e4627d3446f3e Reviewed-on: https://go-review.googlesource.com/c/go/+/549455 Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
parent
e0ee5b1afa
commit
977803e796
@ -1331,20 +1331,25 @@ func writeITab(lsym *obj.LSym, typ, iface *types.Type, allowNonImplement bool) {
|
||||
// _ [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)
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,9 @@ var UncommonType *types.Type
|
||||
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
|
||||
@ -64,6 +67,8 @@ func Init() {
|
||||
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.
|
||||
@ -154,6 +159,12 @@ func (c Cursor) WritePtr(target *obj.LSym) {
|
||||
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())
|
||||
@ -250,6 +261,17 @@ func (c Cursor) Field(name string) Cursor {
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user