llgo/ssa: pyCall; demo: _pydemo/callpy
This commit is contained in:
@@ -22,6 +22,10 @@ import (
|
||||
"github.com/goplus/llgo/cl/cltest"
|
||||
)
|
||||
|
||||
func TestFromTestpy(t *testing.T) {
|
||||
cltest.FromDir(t, "", "../cl/_testpy", false)
|
||||
}
|
||||
|
||||
func TestFromTestrt(t *testing.T) {
|
||||
cltest.FromDir(t, "", "../cl/_testrt", true)
|
||||
}
|
||||
|
||||
@@ -1176,7 +1176,6 @@ func (b Builder) InlineCall(fn Expr, args ...Expr) (ret Expr) {
|
||||
// t4 = t3()
|
||||
// t7 = invoke t5.Println(...t6)
|
||||
func (b Builder) Call(fn Expr, args ...Expr) (ret Expr) {
|
||||
prog := b.Prog
|
||||
if debugInstr {
|
||||
var b bytes.Buffer
|
||||
name := fn.impl.Name()
|
||||
@@ -1191,11 +1190,16 @@ func (b Builder) Call(fn Expr, args ...Expr) (ret Expr) {
|
||||
}
|
||||
log.Println(b.String())
|
||||
}
|
||||
var kind = fn.kind
|
||||
if kind == vkPyFunc {
|
||||
return b.pyCall(fn, args)
|
||||
}
|
||||
var ll llvm.Type
|
||||
var data Expr
|
||||
var sig *types.Signature
|
||||
var prog = b.Prog
|
||||
var raw = fn.raw.Type
|
||||
switch fn.kind {
|
||||
switch kind {
|
||||
case vkClosure:
|
||||
data = b.Field(fn, 1)
|
||||
fn = b.Field(fn, 0)
|
||||
|
||||
@@ -136,7 +136,9 @@ type aProgram struct {
|
||||
pyObjPtr Type
|
||||
pyObjPPtr Type
|
||||
|
||||
pyImpTy *types.Signature
|
||||
pyImpTy *types.Signature
|
||||
callNoArg *types.Signature
|
||||
callOneArg *types.Signature
|
||||
|
||||
needRuntime bool
|
||||
needPyInit bool
|
||||
@@ -385,7 +387,7 @@ func (p Package) rtFunc(fnName string) Expr {
|
||||
return p.NewFunc(name, sig, InGo).Expr
|
||||
}
|
||||
|
||||
func (p Package) cpyFunc(fullName string, sig *types.Signature) Expr {
|
||||
func (p Package) pyFunc(fullName string, sig *types.Signature) Expr {
|
||||
p.Prog.needPyInit = true
|
||||
return p.NewFunc(fullName, sig, InC).Expr
|
||||
}
|
||||
@@ -483,10 +485,31 @@ func (p Program) tyImportPyModule() *types.Signature {
|
||||
return p.pyImpTy
|
||||
}
|
||||
|
||||
func (p Program) tyCallNoArg() *types.Signature {
|
||||
if p.callNoArg == nil {
|
||||
objPtr := p.PyObjectPtr().raw.Type
|
||||
paramObjPtr := types.NewParam(token.NoPos, nil, "", objPtr)
|
||||
params := types.NewTuple(paramObjPtr)
|
||||
p.callNoArg = types.NewSignatureType(nil, nil, nil, params, params, false)
|
||||
}
|
||||
return p.callNoArg
|
||||
}
|
||||
|
||||
func (p Program) tyCallOneArg() *types.Signature {
|
||||
if p.callOneArg == nil {
|
||||
objPtr := p.PyObjectPtr().raw.Type
|
||||
paramObjPtr := types.NewParam(token.NoPos, nil, "", objPtr)
|
||||
params := types.NewTuple(paramObjPtr, paramObjPtr)
|
||||
results := types.NewTuple(paramObjPtr)
|
||||
p.callOneArg = types.NewSignatureType(nil, nil, nil, params, results, false)
|
||||
}
|
||||
return p.callOneArg
|
||||
}
|
||||
|
||||
// ImportPyMod imports a Python module.
|
||||
func (b Builder) ImportPyMod(path string) Expr {
|
||||
pkg := b.Func.Pkg
|
||||
fnImp := pkg.cpyFunc("PyImport_ImportModule", b.Prog.tyImportPyModule())
|
||||
fnImp := pkg.pyFunc("PyImport_ImportModule", b.Prog.tyImportPyModule())
|
||||
return b.Call(fnImp, b.CStr(path))
|
||||
}
|
||||
|
||||
@@ -500,4 +523,23 @@ func (p Package) NewPyModVar(name string) Global {
|
||||
return g
|
||||
}
|
||||
|
||||
func (b Builder) pyCall(fn Expr, args []Expr) (ret Expr) {
|
||||
prog := b.Prog
|
||||
pkg := b.Func.Pkg
|
||||
sig := fn.raw.Type.(*types.Signature)
|
||||
params := sig.Params()
|
||||
n := params.Len()
|
||||
switch n {
|
||||
case 0:
|
||||
call := pkg.pyFunc("PyObject_CallNoArg", prog.tyCallNoArg())
|
||||
ret = b.Call(call, fn)
|
||||
case 1:
|
||||
call := pkg.pyFunc("PyObject_CallOneArg", prog.tyCallOneArg())
|
||||
ret = b.Call(call, fn, args[0])
|
||||
default:
|
||||
panic("todo")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user