diff --git a/cl/_testpy/callpy/out.ll b/cl/_testpy/callpy/out.ll index 001dd685..c1589558 100644 --- a/cl/_testpy/callpy/out.ll +++ b/cl/_testpy/callpy/out.ll @@ -4,8 +4,8 @@ source_filename = "main" @"main.init$guard" = global ptr null @__llgo_argc = global ptr null @__llgo_argv = global ptr null -@sqrt = external global ptr -@getcwd = external global ptr +@__llgo_py.math.sqrt = linkonce global ptr null +@__llgo_py.os.getcwd = linkonce global ptr null @0 = private unnamed_addr constant [14 x i8] c"sqrt(2) = %f\0A\00", align 1 @1 = private unnamed_addr constant [10 x i8] c"cwd = %s\0A\00", align 1 @@ -31,8 +31,8 @@ _llgo_0: call void @"github.com/goplus/llgo/internal/runtime.init"() call void @main.init() %2 = call ptr @PyFloat_FromDouble(double 2.000000e+00) - %3 = call ptr @PyObject_CallOneArg(ptr @sqrt, ptr %2) - %4 = call ptr @PyObject_CallNoArg(ptr @getcwd) + %3 = call ptr @PyObject_CallOneArg(ptr @__llgo_py.math.sqrt, ptr %2) + %4 = call ptr @PyObject_CallNoArgs(ptr @__llgo_py.os.getcwd) %5 = call double @PyFloat_AsDouble() %6 = call i32 (ptr, ...) @printf(ptr @0, double %5) %7 = call ptr @PyBytes_AsString() @@ -50,7 +50,7 @@ declare ptr @PyFloat_FromDouble(double) declare ptr @PyObject_CallOneArg(ptr, ptr) -declare ptr @PyObject_CallNoArg(ptr) +declare ptr @PyObject_CallNoArgs(ptr) declare double @PyFloat_AsDouble() diff --git a/cl/compile.go b/cl/compile.go index fd96cbdf..d762356a 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -285,13 +285,18 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Fun // funcOf returns a function by name and set ftype = goFunc, cFunc, etc. // or returns nil and set ftype = llgoCstr, llgoAlloca, llgoUnreachable, etc. func (p *context) funcOf(fn *ssa.Function) (aFn llssa.Function, pyFn llssa.PyFunction, ftype int) { - _, name, ftype := p.funcName(fn, false) + pkgTypes, name, ftype := p.funcName(fn, false) switch ftype { case pyFunc: - pkg := p.pkg - if pyFn = pkg.PyFuncOf(name); pyFn == nil { - pyFn = pkg.NewPyFunc(name, fn.Signature) + if kind, mod := pkgKindByScope(pkgTypes.Scope()); kind == PkgPyModule { + pkg := p.pkg + fnName := pysymPrefix + mod + "." + name + if pyFn = pkg.PyFuncOf(fnName); pyFn == nil { + pyFn = pkg.NewPyFunc(fnName, fn.Signature) + return + } } + ftype = ignoredFunc case llgoInstr: switch name { case "cstr": diff --git a/py/math/llgo_autogen.lla b/py/math/llgo_autogen.lla new file mode 100644 index 00000000..1daa2e16 Binary files /dev/null and b/py/math/llgo_autogen.lla differ diff --git a/py/os/llgo_autogen.lla b/py/os/llgo_autogen.lla new file mode 100644 index 00000000..b018d58d Binary files /dev/null and b/py/os/llgo_autogen.lla differ diff --git a/ssa/decl.go b/ssa/decl.go index b89243fa..7c2b6933 100644 --- a/ssa/decl.go +++ b/ssa/decl.go @@ -298,7 +298,10 @@ func (p Package) NewPyFunc(name string, sig *types.Signature) PyFunction { if v, ok := p.pyfns[name]; ok { return v } - obj := p.NewVar(name, p.Prog.PyObjectPtrPtr().RawType(), InC) + prog := p.Prog + obj := p.NewVar(name, prog.PyObjectPtrPtr().RawType(), InC) + obj.Init(prog.Null(obj.Type)) + obj.impl.SetLinkage(llvm.LinkOnceAnyLinkage) ty := &aType{obj.ll, rawType{sig}, vkPyFunc} expr := Expr{obj.impl, ty} ret := &aPyFunction{expr, obj} diff --git a/ssa/package.go b/ssa/package.go index cb3691b3..e64df9c3 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -137,7 +137,7 @@ type aProgram struct { pyObjPPtr Type pyImpTy *types.Signature - callNoArg *types.Signature + callNoArgs *types.Signature callOneArg *types.Signature needRuntime bool @@ -485,14 +485,14 @@ func (p Program) tyImportPyModule() *types.Signature { return p.pyImpTy } -func (p Program) tyCallNoArg() *types.Signature { - if p.callNoArg == nil { +func (p Program) tyCallNoArgs() *types.Signature { + if p.callNoArgs == 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) + p.callNoArgs = types.NewSignatureType(nil, nil, nil, params, params, false) } - return p.callNoArg + return p.callNoArgs } func (p Program) tyCallOneArg() *types.Signature { @@ -531,7 +531,7 @@ func (b Builder) pyCall(fn Expr, args []Expr) (ret Expr) { n := params.Len() switch n { case 0: - call := pkg.pyFunc("PyObject_CallNoArg", prog.tyCallNoArg()) + call := pkg.pyFunc("PyObject_CallNoArgs", prog.tyCallNoArgs()) ret = b.Call(call, fn) case 1: call := pkg.pyFunc("PyObject_CallOneArg", prog.tyCallOneArg())