vkFuncDecl, vkFuncPtr, vkClosure; callback example

This commit is contained in:
xushiwei
2024-05-05 15:59:33 +08:00
parent 03a194a514
commit 067cf0cba6
11 changed files with 136 additions and 38 deletions

View File

@@ -183,7 +183,7 @@ func (b Builder) CStr(v string) Expr {
func (b Builder) Str(v string) (ret Expr) {
prog := b.Prog
cstr := b.CStr(v)
ret = b.InlineCall(b.fn.pkg.rtFunc("NewString"), cstr, prog.Val(len(v)))
ret = b.InlineCall(b.Func.Pkg.rtFunc("NewString"), cstr, prog.Val(len(v)))
ret.Type = prog.String()
return
}
@@ -296,7 +296,7 @@ func (b Builder) BinOp(op token.Token, x, y Expr) Expr {
switch kind {
case vkString:
if op == token.ADD {
pkg := b.fn.pkg
pkg := b.Func.Pkg
return b.InlineCall(pkg.rtFunc("StringCat"), x, y)
}
case vkComplex:
@@ -566,7 +566,7 @@ func (b Builder) IndexAddr(x, idx Expr) Expr {
pt := prog.Pointer(telem)
switch x.raw.Type.Underlying().(type) {
case *types.Slice:
pkg := b.fn.pkg
pkg := b.Func.Pkg
ptr := b.InlineCall(pkg.rtFunc("SliceData"), x)
indices := []llvm.Value{idx.impl}
return Expr{llvm.CreateInBoundsGEP(b.impl, telem.ll, ptr.impl, indices), pt}
@@ -596,7 +596,7 @@ func (b Builder) Index(x, idx Expr, addr func(Expr) Expr) Expr {
panic(fmt.Errorf("invalid operation: cannot index %v", t))
}
telem = prog.rawType(types.Typ[types.Byte])
pkg := b.fn.pkg
pkg := b.Func.Pkg
ptr = b.InlineCall(pkg.rtFunc("StringData"), x)
case *types.Array:
telem = prog.Index(x.Type)
@@ -631,7 +631,7 @@ func (b Builder) Slice(x, low, high, max Expr) (ret Expr) {
log.Printf("Slice %v, %v, %v\n", x.impl, low.impl, high.impl)
}
prog := b.Prog
pkg := b.fn.pkg
pkg := b.Func.Pkg
var nCap Expr
var nEltSize Expr
var base Expr
@@ -693,7 +693,7 @@ func (b Builder) MakeMap(t Type, nReserve Expr) (ret Expr) {
if debugInstr {
log.Printf("MakeMap %v, %v\n", t.RawType(), nReserve.impl)
}
pkg := b.fn.pkg
pkg := b.Func.Pkg
ret.Type = t
ret.impl = b.InlineCall(pkg.rtFunc("MakeSmallMap")).impl
// TODO(xsw): nReserve
@@ -718,7 +718,7 @@ func (b Builder) MakeSlice(t Type, len, cap Expr) (ret Expr) {
if debugInstr {
log.Printf("MakeSlice %v, %v, %v\n", t.RawType(), len.impl, cap.impl)
}
pkg := b.fn.pkg
pkg := b.Func.Pkg
if cap.IsNil() {
cap = len
}
@@ -756,7 +756,7 @@ func (b Builder) Alloc(elem Type, heap bool) (ret Expr) {
log.Printf("Alloc %v, %v\n", elem.RawType(), heap)
}
prog := b.Prog
pkg := b.fn.pkg
pkg := b.Func.Pkg
size := b.SizeOf(elem)
if heap {
ret = b.InlineCall(pkg.rtFunc("AllocZ"), size)
@@ -797,7 +797,7 @@ func (b Builder) AllocaCStr(gostr Expr) (ret Expr) {
if debugInstr {
log.Printf("AllocaCStr %v\n", gostr.impl)
}
pkg := b.fn.pkg
pkg := b.Func.Pkg
n := b.InlineCall(pkg.rtFunc("StringLen"), gostr)
n1 := b.BinOp(token.ADD, n, b.Prog.Val(1))
cstr := b.Alloca(n1)
@@ -931,7 +931,7 @@ func (b Builder) MakeInterface(tinter Type, x Expr, mayDelay bool) (ret Expr) {
isAny := tiund.Empty()
fnDo := func() Expr {
prog := b.Prog
pkg := b.fn.pkg
pkg := b.Func.Pkg
switch tx := x.raw.Type.Underlying().(type) {
case *types.Basic:
kind := tx.Kind()
@@ -998,7 +998,7 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) (ret Expr) {
}
switch assertedTyp.kind {
case vkSigned, vkUnsigned, vkFloat:
pkg := b.fn.pkg
pkg := b.Func.Pkg
fnName := "I2Int"
if commaOk {
fnName = "CheckI2Int"
@@ -1051,20 +1051,25 @@ func (b Builder) Call(fn Expr, args ...Expr) (ret Expr) {
}
log.Println(b.String())
}
var ll llvm.Type
var sig *types.Signature
var raw = fn.raw.Type
switch fn.kind {
case vkClosure:
fn := b.Field(fn, 0)
fn = b.Field(fn, 0)
raw = fn.raw.Type
fallthrough
case vkFunc:
case vkFuncPtr:
sig = raw.(*types.Signature)
ret.Type = prog.retType(sig)
ll = prog.FuncDecl(sig, InC).ll
case vkFuncDecl:
sig = raw.(*types.Signature)
ll = fn.ll
default:
panic("unreachable")
}
ret.impl = llvm.CreateCall(b.impl, fn.ll, fn.impl, llvmValues(args, sig.Params(), b))
ret.Type = prog.retType(sig)
ret.impl = llvm.CreateCall(b.impl, ll, fn.impl, llvmValues(args, sig.Params(), b))
return
}
@@ -1081,10 +1086,10 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
arg := args[0]
switch t := arg.raw.Type.Underlying().(type) {
case *types.Slice:
return b.InlineCall(b.fn.pkg.rtFunc("SliceLen"), arg)
return b.InlineCall(b.Func.Pkg.rtFunc("SliceLen"), arg)
case *types.Basic:
if t.Kind() == types.String {
return b.InlineCall(b.fn.pkg.rtFunc("StringLen"), arg)
return b.InlineCall(b.Func.Pkg.rtFunc("StringLen"), arg)
}
}
}
@@ -1093,7 +1098,7 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
arg := args[0]
switch arg.raw.Type.Underlying().(type) {
case *types.Slice:
return b.InlineCall(b.fn.pkg.rtFunc("SliceCap"), arg)
return b.InlineCall(b.Func.Pkg.rtFunc("SliceCap"), arg)
}
}
}