llgo/ssa: Imethod

This commit is contained in:
xushiwei
2024-05-27 09:46:07 +08:00
parent eba08334d1
commit 8536fe4987
6 changed files with 41 additions and 78 deletions

View File

@@ -900,15 +900,6 @@ func (b Builder) InlineCall(fn Expr, args ...Expr) (ret Expr) {
return b.Call(fn, args...)
}
// The Icall instruction represents a interface method call.
//
// Example printed form:
//
// t7 = invoke t5.Println(...t6)
func (b Builder) Icall(o Expr, method *types.Func, args ...Expr) (ret Expr) {
panic("todo")
}
// The Call instruction represents a function call.
//
// The Call instruction yields the function result if there is exactly
@@ -1079,11 +1070,10 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
typ = prog.Float64()
case vkSlice:
fn = "PrintSlice"
case vkPtr, vkFuncPtr, vkFuncDecl:
fn = "PrintPointer"
typ = prog.VoidPtr()
case vkClosure:
arg = b.Field(arg, 0)
fallthrough
case vkPtr, vkFuncPtr, vkFuncDecl:
fn = "PrintPointer"
typ = prog.VoidPtr()
case vkString:

View File

@@ -226,6 +226,31 @@ func (b Builder) unsafeInterface(rawIntf *types.Interface, t Expr, data llvm.Val
return b.unsafeIface(itab.impl, data)
}
func iMethodOf(rawIntf *types.Interface, method *types.Func) int {
name := method.Name()
n := rawIntf.NumMethods()
for i := 0; i < n; i++ {
m := rawIntf.Method(i)
if m.Name() == name {
// TODO(xsw): check signature
return i
}
}
return -1
}
// Imethod returns closure of an interface method.
func (b Builder) Imethod(intf Expr, method *types.Func) Expr {
prog := b.Prog
rawIntf := intf.raw.Type.Underlying().(*types.Interface)
i := iMethodOf(rawIntf, method)
impl := intf.impl
itab := Expr{b.faceItab(impl), prog.VoidPtrPtr()}
pfn := b.Advance(itab, prog.IntVal(uint64(i+3), prog.Int()))
tclosure := prog.Type(method.Type(), InGo)
return b.aggregateValue(tclosure, b.Load(pfn).impl, b.faceData(impl))
}
// -----------------------------------------------------------------------------
// MakeInterface constructs an instance of an interface type from a
@@ -427,6 +452,10 @@ func (b Builder) faceData(x llvm.Value) llvm.Value {
return llvm.CreateExtractValue(b.impl, x, 1)
}
func (b Builder) faceItab(x llvm.Value) llvm.Value {
return llvm.CreateExtractValue(b.impl, x, 0)
}
func (b Builder) faceAbiType(x Expr) Expr {
if x.kind == vkIface {
panic("todo")

View File

@@ -132,6 +132,7 @@ type aProgram struct {
anyTy Type
voidTy Type
voidPtr Type
voidPPtr Type
boolTy Type
cstrTy Type
cintTy Type
@@ -371,6 +372,13 @@ func (p Program) VoidPtr() Type {
return p.voidPtr
}
func (p Program) VoidPtrPtr() Type {
if p.voidPPtr == nil {
p.voidPPtr = p.rawType(types.NewPointer(types.Typ[types.UnsafePointer]))
}
return p.voidPPtr
}
// Bool returns bool type.
func (p Program) Bool() Type {
if p.boolTy == nil {

View File

@@ -66,27 +66,6 @@ func (p Program) FuncDecl(sig *types.Signature, bg Background) Type {
return &aType{p.toLLVMFunc(sig), rawType{sig}, vkFuncDecl}
}
/*
// cvtCxFunc converts a C extended function type into raw type.
func cvtCxFunc(sig *types.Signature, recv *types.Var) *types.Signature {
if sig.Variadic() {
// convert printf-like function type
tParams := sig.Params()
n := tParams.Len()
params := make([]*types.Var, n)
n--
for i := 0; i < n; i++ {
params[i] = tParams.At(i)
}
params[n] = VArg()
sig = types.NewSignatureType(nil, nil, nil, types.NewTuple(params...), sig.Results(), true)
panic("todo")
}
sig = FuncAddCtx(recv, sig)
return sig
}
*/
// Closure creates a closture type for a function.
func (p Program) Closure(fn Type) Type {
sig := fn.raw.Type.(*types.Signature)