llgo/ssa: unsafeEface
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
Reference in New Issue
Block a user