diff --git a/internal/runtime/z_eface.go b/internal/runtime/z_eface.go index 03095088..a0f96d03 100644 --- a/internal/runtime/z_eface.go +++ b/internal/runtime/z_eface.go @@ -39,12 +39,6 @@ func MakeAnyString(data string) Eface { } } -func MakeAny(typ *Type, data unsafe.Pointer) Eface { - return eface{ - _type: typ, data: data, - } -} - func I2Int(v Eface, t *Type) uintptr { if v._type == t { return uintptr(v.data) diff --git a/ssa/interface.go b/ssa/interface.go index 84f7fe04..e497cae9 100644 --- a/ssa/interface.go +++ b/ssa/interface.go @@ -31,23 +31,24 @@ import ( func (b Builder) abiBasic(t *types.Basic) Expr { name := abi.BasicName(t) g := b.Pkg.NewVarFrom(name, b.Prog.AbiTypePtrPtr()) - return g.Expr + return b.Load(g.Expr) } // abiStruct returns the abi type of the specified struct type. func (b Builder) abiStruct(t *types.Struct) Expr { pkg := b.Pkg name, _ := pkg.abi.StructName(t) - if v := pkg.VarOf(name); v != nil { - return v.Expr + g := pkg.VarOf(name) + if g == nil { + prog := b.Prog + g := pkg.doNewVar(name, prog.AbiTypePtrPtr()) + g.Init(prog.Null(g.Type)) } - prog := b.Prog - g := pkg.doNewVar(name, prog.AbiTypePtrPtr()) - g.Init(prog.Null(g.Type)) pkg.abitys = append(pkg.abitys, func() { - b.structOf(t) + tabi := b.structOf(t) + b.Store(g.Expr, tabi) }) - return g.Expr + return b.Load(g.Expr) } // func Struct(size uintptr, pkgPath string, fields []abi.StructField) *abi.Type @@ -91,6 +92,11 @@ func (b Builder) abiType(raw types.Type) Expr { panic("todo") } +// unsafeEface(t *abi.Type, data unsafe.Pointer) Eface +func (b Builder) unsafeEface(t, data llvm.Value) llvm.Value { + return aggregateValue(b.impl, b.Prog.rtEface(), t, data) +} + // ----------------------------------------------------------------------------- // MakeInterface constructs an instance of an interface type from a @@ -155,9 +161,7 @@ func (b Builder) makeIntfAlloc(tinter Type, rawIntf *types.Interface, typ Type, func (b Builder) makeIntfByPtr(tinter Type, rawIntf *types.Interface, typ Type, vptr Expr) (ret Expr) { if rawIntf.Empty() { - ret = b.InlineCall(b.Pkg.rtFunc("MakeAny"), b.abiType(typ.raw.Type), vptr) - ret.Type = tinter - return + return Expr{b.unsafeEface(b.abiType(typ.raw.Type).impl, vptr.impl), tinter} } panic("todo") } @@ -215,6 +219,10 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) (ret Expr) { if debugInstr { log.Printf("TypeAssert %v, %v, %v\n", x.impl, assertedTyp.raw.Type, commaOk) } + // TODO(xsw) + // if x.kind != vkEface { + // panic("todo: non empty interface") + // } switch assertedTyp.kind { case vkSigned, vkUnsigned, vkFloat, vkBool: pkg := b.Pkg diff --git a/ssa/package.go b/ssa/package.go index e5960391..879e38ee 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -122,7 +122,7 @@ type aProgram struct { voidPtrTy llvm.Type rtStringTy llvm.Type - rtIfaceTy llvm.Type + rtEfaceTy llvm.Type rtSliceTy llvm.Type rtMapTy llvm.Type @@ -145,6 +145,8 @@ type aProgram struct { pyObjPtr Type pyObjPPtr Type abiTyptr Type + abiTypptr Type + efaceTy Type pyImpTy *types.Signature pyNewList *types.Signature @@ -245,10 +247,10 @@ func (p Program) rtType(name string) Type { } func (p Program) rtEface() llvm.Type { - if p.rtIfaceTy.IsNil() { - p.rtIfaceTy = p.rtType("Eface").ll + if p.rtEfaceTy.IsNil() { + p.rtEfaceTy = p.rtType("Eface").ll } - return p.rtIfaceTy + return p.rtEfaceTy } func (p Program) rtMap() llvm.Type { @@ -291,6 +293,14 @@ func (p Program) NewPackage(name, pkgPath string) Package { return ret } +// Eface returns the empty interface type. +func (p Program) Eface() Type { + if p.efaceTy == nil { + p.efaceTy = p.rawType(tyAny) + } + return p.efaceTy +} + // AbiTypePtr returns *abi.Type. func (p Program) AbiTypePtr() Type { if p.abiTyptr == nil { @@ -299,9 +309,12 @@ func (p Program) AbiTypePtr() Type { return p.abiTyptr } -// AbiTypePtr returns **abi.Type. +// AbiTypePtrPtr returns **abi.Type. func (p Program) AbiTypePtrPtr() Type { - return p.Pointer(p.AbiTypePtr()) + if p.abiTypptr == nil { + p.abiTypptr = p.Pointer(p.AbiTypePtr()) + } + return p.abiTypptr } // PyObjectPtrPtr returns the **py.Object type.