llgo/ssa: unsafeEface

This commit is contained in:
xushiwei
2024-05-22 13:47:21 +08:00
parent c19786bdfb
commit 6442ab2f20
3 changed files with 38 additions and 23 deletions

View File

@@ -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 { func I2Int(v Eface, t *Type) uintptr {
if v._type == t { if v._type == t {
return uintptr(v.data) return uintptr(v.data)

View File

@@ -31,23 +31,24 @@ import (
func (b Builder) abiBasic(t *types.Basic) Expr { func (b Builder) abiBasic(t *types.Basic) Expr {
name := abi.BasicName(t) name := abi.BasicName(t)
g := b.Pkg.NewVarFrom(name, b.Prog.AbiTypePtrPtr()) 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. // abiStruct returns the abi type of the specified struct type.
func (b Builder) abiStruct(t *types.Struct) Expr { func (b Builder) abiStruct(t *types.Struct) Expr {
pkg := b.Pkg pkg := b.Pkg
name, _ := pkg.abi.StructName(t) name, _ := pkg.abi.StructName(t)
if v := pkg.VarOf(name); v != nil { g := pkg.VarOf(name)
return v.Expr 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() { 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 // 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") 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 // 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) { func (b Builder) makeIntfByPtr(tinter Type, rawIntf *types.Interface, typ Type, vptr Expr) (ret Expr) {
if rawIntf.Empty() { if rawIntf.Empty() {
ret = b.InlineCall(b.Pkg.rtFunc("MakeAny"), b.abiType(typ.raw.Type), vptr) return Expr{b.unsafeEface(b.abiType(typ.raw.Type).impl, vptr.impl), tinter}
ret.Type = tinter
return
} }
panic("todo") panic("todo")
} }
@@ -215,6 +219,10 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) (ret Expr) {
if debugInstr { if debugInstr {
log.Printf("TypeAssert %v, %v, %v\n", x.impl, assertedTyp.raw.Type, commaOk) 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 { switch assertedTyp.kind {
case vkSigned, vkUnsigned, vkFloat, vkBool: case vkSigned, vkUnsigned, vkFloat, vkBool:
pkg := b.Pkg pkg := b.Pkg

View File

@@ -122,7 +122,7 @@ type aProgram struct {
voidPtrTy llvm.Type voidPtrTy llvm.Type
rtStringTy llvm.Type rtStringTy llvm.Type
rtIfaceTy llvm.Type rtEfaceTy llvm.Type
rtSliceTy llvm.Type rtSliceTy llvm.Type
rtMapTy llvm.Type rtMapTy llvm.Type
@@ -145,6 +145,8 @@ type aProgram struct {
pyObjPtr Type pyObjPtr Type
pyObjPPtr Type pyObjPPtr Type
abiTyptr Type abiTyptr Type
abiTypptr Type
efaceTy Type
pyImpTy *types.Signature pyImpTy *types.Signature
pyNewList *types.Signature pyNewList *types.Signature
@@ -245,10 +247,10 @@ func (p Program) rtType(name string) Type {
} }
func (p Program) rtEface() llvm.Type { func (p Program) rtEface() llvm.Type {
if p.rtIfaceTy.IsNil() { if p.rtEfaceTy.IsNil() {
p.rtIfaceTy = p.rtType("Eface").ll p.rtEfaceTy = p.rtType("Eface").ll
} }
return p.rtIfaceTy return p.rtEfaceTy
} }
func (p Program) rtMap() llvm.Type { func (p Program) rtMap() llvm.Type {
@@ -291,6 +293,14 @@ func (p Program) NewPackage(name, pkgPath string) Package {
return ret 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. // AbiTypePtr returns *abi.Type.
func (p Program) AbiTypePtr() Type { func (p Program) AbiTypePtr() Type {
if p.abiTyptr == nil { if p.abiTyptr == nil {
@@ -299,9 +309,12 @@ func (p Program) AbiTypePtr() Type {
return p.abiTyptr return p.abiTyptr
} }
// AbiTypePtr returns **abi.Type. // AbiTypePtrPtr returns **abi.Type.
func (p Program) AbiTypePtrPtr() 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. // PyObjectPtrPtr returns the **py.Object type.