closureStub
This commit is contained in:
@@ -22,11 +22,12 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0
|
|||||||
br i1 %8, label %_llgo_2, label %_llgo_3
|
br i1 %8, label %_llgo_2, label %_llgo_3
|
||||||
|
|
||||||
_llgo_2: ; preds = %_llgo_1
|
_llgo_2: ; preds = %_llgo_1
|
||||||
%9 = extractvalue { ptr, ptr } %1, 0
|
%9 = extractvalue { ptr, ptr } %1, 1
|
||||||
%10 = call i32 %9()
|
%10 = extractvalue { ptr, ptr } %1, 0
|
||||||
%11 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %4)
|
%11 = call i32 %10(ptr %9)
|
||||||
%12 = getelementptr inbounds i32, ptr %11, i64 %7
|
%12 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %4)
|
||||||
store i32 %10, ptr %12, align 4
|
%13 = getelementptr inbounds i32, ptr %12, i64 %7
|
||||||
|
store i32 %11, ptr %13, align 4
|
||||||
br label %_llgo_1
|
br label %_llgo_1
|
||||||
|
|
||||||
_llgo_3: ; preds = %_llgo_1
|
_llgo_3: ; preds = %_llgo_1
|
||||||
@@ -54,7 +55,7 @@ _llgo_0:
|
|||||||
store i32 1, ptr %0, align 4
|
store i32 1, ptr %0, align 4
|
||||||
%1 = alloca { ptr, ptr }, align 8
|
%1 = alloca { ptr, ptr }, align 8
|
||||||
%2 = getelementptr inbounds { ptr, ptr }, ptr %1, i32 0, i32 0
|
%2 = getelementptr inbounds { ptr, ptr }, ptr %1, i32 0, i32 0
|
||||||
store ptr @rand, ptr %2, align 8
|
store ptr @__llgo_stub.rand, ptr %2, align 8
|
||||||
%3 = getelementptr inbounds { ptr, ptr }, ptr %1, i32 0, i32 1
|
%3 = getelementptr inbounds { ptr, ptr }, ptr %1, i32 0, i32 1
|
||||||
store ptr null, ptr %3, align 8
|
store ptr null, ptr %3, align 8
|
||||||
%4 = load { ptr, ptr }, ptr %1, align 8
|
%4 = load { ptr, ptr }, ptr %1, align 8
|
||||||
@@ -118,6 +119,12 @@ declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
|||||||
|
|
||||||
declare i32 @rand()
|
declare i32 @rand()
|
||||||
|
|
||||||
|
define i32 @__llgo_stub.rand(ptr %0) {
|
||||||
|
_llgo_0:
|
||||||
|
%1 = call i32 @rand()
|
||||||
|
ret i32 %1
|
||||||
|
}
|
||||||
|
|
||||||
declare i32 @printf(ptr, ...)
|
declare i32 @printf(ptr, ...)
|
||||||
|
|
||||||
define i32 @"main.main$1"({ ptr } %0) {
|
define i32 @"main.main$1"({ ptr } %0) {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
ClosureCtx = "__llgo_ctx"
|
ClosureCtx = "__llgo_ctx"
|
||||||
|
ClosureStub = "__llgo_stub."
|
||||||
NameValist = "__llgo_va_list"
|
NameValist = "__llgo_va_list"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -358,10 +358,7 @@ func (b Builder) UnOp(op token.Token, x Expr) Expr {
|
|||||||
func checkExpr(v Expr, t types.Type, b Builder) Expr {
|
func checkExpr(v Expr, t types.Type, b Builder) Expr {
|
||||||
if t, ok := t.(*types.Struct); ok && isClosure(t) {
|
if t, ok := t.(*types.Struct); ok && isClosure(t) {
|
||||||
if v.kind != vkClosure {
|
if v.kind != vkClosure {
|
||||||
log.Panicln("checkExpr:", v.impl.Name())
|
return b.Func.Pkg.closureStub(b, t, v)
|
||||||
prog := b.Prog
|
|
||||||
nilVal := prog.Null(prog.VoidPtr()).impl
|
|
||||||
return b.aggregateValue(prog.rawType(t), v.impl, nilVal)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package ssa
|
package ssa
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"go/token"
|
||||||
"go/types"
|
"go/types"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
@@ -223,10 +224,11 @@ func (p Program) NewPackage(name, pkgPath string) Package {
|
|||||||
mod := p.ctx.NewModule(pkgPath)
|
mod := p.ctx.NewModule(pkgPath)
|
||||||
// TODO(xsw): Finalize may cause panic, so comment it.
|
// TODO(xsw): Finalize may cause panic, so comment it.
|
||||||
// mod.Finalize()
|
// mod.Finalize()
|
||||||
fns := make(map[string]Function)
|
|
||||||
gbls := make(map[string]Global)
|
gbls := make(map[string]Global)
|
||||||
|
fns := make(map[string]Function)
|
||||||
|
stubs := make(map[string]Function)
|
||||||
p.needRuntime = false
|
p.needRuntime = false
|
||||||
return &aPackage{mod, fns, gbls, p}
|
return &aPackage{mod, gbls, fns, stubs, p}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Void returns void type.
|
// Void returns void type.
|
||||||
@@ -310,8 +312,9 @@ func (p Program) Float64() Type {
|
|||||||
// and unspecified other things too.
|
// and unspecified other things too.
|
||||||
type aPackage struct {
|
type aPackage struct {
|
||||||
mod llvm.Module
|
mod llvm.Module
|
||||||
fns map[string]Function
|
|
||||||
vars map[string]Global
|
vars map[string]Global
|
||||||
|
fns map[string]Function
|
||||||
|
stubs map[string]Function
|
||||||
Prog Program
|
Prog Program
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,6 +368,30 @@ func (p Package) rtFunc(fnName string) Expr {
|
|||||||
return p.NewFunc(name, sig, InGo).Expr
|
return p.NewFunc(name, sig, InGo).Expr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p Package) closureStub(b Builder, t *types.Struct, v Expr) Expr {
|
||||||
|
name := v.impl.Name()
|
||||||
|
prog := b.Prog
|
||||||
|
nilVal := prog.Null(prog.VoidPtr()).impl
|
||||||
|
if fn, ok := p.stubs[name]; ok {
|
||||||
|
v = fn.Expr
|
||||||
|
} else {
|
||||||
|
sig := v.raw.Type.(*types.Signature)
|
||||||
|
n := sig.Params().Len()
|
||||||
|
ctx := types.NewParam(token.NoPos, nil, ClosureCtx, types.Typ[types.UnsafePointer])
|
||||||
|
sig = FuncAddCtx(ctx, sig)
|
||||||
|
fn := p.NewFunc(ClosureStub+name, sig, InC)
|
||||||
|
args := make([]Expr, n)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
args[i] = fn.Param(i + 1)
|
||||||
|
}
|
||||||
|
b := fn.MakeBody(1)
|
||||||
|
b.Return(b.Call(v, args...))
|
||||||
|
p.stubs[name] = fn
|
||||||
|
v = fn.Expr
|
||||||
|
}
|
||||||
|
return b.aggregateValue(prog.rawType(t), v.impl, nilVal)
|
||||||
|
}
|
||||||
|
|
||||||
// FuncOf returns a function by name.
|
// FuncOf returns a function by name.
|
||||||
func (p Package) FuncOf(name string) Function {
|
func (p Package) FuncOf(name string) Function {
|
||||||
return p.fns[name]
|
return p.fns[name]
|
||||||
|
|||||||
Reference in New Issue
Block a user