diff --git a/cl/_testrt/callback/in.go b/cl/_testrt/callback/in.go index 3e2466f5..833bb900 100644 --- a/cl/_testrt/callback/in.go +++ b/cl/_testrt/callback/in.go @@ -4,12 +4,15 @@ import ( "github.com/goplus/llgo/internal/runtime/c" ) -func callback(f func()) { - f() +func callback(msg *c.Char, f func(*c.Char)) { + f(msg) +} + +func print(msg *c.Char) { + c.Printf(msg) } func main() { - callback(func() { - c.Printf(c.Str("Hello, callback\n")) - }) + callback(c.Str("Hello\n"), print) + callback(c.Str("callback\n"), print) } diff --git a/cl/_testrt/callback/out.ll b/cl/_testrt/callback/out.ll index af9f93d3..6156c095 100644 --- a/cl/_testrt/callback/out.ll +++ b/cl/_testrt/callback/out.ll @@ -2,12 +2,14 @@ source_filename = "main" @"main.init$guard" = global ptr null -@0 = private unnamed_addr constant [17 x i8] c"Hello, callback\0A\00", align 1 +@0 = private unnamed_addr constant [7 x i8] c"Hello\0A\00", align 1 +@1 = private unnamed_addr constant [10 x i8] c"callback\0A\00", align 1 -define void @main.callback({ ptr, ptr } %0) { +define void @main.callback(ptr %0, { ptr, ptr } %1) { _llgo_0: - %1 = extractvalue { ptr, ptr } %0, 0 - call void %1() + %2 = extractvalue { ptr, ptr } %1, 1 + %3 = extractvalue { ptr, ptr } %1, 0 + call void %3(ptr %2, ptr %0) ret void } @@ -30,19 +32,40 @@ _llgo_0: call void @main.init() %0 = alloca { ptr, ptr }, align 8 %1 = getelementptr inbounds { ptr, ptr }, ptr %0, i32 0, i32 0 - store ptr @"main.main$1", ptr %1, align 8 + store ptr @__llgo_stub.main.print, ptr %1, align 8 %2 = getelementptr inbounds { ptr, ptr }, ptr %0, i32 0, i32 1 store ptr null, ptr %2, align 8 %3 = load { ptr, ptr }, ptr %0, align 8 - call void @main.callback({ ptr, ptr } %3) + call void @main.callback(ptr @0, { ptr, ptr } %3) + %4 = alloca { ptr, ptr }, align 8 + %5 = getelementptr inbounds { ptr, ptr }, ptr %4, i32 0, i32 0 + store ptr @__llgo_stub.main.print, ptr %5, align 8 + %6 = getelementptr inbounds { ptr, ptr }, ptr %4, i32 0, i32 1 + store ptr null, ptr %6, align 8 + %7 = load { ptr, ptr }, ptr %4, align 8 + call void @main.callback(ptr @1, { ptr, ptr } %7) ret void } +define void @main.print(ptr %0) { +_llgo_0: + %1 = call i32 (ptr, ...) @printf(ptr %0) + ret void + %2 = call i32 (ptr, ...) @printf(ptr %0) + ret void + %3 = call i32 (ptr, ...) @printf(ptr %0) + ret void + +_llgo_01: ; No predecessors! + +_llgo_02: ; No predecessors! +} + declare void @"github.com/goplus/llgo/internal/runtime.init"() -define void @"main.main$1"() { +define void @__llgo_stub.main.print(ptr %0, ptr %1) { _llgo_0: - %0 = call i32 (ptr, ...) @printf(ptr @0) + call void @main.print(ptr %1) ret void } diff --git a/internal/llgen/llgen.go b/internal/llgen/llgen.go index d56b809e..fafcb959 100644 --- a/internal/llgen/llgen.go +++ b/internal/llgen/llgen.go @@ -71,6 +71,11 @@ func Gen(pkgPath, inFile string, src any) string { } prog := llssa.NewProgram(nil) + prog.SetRuntime(func() *types.Package { + rt, err := imp.Import(llssa.PkgRuntime) + check(err) + return rt + }) ret, err := cl.NewPackage(prog, ssaPkg, files) check(err) diff --git a/ssa/package.go b/ssa/package.go index a0de6d0b..e58cff70 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -377,6 +377,7 @@ func (p Package) closureStub(b Builder, t *types.Struct, v Expr) Expr { } else { sig := v.raw.Type.(*types.Signature) n := sig.Params().Len() + nret := sig.Results().Len() ctx := types.NewParam(token.NoPos, nil, ClosureCtx, types.Typ[types.UnsafePointer]) sig = FuncAddCtx(ctx, sig) fn := p.NewFunc(ClosureStub+name, sig, InC) @@ -385,7 +386,13 @@ func (p Package) closureStub(b Builder, t *types.Struct, v Expr) Expr { args[i] = fn.Param(i + 1) } b := fn.MakeBody(1) - b.Return(b.Call(v, args...)) + call := b.Call(v, args...) + switch nret { + case 0: + b.impl.CreateRetVoid() + default: // TODO(xsw): support multiple return values + b.impl.CreateRet(call.impl) + } p.stubs[name] = fn v = fn.Expr }