From 9ac0450255c70b5a4cf8fbbc7ea4c2e24ebe45a2 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 12 May 2024 18:27:23 +0800 Subject: [PATCH 1/9] llgo/ssa: LoadPyModSyms --- .gitignore | 1 + cl/compile.go | 10 +++--- py/_pyg/module.c | 25 +++++++++++++ py/llgo.cfg | 6 ++++ py/llgo_autogen.lla | Bin 523 -> 1822 bytes py/module.go | 3 ++ py/module.ll | 84 ++++++++++++++++++++++++++++++++++++++++++++ ssa/decl.go | 27 ++++++++------ ssa/package.go | 40 +++++++++++++++++---- ssa/ssa_test.go | 4 +-- 10 files changed, 176 insertions(+), 24 deletions(-) create mode 100644 py/_pyg/module.c create mode 100644 py/llgo.cfg create mode 100644 py/module.ll diff --git a/.gitignore b/.gitignore index d3ecf298..41c277a2 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ _go/ _runtime/ _tinygo/ build.dir/ +.vscode/ # Test binary, built with `go test -c` *.test diff --git a/cl/compile.go b/cl/compile.go index 998958ec..68a8f2ad 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -211,7 +211,7 @@ var ( argvTy = types.NewPointer(types.NewPointer(types.Typ[types.Int8])) ) -func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function, call bool) (llssa.Function, llssa.PyFunction, int) { +func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function, call bool) (llssa.Function, llssa.PyObject, int) { pkgTypes, name, ftype := p.funcName(f, true) if ftype != goFunc { if ftype == pyFunc { @@ -284,14 +284,14 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function, call bool) // 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) { +func (p *context) funcOf(fn *ssa.Function) (aFn llssa.Function, pyFn llssa.PyObject, ftype int) { pkgTypes, name, ftype := p.funcName(fn, false) switch ftype { case pyFunc: if kind, mod := pkgKindByScope(pkgTypes.Scope()); kind == PkgPyModule { pkg := p.pkg fnName := pysymPrefix + mod + "." + name - if pyFn = pkg.PyFuncOf(fnName); pyFn == nil { + if pyFn = pkg.PyObjOf(fnName); pyFn == nil { pyFn = pkg.NewPyFunc(fnName, fn.Signature, true) return } @@ -361,7 +361,7 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do jumpTo := p.jumpTo(jump) modPath := p.pyMod modName := pysymPrefix + modPath - modPtr := p.pkg.NewPyModVar(modName).Expr + modPtr := p.pkg.NewPyModVar(modName, true).Expr mod := b.Load(modPtr) cond := b.BinOp(token.NEQ, mod, b.Prog.Null(mod.Type)) newBlk := p.fn.MakeBlock() @@ -763,7 +763,7 @@ func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) { } } -func (p *context) compileFunction(v *ssa.Function) (goFn llssa.Function, pyFn llssa.PyFunction, kind int) { +func (p *context) compileFunction(v *ssa.Function) (goFn llssa.Function, pyFn llssa.PyObject, kind int) { // v.Pkg == nil: means auto generated function? if v.Pkg == p.goPkg || v.Pkg == nil { // function in this package diff --git a/py/_pyg/module.c b/py/_pyg/module.c new file mode 100644 index 00000000..7ce91821 --- /dev/null +++ b/py/_pyg/module.c @@ -0,0 +1,25 @@ +#include +#include + +// example: +// llgoLoadPyModSyms(mod, "name1", &func1, "name2", &func2, NULL) + +typedef struct PyObject PyObject; + +PyObject* PyObject_GetAttrString(PyObject* mod, const char* attrName); + +void llgoLoadPyModSyms(PyObject* mod, ...) { + va_list ap; + va_start(ap, mod); + for (;;) { + const char* name = va_arg(ap, const char*); + if (name == NULL) { + break; + } + PyObject** pfunc = va_arg(ap, PyObject**); + if (*pfunc == NULL) { + *pfunc = PyObject_GetAttrString(mod, name); + } + } + va_end(ap); +} diff --git a/py/llgo.cfg b/py/llgo.cfg new file mode 100644 index 00000000..09270308 --- /dev/null +++ b/py/llgo.cfg @@ -0,0 +1,6 @@ +{ + "cl": [ + "clang -emit-llvm -S -o module.ll -c _pyg/module.c", + "rm llgo_autogen.lla; zip llgo_autogen.lla llgo_autogen.ll module.ll", + ] +} diff --git a/py/llgo_autogen.lla b/py/llgo_autogen.lla index 79b52437fa407fb23c5da0a55c2f952b2d5d7ecc..ab226c5eee6f15bb2cb9eddb5bc7a0613c4f92e3 100644 GIT binary patch delta 1339 zcmZ|Pe>l?#90&04X0uiq4vW&7o{+RnF`XZWp&TO;v7*Pc`8iXxLzbo7LYEVg-#2T1 zR2ZR2#CFZm&Gf^$(KIB4L`^>!&UOFXbI)_n=lMME=l#d~-`5pL8KRyGVyQuN0RY$l z%xBjGcGBHvQXv4)f&c(GUgc}`&y>(5Bs1b`rmAOQF}eH{=S z`@&lH{GWUdUf(OKM<`Ap9iNNF?wIXH9d(4{2au60=U_sH6NI)wL~)Iy7rcFTWr3ND7WIp ztg_H)lH+1pPXZfGE=Zp#$RC0%4@gLpmGA+5uxz?r!Y1098|_dU6bKg$(bt?W9`fX@ z_TR1CGWDo~=(jsRPs{Zeh!)OzA6fGyd2e@{m*?SaM=S@=CC=K^GUSEYT_YGYe(Qp! z(?|Dt_0a_PZcvV!R<5DFbmOCk0t%W{Tay++8I^^UT(y@e@W18%xN@|4C^u?IyUg`w^!+SeQ{|(7@~QH#C+arl`@e zz)kM@W6T+FtJqaC)xgQzZWlVz z*)@Pv;&vT2jl58*aYU5ly9fU11TYjuwVy^EM zLkX8#P5QME3#fH+J#Qu00;Nx#i-HQQv>o{I=Y@Cc_~OPtgxPh#+WJ~5oL+o!q(KwPItIYB)(HPu~*ooKu;-h5#V`C|Hy3`I&b@1oS}{+r=XBa&&t_8CI+ zoG^w9JJ`g6K^tLs0nC(vV@3ogiFkBoCA;s=3#M!KndVprRmN)Q?X=)1yD4*mqn7Mp zIbWST7dVli)R4^&JpCz}KL+)0JT6fmS7X!ml?z=nA1999i`!o~F>idGU|)L$hP_!w zghLfEzTygZ@br!3khO#Ln+jVdEm8)_;ziL_B7N{&A4b+{fO$Lfb4R&1t;bpdLFZz5 z7z_qbL(hU+%^qIzDsFC26f0eP-j5q%ilGGAWqyaY?VaS{+2o1n>}(_DtN3N%5-gVk v3OEG Date: Sun, 12 May 2024 18:42:45 +0800 Subject: [PATCH 2/9] compileBlock refactor --- cl/compile.go | 47 +++++++++++++++++++++++------------------------ py/module.ll | 2 -- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index 68a8f2ad..e3bdad5d 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -250,7 +250,6 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function, call bool) } if nblk := len(f.Blocks); nblk > 0 { fn.MakeBlocks(nblk) // to set fn.HasBody() = true - isPyMod := p.pyMod != "" p.inits = append(p.inits, func() { p.fn = fn defer func() { @@ -270,9 +269,9 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function, call bool) off[i] = p.compilePhis(b, block) } for i, block := range f.Blocks { - doInit := (i == 0 && name == "main") - doPyModInit := (isPyMod && i == 1 && f.Name() == "init" && sig.Recv() == nil) - p.compileBlock(b, block, off[i], doInit, doPyModInit) + doMainInit := (i == 0 && name == "main") + doModInit := (i == 1 && f.Name() == "init" && sig.Recv() == nil) + p.compileBlock(b, block, off[i], doMainInit, doModInit) } for _, phi := range p.phis { phi() @@ -329,35 +328,35 @@ func (p *context) funcOf(fn *ssa.Function) (aFn llssa.Function, pyFn llssa.PyObj return } -func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, doInit, pyModInit bool) llssa.BasicBlock { +func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, doMainInit, doModInit bool) llssa.BasicBlock { var last int - var instrs []ssa.Instruction + var pyModInit bool + var instrs = block.Instrs[n:] var ret = p.fn.Block(block.Index) b.SetBlock(ret) - if pyModInit { - last = len(block.Instrs) - 1 - instrs = block.Instrs[n:last] - } else { - instrs = block.Instrs[n:] - if doInit { - prog := p.prog - pkg := p.pkg - fn := p.fn - argc := pkg.NewVar("__llgo_argc", types.NewPointer(types.Typ[types.Int32]), llssa.InC) - argv := pkg.NewVar("__llgo_argv", types.NewPointer(argvTy), llssa.InC) - argc.Init(prog.Null(argc.Type)) - argv.Init(prog.Null(argv.Type)) - b.Store(argc.Expr, fn.Param(0)) - b.Store(argv.Expr, fn.Param(1)) - callRuntimeInit(b, pkg) - b.Call(pkg.FuncOf("main.init").Expr) + if doModInit { + if pyModInit = p.pyMod != ""; pyModInit { + last = len(instrs) - 1 + instrs = instrs[:last] } + } else if doMainInit { + prog := p.prog + pkg := p.pkg + fn := p.fn + argc := pkg.NewVar("__llgo_argc", types.NewPointer(types.Typ[types.Int32]), llssa.InC) + argv := pkg.NewVar("__llgo_argv", types.NewPointer(argvTy), llssa.InC) + argc.Init(prog.Null(argc.Type)) + argv.Init(prog.Null(argv.Type)) + b.Store(argc.Expr, fn.Param(0)) + b.Store(argv.Expr, fn.Param(1)) + callRuntimeInit(b, pkg) + b.Call(pkg.FuncOf("main.init").Expr) } for _, instr := range instrs { p.compileInstr(b, instr) } if pyModInit { - jump := block.Instrs[last].(*ssa.Jump) + jump := block.Instrs[n+last].(*ssa.Jump) jumpTo := p.jumpTo(jump) modPath := p.pyMod modName := pysymPrefix + modPath diff --git a/py/module.ll b/py/module.ll index 390aaa64..d11c7450 100644 --- a/py/module.ll +++ b/py/module.ll @@ -1,7 +1,5 @@ ; ModuleID = '_pyg/module.c' source_filename = "_pyg/module.c" -target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" -target triple = "arm64-apple-macosx13.0.0" %struct.PyObject = type opaque From 03fe594339843a95e2a6a168cc7b1bc82923af15 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 12 May 2024 20:03:27 +0800 Subject: [PATCH 3/9] compileBlock: use LoadPyModSyms --- cl/compile.go | 28 ++++++++++++++++++++++++---- cl/compile_test.go | 2 +- ssa/package.go | 9 +++++++-- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index e3bdad5d..4d3c95d5 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -328,9 +328,18 @@ func (p *context) funcOf(fn *ssa.Function) (aFn llssa.Function, pyFn llssa.PyObj return } +func modOf(name string) string { + if pos := strings.LastIndexByte(name, '.'); pos > 0 { + return name[:pos] + } + return "" +} + func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, doMainInit, doModInit bool) llssa.BasicBlock { var last int var pyModInit bool + var prog = p.prog + var pkg = p.pkg var instrs = block.Instrs[n:] var ret = p.fn.Block(block.Index) b.SetBlock(ret) @@ -339,9 +348,20 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do last = len(instrs) - 1 instrs = instrs[:last] } + p.inits = append(p.inits, func() { + if objs := pkg.PyObjs(); len(objs) > 0 { + mods := make(map[string][]llssa.PyObject) + for name, obj := range objs { + modName := modOf(name) + mods[modName] = append(mods[modName], obj) + } + b.SetBlockEx(ret, llssa.AtStart) + for modName, objs := range mods { + b.LoadPyModSyms(modName, objs...) + } + } + }) } else if doMainInit { - prog := p.prog - pkg := p.pkg fn := p.fn argc := pkg.NewVar("__llgo_argc", types.NewPointer(types.Typ[types.Int32]), llssa.InC) argv := pkg.NewVar("__llgo_argv", types.NewPointer(argvTy), llssa.InC) @@ -360,9 +380,9 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do jumpTo := p.jumpTo(jump) modPath := p.pyMod modName := pysymPrefix + modPath - modPtr := p.pkg.NewPyModVar(modName, true).Expr + modPtr := pkg.NewPyModVar(modName, true).Expr mod := b.Load(modPtr) - cond := b.BinOp(token.NEQ, mod, b.Prog.Null(mod.Type)) + cond := b.BinOp(token.NEQ, mod, prog.Null(mod.Type)) newBlk := p.fn.MakeBlock() b.If(cond, jumpTo, newBlk) b.SetBlock(newBlk) diff --git a/cl/compile_test.go b/cl/compile_test.go index 6f417cbe..a1237888 100644 --- a/cl/compile_test.go +++ b/cl/compile_test.go @@ -29,7 +29,7 @@ func testCompile(t *testing.T, src, expected string) { } func TestFromTestpy(t *testing.T) { - cltest.FromDir(t, "", "./_testpy", false) + cltest.FromDir(t, "callpy", "./_testpy", false) } func TestFromTestlibc(t *testing.T) { diff --git a/ssa/package.go b/ssa/package.go index 5893c298..67167685 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -557,12 +557,17 @@ func (b Builder) LoadPyModSyms(modName string, objs ...PyObject) Expr { fnLoad := pkg.pyFunc("llgoLoadPyModSyms", b.Prog.tyLoadPyModSyms()) modPtr := pkg.NewPyModVar(modName, false).Expr mod := b.Load(modPtr) - args := make([]Expr, 1, len(objs)*2+1) + args := make([]Expr, 1, len(objs)*2+2) args[0] = mod + nbase := len(modName) + 1 for _, o := range objs { - args = append(args, b.CStr(o.impl.Name())) + fullName := o.impl.Name() + name := fullName[nbase:] + args = append(args, b.CStr(name)) args = append(args, o.Expr) } + prog := b.Prog + args = append(args, prog.Null(prog.CStr())) return b.Call(fnLoad, args...) } From 23692430d5fee44a35c092c054452010cb0509bc Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 12 May 2024 22:51:25 +0800 Subject: [PATCH 4/9] llgo/ssa: SetBlockEx AfterInit --- cl/_testpy/callpy/out.ll | 10 ++++++++++ cl/compile.go | 2 +- ssa/stmt_builder.go | 25 +++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/cl/_testpy/callpy/out.ll b/cl/_testpy/callpy/out.ll index d3892453..437dd6f7 100644 --- a/cl/_testpy/callpy/out.ll +++ b/cl/_testpy/callpy/out.ll @@ -8,6 +8,10 @@ source_filename = "main" @__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 +@__llgo_py.math = external global ptr +@2 = private unnamed_addr constant [5 x i8] c"sqrt\00", align 1 +@__llgo_py.os = external global ptr +@3 = private unnamed_addr constant [7 x i8] c"getcwd\00", align 1 define void @main.init() { _llgo_0: @@ -18,6 +22,10 @@ _llgo_1: ; preds = %_llgo_0 store i1 true, ptr @"main.init$guard", align 1 call void @"github.com/goplus/llgo/py/math.init"() call void @"github.com/goplus/llgo/py/os.init"() + %1 = load ptr, ptr @__llgo_py.math, align 8 + call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @2, ptr @__llgo_py.math.sqrt, ptr null) + %2 = load ptr, ptr @__llgo_py.os, align 8 + call void (ptr, ...) @llgoLoadPyModSyms(ptr %2, ptr @3, ptr @__llgo_py.os.getcwd, ptr null) br label %_llgo_2 _llgo_2: ; preds = %_llgo_1, %_llgo_0 @@ -59,4 +67,6 @@ declare i32 @printf(ptr, ...) declare ptr @PyBytes_AsString() +declare void @llgoLoadPyModSyms(ptr, ...) + declare void @Py_Initialize() diff --git a/cl/compile.go b/cl/compile.go index 4d3c95d5..18142e64 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -355,7 +355,7 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do modName := modOf(name) mods[modName] = append(mods[modName], obj) } - b.SetBlockEx(ret, llssa.AtStart) + b.SetBlockEx(ret, llssa.AfterInit) for modName, objs := range mods { b.LoadPyModSyms(modName, objs...) } diff --git a/ssa/stmt_builder.go b/ssa/stmt_builder.go index 817d6524..579e744b 100644 --- a/ssa/stmt_builder.go +++ b/ssa/stmt_builder.go @@ -21,6 +21,7 @@ import ( "fmt" "go/types" "log" + "strings" "github.com/goplus/llvm" ) @@ -76,6 +77,7 @@ type InsertPoint int const ( AtEnd InsertPoint = iota AtStart + AfterInit ) // SetBlockEx sets blk as current basic block and pos as its insert point. @@ -88,12 +90,35 @@ func (b Builder) SetBlockEx(blk BasicBlock, pos InsertPoint) Builder { b.impl.SetInsertPointAtEnd(blk.impl) case AtStart: b.impl.SetInsertPointBefore(blk.impl.FirstInstruction()) + case AfterInit: + b.impl.SetInsertPointBefore(instrAfterInit(blk.impl)) default: panic("SetBlockEx: invalid pos") } return b } +func instrAfterInit(blk llvm.BasicBlock) llvm.Value { + instr := blk.FirstInstruction() + for { + instr = llvm.NextInstruction(instr) + if notInit(instr) { + return instr + } + } +} + +func notInit(instr llvm.Value) bool { + switch op := instr.InstructionOpcode(); op { + case llvm.Call: + if n := instr.OperandsCount(); n == 1 { + fn := instr.Operand(0) + return !strings.HasSuffix(fn.Name(), ".init") + } + } + return true +} + // Panic emits a panic instruction. func (b Builder) Panic(v Expr) { if debugInstr { From f7dfab481b6dfb679721e72bf1b9db2b773b8234 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 12 May 2024 23:08:44 +0800 Subject: [PATCH 5/9] vkPyFunc => vkPyFuncRef --- chore/gentests/gentests.go | 1 + cl/_testpy/callpy/out.ll | 14 ++++++++------ cl/_testpy/math/out.ll | 25 +++++++++++++++---------- cl/compile.go | 8 ++++---- ssa/decl.go | 16 ++++++++-------- ssa/expr.go | 2 +- ssa/package.go | 7 ++++--- ssa/type.go | 2 +- 8 files changed, 42 insertions(+), 33 deletions(-) diff --git a/chore/gentests/gentests.go b/chore/gentests/gentests.go index b57138a1..bb34a1a7 100644 --- a/chore/gentests/gentests.go +++ b/chore/gentests/gentests.go @@ -33,6 +33,7 @@ func main() { llgenDir(dir + "/cl/_testlibc") llgenDir(dir + "/cl/_testrt") + llgenDir(dir + "/cl/_testpy") llgenDir(dir+"/cl/_testdata", "") } diff --git a/cl/_testpy/callpy/out.ll b/cl/_testpy/callpy/out.ll index 437dd6f7..c982584d 100644 --- a/cl/_testpy/callpy/out.ll +++ b/cl/_testpy/callpy/out.ll @@ -40,12 +40,14 @@ _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 @__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() - %8 = call i32 (ptr, ...) @printf(ptr @1, ptr %7) + %3 = load ptr, ptr @__llgo_py.math.sqrt, align 8 + %4 = call ptr @PyObject_CallOneArg(ptr %3, ptr %2) + %5 = load ptr, ptr @__llgo_py.os.getcwd, align 8 + %6 = call ptr @PyObject_CallNoArgs(ptr %5) + %7 = call double @PyFloat_AsDouble() + %8 = call i32 (ptr, ...) @printf(ptr @0, double %7) + %9 = call ptr @PyBytes_AsString() + %10 = call i32 (ptr, ...) @printf(ptr @1, ptr %9) ret void } diff --git a/cl/_testpy/math/out.ll b/cl/_testpy/math/out.ll index f5feead3..66f80e8f 100644 --- a/cl/_testpy/math/out.ll +++ b/cl/_testpy/math/out.ll @@ -1,29 +1,34 @@ -; ModuleID = 'math' -source_filename = "math" +; ModuleID = 'command-line-arguments' +source_filename = "command-line-arguments" @__llgo_py.math.sqrt = external global ptr -@"math.init$guard" = global ptr null +@"command-line-arguments.init$guard" = global ptr null @__llgo_py.math = linkonce global ptr null @0 = private unnamed_addr constant [5 x i8] c"math\00", align 1 +@1 = private unnamed_addr constant [5 x i8] c"sqrt\00", align 1 -define void @math.init() { +define void @command-line-arguments.init() { _llgo_0: - %0 = load i1, ptr @"math.init$guard", align 1 + %0 = load i1, ptr @"command-line-arguments.init$guard", align 1 br i1 %0, label %_llgo_2, label %_llgo_1 _llgo_1: ; preds = %_llgo_0 - store i1 true, ptr @"math.init$guard", align 1 + store i1 true, ptr @"command-line-arguments.init$guard", align 1 %1 = load ptr, ptr @__llgo_py.math, align 8 - %2 = icmp ne ptr %1, null - br i1 %2, label %_llgo_2, label %_llgo_3 + call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @1, ptr @__llgo_py.math.sqrt, ptr null) + %2 = load ptr, ptr @__llgo_py.math, align 8 + %3 = icmp ne ptr %2, null + br i1 %3, label %_llgo_2, label %_llgo_3 _llgo_2: ; preds = %_llgo_3, %_llgo_1, %_llgo_0 ret void _llgo_3: ; preds = %_llgo_1 - %3 = call ptr @PyImport_ImportModule(ptr @0) - store ptr %3, ptr @__llgo_py.math, align 8 + %4 = call ptr @PyImport_ImportModule(ptr @0) + store ptr %4, ptr @__llgo_py.math, align 8 br label %_llgo_2 } declare ptr @PyImport_ImportModule(ptr) + +declare void @llgoLoadPyModSyms(ptr, ...) diff --git a/cl/compile.go b/cl/compile.go index 18142e64..a786981b 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -211,7 +211,7 @@ var ( argvTy = types.NewPointer(types.NewPointer(types.Typ[types.Int8])) ) -func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function, call bool) (llssa.Function, llssa.PyObject, int) { +func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function, call bool) (llssa.Function, llssa.PyObjRef, int) { pkgTypes, name, ftype := p.funcName(f, true) if ftype != goFunc { if ftype == pyFunc { @@ -283,7 +283,7 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function, call bool) // 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.PyObject, ftype int) { +func (p *context) funcOf(fn *ssa.Function) (aFn llssa.Function, pyFn llssa.PyObjRef, ftype int) { pkgTypes, name, ftype := p.funcName(fn, false) switch ftype { case pyFunc: @@ -350,7 +350,7 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do } p.inits = append(p.inits, func() { if objs := pkg.PyObjs(); len(objs) > 0 { - mods := make(map[string][]llssa.PyObject) + mods := make(map[string][]llssa.PyObjRef) for name, obj := range objs { modName := modOf(name) mods[modName] = append(mods[modName], obj) @@ -782,7 +782,7 @@ func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) { } } -func (p *context) compileFunction(v *ssa.Function) (goFn llssa.Function, pyFn llssa.PyObject, kind int) { +func (p *context) compileFunction(v *ssa.Function) (goFn llssa.Function, pyFn llssa.PyObjRef, kind int) { // v.Pkg == nil: means auto generated function? if v.Pkg == p.goPkg || v.Pkg == nil { // function in this package diff --git a/ssa/decl.go b/ssa/decl.go index 925ea0db..ca857cb1 100644 --- a/ssa/decl.go +++ b/ssa/decl.go @@ -285,16 +285,16 @@ func (p Function) Block(idx int) BasicBlock { // ----------------------------------------------------------------------------- -type aPyObject struct { +type aPyObjRef struct { Expr Obj Global } -// PyObject represents a python object. -type PyObject = *aPyObject +// PyObjRef represents a python object reference. +type PyObjRef = *aPyObjRef // NewPyFunc creates a new python function. -func (p Package) NewPyFunc(name string, sig *types.Signature, doInit bool) PyObject { +func (p Package) NewPyFunc(name string, sig *types.Signature, doInit bool) PyObjRef { if v, ok := p.pyobjs[name]; ok { return v } @@ -305,20 +305,20 @@ func (p Package) NewPyFunc(name string, sig *types.Signature, doInit bool) PyObj obj.Init(prog.Null(obj.Type)) obj.impl.SetLinkage(llvm.LinkOnceAnyLinkage) } - ty := &aType{obj.ll, rawType{sig}, vkPyFunc} + ty := &aType{obj.ll, rawType{types.NewPointer(sig)}, vkPyFuncRef} expr := Expr{obj.impl, ty} - ret := &aPyObject{expr, obj} + ret := &aPyObjRef{expr, obj} p.pyobjs[name] = ret return ret } // PyObjOf returns a python object by name. -func (p Package) PyObjOf(name string) PyObject { +func (p Package) PyObjOf(name string) PyObjRef { return p.pyobjs[name] } // PyObjs returns all used python objects in this project. -func (p Package) PyObjs() map[string]PyObject { +func (p Package) PyObjs() map[string]PyObjRef { return p.pyobjs } diff --git a/ssa/expr.go b/ssa/expr.go index a97157b8..71921b5e 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -1238,7 +1238,7 @@ func (b Builder) Call(fn Expr, args ...Expr) (ret Expr) { log.Println(b.String()) } var kind = fn.kind - if kind == vkPyFunc { + if kind == vkPyFuncRef { return b.pyCall(fn, args) } var ll llvm.Type diff --git a/ssa/package.go b/ssa/package.go index 67167685..eeee0f24 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -258,7 +258,7 @@ func (p Program) NewPackage(name, pkgPath string) Package { gbls := make(map[string]Global) fns := make(map[string]Function) stubs := make(map[string]Function) - pyobjs := make(map[string]PyObject) + pyobjs := make(map[string]PyObjRef) pymods := make(map[string]Global) p.NeedRuntime = false // Don't need reset p.needPyInit here @@ -367,7 +367,7 @@ type aPackage struct { vars map[string]Global fns map[string]Function stubs map[string]Function - pyobjs map[string]PyObject + pyobjs map[string]PyObjRef pymods map[string]Global Prog Program } @@ -552,7 +552,7 @@ func (b Builder) ImportPyMod(path string) Expr { } // LoadPyModSyms loads python objects from specified module. -func (b Builder) LoadPyModSyms(modName string, objs ...PyObject) Expr { +func (b Builder) LoadPyModSyms(modName string, objs ...PyObjRef) Expr { pkg := b.Func.Pkg fnLoad := pkg.pyFunc("llgoLoadPyModSyms", b.Prog.tyLoadPyModSyms()) modPtr := pkg.NewPyModVar(modName, false).Expr @@ -574,6 +574,7 @@ func (b Builder) LoadPyModSyms(modName string, objs ...PyObject) Expr { func (b Builder) pyCall(fn Expr, args []Expr) (ret Expr) { prog := b.Prog pkg := b.Func.Pkg + fn = b.Load(fn) sig := fn.raw.Type.(*types.Signature) params := sig.Params() n := params.Len() diff --git a/ssa/type.go b/ssa/type.go index 936c9b21..735a3d90 100644 --- a/ssa/type.go +++ b/ssa/type.go @@ -43,7 +43,7 @@ const ( vkFuncDecl vkFuncPtr vkClosure - vkPyFunc + vkPyFuncRef vkTuple vkPhisExpr = -1 ) From acfbe6902a85b7c5503bbf651b43ca4f1d920c23 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 12 May 2024 23:37:12 +0800 Subject: [PATCH 6/9] FuncDecl bugfix: even in C, we need to add ctx for method --- cl/_testlibc/sqlite/out.ll | 8 ++++---- cl/_testpy/callpy/in.go | 3 --- cl/_testpy/callpy/out.ll | 27 +++++---------------------- ssa/type_cvt.go | 5 ++++- 4 files changed, 13 insertions(+), 30 deletions(-) diff --git a/cl/_testlibc/sqlite/out.ll b/cl/_testlibc/sqlite/out.ll index 339ca048..bdf9be1a 100644 --- a/cl/_testlibc/sqlite/out.ll +++ b/cl/_testlibc/sqlite/out.ll @@ -13,7 +13,7 @@ _llgo_0: br i1 %1, label %_llgo_1, label %_llgo_2 _llgo_1: ; preds = %_llgo_0 - %2 = call ptr @sqlite3_errstr() + %2 = call ptr @sqlite3_errstr(i32 %0) %3 = call i32 (ptr, ...) @printf(ptr @0, i32 %0, ptr %2) call void @exit(i32 1) br label %_llgo_2 @@ -45,11 +45,11 @@ _llgo_0: %3 = extractvalue { ptr, i32 } %2, 0 %4 = extractvalue { ptr, i32 } %2, 1 call void @main.check(i32 %4) - %5 = call i32 @sqlite3_close() + %5 = call i32 @sqlite3_close(ptr %3) ret void } -declare ptr @sqlite3_errstr() +declare ptr @sqlite3_errstr(i32) declare i32 @printf(ptr, ...) @@ -59,4 +59,4 @@ declare void @"github.com/goplus/llgo/internal/runtime.init"() declare { ptr, i32 } @"github.com/goplus/llgo/x/sqlite.OpenV2"(ptr, i32, ptr) -declare i32 @sqlite3_close() +declare i32 @sqlite3_close(ptr) diff --git a/cl/_testpy/callpy/in.go b/cl/_testpy/callpy/in.go index 12424d62..21ec21ab 100644 --- a/cl/_testpy/callpy/in.go +++ b/cl/_testpy/callpy/in.go @@ -4,12 +4,9 @@ import ( "github.com/goplus/llgo/c" "github.com/goplus/llgo/py" "github.com/goplus/llgo/py/math" - "github.com/goplus/llgo/py/os" ) func main() { x := math.Sqrt(py.Float(2)) - wd := os.Getcwd() c.Printf(c.Str("sqrt(2) = %f\n"), x.Float64()) - c.Printf(c.Str("cwd = %s\n"), wd.CStr()) } diff --git a/cl/_testpy/callpy/out.ll b/cl/_testpy/callpy/out.ll index c982584d..c5c1d258 100644 --- a/cl/_testpy/callpy/out.ll +++ b/cl/_testpy/callpy/out.ll @@ -5,13 +5,9 @@ source_filename = "main" @__llgo_argc = global ptr null @__llgo_argv = global ptr null @__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 @__llgo_py.math = external global ptr -@2 = private unnamed_addr constant [5 x i8] c"sqrt\00", align 1 -@__llgo_py.os = external global ptr -@3 = private unnamed_addr constant [7 x i8] c"getcwd\00", align 1 +@1 = private unnamed_addr constant [5 x i8] c"sqrt\00", align 1 define void @main.init() { _llgo_0: @@ -21,11 +17,8 @@ _llgo_0: _llgo_1: ; preds = %_llgo_0 store i1 true, ptr @"main.init$guard", align 1 call void @"github.com/goplus/llgo/py/math.init"() - call void @"github.com/goplus/llgo/py/os.init"() %1 = load ptr, ptr @__llgo_py.math, align 8 - call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @2, ptr @__llgo_py.math.sqrt, ptr null) - %2 = load ptr, ptr @__llgo_py.os, align 8 - call void (ptr, ...) @llgoLoadPyModSyms(ptr %2, ptr @3, ptr @__llgo_py.os.getcwd, ptr null) + call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @1, ptr @__llgo_py.math.sqrt, ptr null) br label %_llgo_2 _llgo_2: ; preds = %_llgo_1, %_llgo_0 @@ -42,33 +35,23 @@ _llgo_0: %2 = call ptr @PyFloat_FromDouble(double 2.000000e+00) %3 = load ptr, ptr @__llgo_py.math.sqrt, align 8 %4 = call ptr @PyObject_CallOneArg(ptr %3, ptr %2) - %5 = load ptr, ptr @__llgo_py.os.getcwd, align 8 - %6 = call ptr @PyObject_CallNoArgs(ptr %5) - %7 = call double @PyFloat_AsDouble() - %8 = call i32 (ptr, ...) @printf(ptr @0, double %7) - %9 = call ptr @PyBytes_AsString() - %10 = call i32 (ptr, ...) @printf(ptr @1, ptr %9) + %5 = call double @PyFloat_AsDouble(ptr %4) + %6 = call i32 (ptr, ...) @printf(ptr @0, double %5) ret void } declare void @"github.com/goplus/llgo/py/math.init"() -declare void @"github.com/goplus/llgo/py/os.init"() - declare void @"github.com/goplus/llgo/internal/runtime.init"() declare ptr @PyFloat_FromDouble(double) declare ptr @PyObject_CallOneArg(ptr, ptr) -declare ptr @PyObject_CallNoArgs(ptr) - -declare double @PyFloat_AsDouble() +declare double @PyFloat_AsDouble(ptr) declare i32 @printf(ptr, ...) -declare ptr @PyBytes_AsString() - declare void @llgoLoadPyModSyms(ptr, ...) declare void @Py_Initialize() diff --git a/ssa/type_cvt.go b/ssa/type_cvt.go index 8346577e..e8bd1c3d 100644 --- a/ssa/type_cvt.go +++ b/ssa/type_cvt.go @@ -57,8 +57,11 @@ func (p Program) Type(typ types.Type, bg Background) Type { // FuncDecl converts a Go/C function declaration into raw type. func (p Program) FuncDecl(sig *types.Signature, bg Background) Type { + recv := sig.Recv() if bg == InGo { - sig = p.gocvt.cvtFunc(sig, sig.Recv()) + sig = p.gocvt.cvtFunc(sig, recv) + } else if recv != nil { // even in C, we need to add ctx for method + sig = FuncAddCtx(recv, sig) } return &aType{p.toLLVMFunc(sig), rawType{sig}, vkFuncDecl} } From ddc2c56115b053141683c7dd3c39ef04d5fac198 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 12 May 2024 23:42:16 +0800 Subject: [PATCH 7/9] gentests --- chore/gentests/gentests.go | 2 +- cl/_testpy/math/out.ll | 12 ++++++------ cl/compile_test.go | 2 +- py/math/llgo_autogen.lla | Bin 563 -> 628 bytes py/os/llgo_autogen.lla | Bin 560 -> 627 bytes x/sqlite/sqlite.ll | 10 +++++----- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/chore/gentests/gentests.go b/chore/gentests/gentests.go index bb34a1a7..2a8c2214 100644 --- a/chore/gentests/gentests.go +++ b/chore/gentests/gentests.go @@ -33,7 +33,7 @@ func main() { llgenDir(dir + "/cl/_testlibc") llgenDir(dir + "/cl/_testrt") - llgenDir(dir + "/cl/_testpy") + llgenDir(dir+"/cl/_testpy", "") llgenDir(dir+"/cl/_testdata", "") } diff --git a/cl/_testpy/math/out.ll b/cl/_testpy/math/out.ll index 66f80e8f..378284c6 100644 --- a/cl/_testpy/math/out.ll +++ b/cl/_testpy/math/out.ll @@ -1,19 +1,19 @@ -; ModuleID = 'command-line-arguments' -source_filename = "command-line-arguments" +; ModuleID = 'math' +source_filename = "math" @__llgo_py.math.sqrt = external global ptr -@"command-line-arguments.init$guard" = global ptr null +@"math.init$guard" = global ptr null @__llgo_py.math = linkonce global ptr null @0 = private unnamed_addr constant [5 x i8] c"math\00", align 1 @1 = private unnamed_addr constant [5 x i8] c"sqrt\00", align 1 -define void @command-line-arguments.init() { +define void @math.init() { _llgo_0: - %0 = load i1, ptr @"command-line-arguments.init$guard", align 1 + %0 = load i1, ptr @"math.init$guard", align 1 br i1 %0, label %_llgo_2, label %_llgo_1 _llgo_1: ; preds = %_llgo_0 - store i1 true, ptr @"command-line-arguments.init$guard", align 1 + store i1 true, ptr @"math.init$guard", align 1 %1 = load ptr, ptr @__llgo_py.math, align 8 call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @1, ptr @__llgo_py.math.sqrt, ptr null) %2 = load ptr, ptr @__llgo_py.math, align 8 diff --git a/cl/compile_test.go b/cl/compile_test.go index a1237888..6f417cbe 100644 --- a/cl/compile_test.go +++ b/cl/compile_test.go @@ -29,7 +29,7 @@ func testCompile(t *testing.T, src, expected string) { } func TestFromTestpy(t *testing.T) { - cltest.FromDir(t, "callpy", "./_testpy", false) + cltest.FromDir(t, "", "./_testpy", false) } func TestFromTestlibc(t *testing.T) { diff --git a/py/math/llgo_autogen.lla b/py/math/llgo_autogen.lla index 7c9261cd20f8f5f5f93d81bbf0a054f81dcb7305..8eaa159b98b5e33266d9b6d3708f3d6a34c2f8c9 100644 GIT binary patch delta 574 zcmV-E0>S;W1oQ-dP)h>@6aWAK2mtrItXL5TS`EMf001xr000jF8~|)=XK!C&b#!lM zWo|BPY*kbV00Y9}KxV|^KxTD#3jhHG^#K3?1QY-O0HsvHYTPgoz3VFm( zNGSNwOQ3~7k8LqpOL0WUk}Jz0ru5%ClI`7Wnq;%AFS6u+nfGSiJoy^F8quS?`3#@n ztXA&6-=vjkmbGcI@0N(QS+>Kn;qLy7b*8tKEbkOb%^OK6(c38zV?|l|ld>IBf0A~; zt)oQw=%m#gp+>WzrFE7S2hdWbmHSZl+=_@GcA21i#OF*DflB`}x|08gX7shS>VZ26 zz4pzBk_%yfp)$I2Ts!#w5gtKZ{)8&>Xg{(nN`RxPHRPfi@06DCV3dG& zwH=+u@P~~JW>*Yg;afn%1*kj;ogE|Jt`vZcB?!Vx0Qp8DEJl{qvprQkyr+U=tS)FDMi8XA9d4S|SXYkA_#X<=7g@Y@Nl@nEpqixEzEte5zho8i z3FCDqx_B2jUdI>xFq(z^15ir=0v-bt000080QbDCSP=(W4Zr~a05AoU;sGcE!s3$* M0wD$o0ssI20R7Dc4gdfE literal 563 zcmWIWW@Zs#U|`^2SeCdZ;+4$4gnC8>21^zO27U$^hMb)A{P@JulKk}4JiVNp&=5`r z=If3QX*Yqmw1S&~k>x8;HQ0cqlLNC48Hlvr|E#T-y2$BbmSl&~heUllo^ShlCz)+* zTk1JoZBftP?{~L^r5`tIul1aKuln4{=_QQ(vn)@Be=lJF8*`)A+kK|qv7LHLS04*{ zRu%K^IP2Egb}P3SOZs1PDstuS(>?fJmr?Pw%13R_o$^1Y27XP`G5a+4saqiD&MTUH zOHEULw%_v5NX##C=j9G~bcOSj=grbXT$)!_he`gAlX`glQitwVnK_?kCvv8qaab0b zx^mNp5^igO&EhAR)_;?6b>s-?iaFRKaO}EM;f<_=4;I}xn85LV38%zaPKWdE6J{9+ zOy1!4ZT{Q&ix`%$sRrn?cn0e&yuQQ7y4a_-V&>ta=b1DM!xFDFd$qJpz1mjopDnXr zuR8xyki*pGD?bglT{VukJ(@L9R8^rm{TR_8nXDO!%?Q;!QhupFaL~mB!YMp2jBs-!1qj!rQMNJh}7#lFlRN0w?mVJMJ30WyIB E0Cf7`O8@`> diff --git a/py/os/llgo_autogen.lla b/py/os/llgo_autogen.lla index a8378f7bad00b6945832c09bb27594f0b9c86aee..d9ad409c2d002012a98d356d4be56f0651eecd7a 100644 GIT binary patch delta 573 zcmV-D0>b^U1oH%cP)h>@6aWAK2mlAYtXN@Di`>5f000~X000jF8~|)=XK!C&b#!lM zWo|BPY*kbV00Z9QKxW|LKxTD#3jhHG^#K3?1QY-O0Hst-Yuqppz3W#Drb}WlUV9yA zNGSNwOQ3;3k4Z3ENpVGG$;fgV6Z+pXlI{IS)9k|fA`8ubyf^dSNY`*{c(26GclZWp zwRFGwb;?Y$tWB%>ZmCplmhG@K-5KdjZ<(l`q!OAo0u!Ro5+Xv%s`C4)9a7V!wQ%eY z$29Tcgw<3*t;`yi)>%@1ij_(&-IuzjmPZJ%%>&&lwa+=wtrfCeNkNtrFcLUD; z&!Or3A>vM8`3IoW>?WH@ihU)k<11Md7%N%R0=ggQQ0g#}8!w6jUKFzzt5du{mf726 z*B>ifP--SAP9X_CUEn?#5QMoKZkpCuSB=Z~>IC7-EZ)pVQ0C%*mZ;ahP~@+_SWM9g z;s0bN@iuV0f*;PpI4I-|P)h*<9s?8r000O82feIVVNr|RzX1RM90il#0Vo3A;*$vi LAqEHn00000kW~ZL literal 560 zcmWIWW@Zs#U|`^2Sf98iV!z_dGc}A145};)4Ezi-3^_UJ`SFRRCHd*8d3rfHp&^_M z%r6}s(q02`X$3a}BgvsB{Yq)92 zjzybNQY?Kn{(kR^ubjHAu|k=D*3R;09#MxDKin$xntexmpx)i+xvghJ0`t5=!zTvq z>^xPQvPy8JPwq?)^B_)N?nc&o@vL%+t4(qrZMoCFjH~$J4ff+k8;cKRtx^bAJG``H z+M0h?xRy?Pr?-CPQ#me~*ACac=Kg-LZ_=;38ESQE$96BF~ zJAZbj6&JbZ%H5k_onMqbLpw5%$td5bw&j}K Date: Sun, 12 May 2024 23:43:51 +0800 Subject: [PATCH 8/9] x/sqlite/llgo_autogen.lla --- x/sqlite/llgo_autogen.lla | Bin 2292054 -> 2292057 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/x/sqlite/llgo_autogen.lla b/x/sqlite/llgo_autogen.lla index cbd7267eb380208fed78f3d5441a07fd630bc5fb..6aa88aa437355bc32fe7682f79b5b0d8d3fdcf25 100644 GIT binary patch delta 829 zcmV-D1H$~)@{0l4@{0k0gaL#Cgad>Ggaw2Kga?EOgb9QSgbRcWgbjoagb#!egb{=i zgcF1mgcXDqgcpPugc*bygd2n$gdKz)gdc<;gdwyd#`P%dysTK{t#(tO0ssJ94*&oO z02}~wacpUHWiD)NRa6N81FPadW?18w?)4%bf2g8_R}yAMl~So)bWyd^NL_Rj5%5q; zj!lh;rW(z^*Tz7Ayhwtwnr!mmKF&SoaAO|9cN*sye)|GGfx86pKly4L(e)&uDbBMA z#tEIgOtQZiad@X?G-nZ9J|hfCxP~G}KarzrnsF!w5e^v%@r31sqct2qafV2ui?aM* ze+t1XNI4q;H1olmrY%mj8Y6=Eha?YKEK4Mqu0kwJ0Fq;@X)%081QtImbo1k>YF`;6 z)RJ!*XSylV4BG;)+ET_X?FS72!x4=z4P$^jcLY?-2!t3V1o$$*6#-F*6^?}}?JZ$Z z)D%gggeBq_5rRkt8Q+9B?+l$%lu=Sp8K6EJLKCNC zcPGTTj_F^nUQeuaEMdA`?!BS7_YZQv+_-J}y&X`pz;ss*?_xQo=gZ+=CdcV}fAvXm zVU2$>n1&2)r8$53+(=0H!dV!Vgk6Txt~4E>mej?V$;~USM#at*r8$)%$V>CR-b)qT zZSVP|+Ow_28XgRW^k8tl2j{o)U~@sdyYL1s+*yL}MpQ=ht~FxyU#dvz8qy!ikOP^> zu1qwPA?IyF&KiacjvLZz8*;jpf4)VjUsEe<-tQXIzu1`f=NmKVY0M2pagW22JeBKa z*EDv0a4r|!S;zZ|4vBNcM2&)D9IhY+hHB$>zB^jk-+2JNUyndY8D|1(Sw(W0amt|V zDLetM2j50rp>(f7DJX5=l|o9blyngm&OG!qVs#=extSX^_C6yNj2#Oq829+7_TJHq z#u22G(I;(xuYQ?cH?x!eAD5i?B4G{eysTK{t#(tO0ssJ9mkRkJBLb`9moNDuAqJoL HA^-pYblGxu delta 853 zcmV-b1FHPl@{0l1@{0k0gaL#Cgad>Ggaw2Kga?EOgb9QSgbRcWgbjoagb#!egb{=i zgcF1mgcXDqgcpPugc*bygd2n$gdKz)gdc<;gdwyd#`P%je5_bZd<6uZ0ssI+4*&oO z02}~wacpUHWiD)NRa6N812=L&W?gcZ?)4%be^NyWuO!TjDy34p=%Q++k-F$6BH*Ex z9Ge;wO*P8D*Tz72OdcdCtI38WzK?UyIT-T@zSAhf@Y@&g3Eahq|H;;qkZz_iO>mY@ zF^=iKS23f(;Zo`iUG}(~Ltgh;YbAfTt`Y9Bts_i8DlEU6kej ze-a2@LBiP>pt%QjnzlUEYJv#jAL1-vkt`8ox(=``0Z4|irbX}>5t#q6)Xk5ls(odQ z(2=~Poav@aGprGK)mAcYWj$yB7`AAHX%GSAI%A+>#vs5bCcu*cjtB??tZ*zamdcHs2jKN3iee<9ohI9rO(7}M~#Zc6g~QDYK`s+xp~)@C_( zezo&xw&NislvH-s8?!EPtS zzK-c%j$Tci_p%F^PMdpoDDJ(3+^@DylYX}YN*0)PSW7b~|?=m?~-=$BAe~Z!N zCxc1A;9i>k+s=)IgfE;0VL{ksD6LY{0cuHIjJe!%#cG)EwxTqrQUtlQc+-1{qPyum zuTXoww^+@C{*WH@`+IP4D-YH;h<6v>z=fSn@ZE^Yi0-vUET5%{q_!cwp$s{YiLBB@ zLm6_>G~~QyNdLGY-KHUDd+8gLe|iZGEXnh@ZnjNh zRY&Gxqw96BFX@mt*G$yNImW>nVqmB?PV2X=75(i8aQ5dB2q~jfU@fXhE>lh!ls$zf z;Pv2}s7sX2H7Et8HM~+tsg;s0#KM^e-b0$pm)yy<8gITJ Date: Sun, 12 May 2024 23:45:56 +0800 Subject: [PATCH 9/9] testpy: os.Getcwd --- cl/_testpy/callpy/in.go | 3 +++ cl/_testpy/callpy/out.ll | 25 +++++++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/cl/_testpy/callpy/in.go b/cl/_testpy/callpy/in.go index 21ec21ab..12424d62 100644 --- a/cl/_testpy/callpy/in.go +++ b/cl/_testpy/callpy/in.go @@ -4,9 +4,12 @@ import ( "github.com/goplus/llgo/c" "github.com/goplus/llgo/py" "github.com/goplus/llgo/py/math" + "github.com/goplus/llgo/py/os" ) func main() { x := math.Sqrt(py.Float(2)) + wd := os.Getcwd() c.Printf(c.Str("sqrt(2) = %f\n"), x.Float64()) + c.Printf(c.Str("cwd = %s\n"), wd.CStr()) } diff --git a/cl/_testpy/callpy/out.ll b/cl/_testpy/callpy/out.ll index c5c1d258..1f6d541c 100644 --- a/cl/_testpy/callpy/out.ll +++ b/cl/_testpy/callpy/out.ll @@ -5,9 +5,13 @@ source_filename = "main" @__llgo_argc = global ptr null @__llgo_argv = global ptr null @__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 @__llgo_py.math = external global ptr -@1 = private unnamed_addr constant [5 x i8] c"sqrt\00", align 1 +@2 = private unnamed_addr constant [5 x i8] c"sqrt\00", align 1 +@__llgo_py.os = external global ptr +@3 = private unnamed_addr constant [7 x i8] c"getcwd\00", align 1 define void @main.init() { _llgo_0: @@ -17,8 +21,11 @@ _llgo_0: _llgo_1: ; preds = %_llgo_0 store i1 true, ptr @"main.init$guard", align 1 call void @"github.com/goplus/llgo/py/math.init"() + call void @"github.com/goplus/llgo/py/os.init"() %1 = load ptr, ptr @__llgo_py.math, align 8 - call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @1, ptr @__llgo_py.math.sqrt, ptr null) + call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @2, ptr @__llgo_py.math.sqrt, ptr null) + %2 = load ptr, ptr @__llgo_py.os, align 8 + call void (ptr, ...) @llgoLoadPyModSyms(ptr %2, ptr @3, ptr @__llgo_py.os.getcwd, ptr null) br label %_llgo_2 _llgo_2: ; preds = %_llgo_1, %_llgo_0 @@ -35,23 +42,33 @@ _llgo_0: %2 = call ptr @PyFloat_FromDouble(double 2.000000e+00) %3 = load ptr, ptr @__llgo_py.math.sqrt, align 8 %4 = call ptr @PyObject_CallOneArg(ptr %3, ptr %2) - %5 = call double @PyFloat_AsDouble(ptr %4) - %6 = call i32 (ptr, ...) @printf(ptr @0, double %5) + %5 = load ptr, ptr @__llgo_py.os.getcwd, align 8 + %6 = call ptr @PyObject_CallNoArgs(ptr %5) + %7 = call double @PyFloat_AsDouble(ptr %4) + %8 = call i32 (ptr, ...) @printf(ptr @0, double %7) + %9 = call ptr @PyBytes_AsString(ptr %6) + %10 = call i32 (ptr, ...) @printf(ptr @1, ptr %9) ret void } declare void @"github.com/goplus/llgo/py/math.init"() +declare void @"github.com/goplus/llgo/py/os.init"() + declare void @"github.com/goplus/llgo/internal/runtime.init"() declare ptr @PyFloat_FromDouble(double) declare ptr @PyObject_CallOneArg(ptr, ptr) +declare ptr @PyObject_CallNoArgs(ptr) + declare double @PyFloat_AsDouble(ptr) declare i32 @printf(ptr, ...) +declare ptr @PyBytes_AsString(ptr) + declare void @llgoLoadPyModSyms(ptr, ...) declare void @Py_Initialize()