From 64c13fa9ae686bf093273ef088e855e3a88f560d Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 12 May 2024 00:24:56 +0800 Subject: [PATCH 1/5] llgo/ssa: NewPyFunc fix --- cl/_testpy/callpy/out.ll | 10 +++++----- cl/compile.go | 13 +++++++++---- py/math/llgo_autogen.lla | Bin 0 -> 563 bytes py/os/llgo_autogen.lla | Bin 0 -> 560 bytes ssa/decl.go | 5 ++++- ssa/package.go | 12 ++++++------ 6 files changed, 24 insertions(+), 16 deletions(-) create mode 100644 py/math/llgo_autogen.lla create mode 100644 py/os/llgo_autogen.lla 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 0000000000000000000000000000000000000000..1daa2e16ed71aae6a33a4adb82f10a7b636a6f76 GIT binary patch literal 563 zcmWIWW@Zs#U|`^2kl4RE;+4$4gnC8>21^zO27U$^hMb)A{P@JulKk}4JiVNp&=5`r zW{0WvX^uc#TEWf0$nq7a8f?JQ$${C23`AP*f7aGZUF38zOR~f0L!!PN&$oTOlgu`@ zE%ltPwy5Xt_q$ud(vO?9*LqIASAFi}^b$t?S(YcmzZbCojk(e5?LJfQ*iOBrtB(ae ztBQGdoOSDLyOmpvCH=2C6}fWv=^lKq%cyu-<)gOePWhix1HY!}n0=c2)Gd&6=M_!9 zrKTxA+i!VjB<2^n^Ku6~y25$N^JeKGF3l^e!zBO5Nj%YmkI&y?`#T;xAICkBs@J80b2a9eTOyGFGgj3=yr^9*o3A2m@ zCU5ZjHvjGXMGQ;WR0H%`JcIQXUfOf7`j_YonZIN%`Hm$8}p@nug5>sUeb z{myGD`;IMnCj8iD@ur=-PaprgN@MFrPh*q+?-u+M;q6xsp4|C=N#~JsffM=bHyV5L zOWEJ%J*ghx&B!Fjj4LK3fHBO#0E{YzC5<2!M!d2@;uS4U1H4(;K*||`Fce6i0GYr5 E0NTyp8~^|S literal 0 HcmV?d00001 diff --git a/py/os/llgo_autogen.lla b/py/os/llgo_autogen.lla new file mode 100644 index 0000000000000000000000000000000000000000..b018d58d72fbda97648a80784eb46a63b2fced9d GIT binary patch literal 560 zcmWIWW@Zs#U|`^2klnvJV!z_dGc}A145};)4Ezi-3^_UJ`SFRRCHd*8d3rfHp&^_M z%wALN(|mxqw1S&~k>x8;HQ0cqlTT+IHV|yK(GBAZ^Qbvu2}HQcmh z$D&OsDVDw(f4}#|S5Dp5SfR{6YiId0kElb7A8r+T&Ay{OQ15Q^+}1N9fq7n`;S+;) zcAlzDStYpACwHcYc@U>BcO&b)cvd;Z)h4-*w%lo7##Q|A2K#ZNjm3wuRw;z59bQ^8 zZOy+cTuZ0D(_6ptsT`NgYlrJzbALbBH|f{i47ED7V>_awb}sdESUcOW!pm~|fu40T zSNY}%-)Nk(pXsyDSE1u^3?V0D4o?x#GYjIrA$9U$SKHo?EOwsPqxL8;)FrRyd8)A7 z@%GiP$?~@uPUvtgh+^nUb85U_c}6ek&5r+(2d>^1`pI!G;7w?f$(lJE7kw<*Cbqrg zoj*I%ii_NHWR!1I+j33rapQrfN2V7V3Cy_bq`=AN(j2T6w&R-~ zkJ?FHHQl)^$!?+L$>ILLO9Q1|U&?zK_iD%8F7@`{%#$krH@L(-UvMJ4c<#(adk?)& z6aK^-;LXS+$BZi)C4kY(zyORVh9!+47DlA9LLwC{LIb>6*+9w}fiM(E9|f7f003pw B-7EkA literal 0 HcmV?d00001 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()) From 0912f1f509789f44bae1749e45765277011dc49f Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 12 May 2024 11:11:19 +0800 Subject: [PATCH 2/5] PyInit --- cl/_testpy/callpy/out.ll | 3 ++ cl/_testpy/math/out.ll | 2 +- cl/cltest/cltest.go | 5 ++++ cl/compile.go | 3 +- cl/compile_test.go | 2 +- cl/import.go | 2 +- internal/build/build.go | 60 ++++++++++++++++++++++++++++------------ internal/llgen/llgen.go | 4 +++ internal/llgen/llgenf.go | 4 +++ ssa/cl_test.go | 2 +- ssa/decl.go | 1 + ssa/package.go | 58 ++++++++++++++++++++++++++++++-------- ssa/stmt_builder.go | 35 +++++++++++++++++++---- 13 files changed, 140 insertions(+), 41 deletions(-) diff --git a/cl/_testpy/callpy/out.ll b/cl/_testpy/callpy/out.ll index c1589558..d3892453 100644 --- a/cl/_testpy/callpy/out.ll +++ b/cl/_testpy/callpy/out.ll @@ -26,6 +26,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0 define void @main(i32 %0, ptr %1) { _llgo_0: + call void @Py_Initialize() store i32 %0, ptr @__llgo_argc, align 4 store ptr %1, ptr @__llgo_argv, align 8 call void @"github.com/goplus/llgo/internal/runtime.init"() @@ -57,3 +58,5 @@ declare double @PyFloat_AsDouble() declare i32 @printf(ptr, ...) declare ptr @PyBytes_AsString() + +declare void @Py_Initialize() diff --git a/cl/_testpy/math/out.ll b/cl/_testpy/math/out.ll index f5feead3..4fd8d274 100644 --- a/cl/_testpy/math/out.ll +++ b/cl/_testpy/math/out.ll @@ -1,7 +1,7 @@ ; ModuleID = 'math' source_filename = "math" -@__llgo_py.math.sqrt = external global ptr +@__llgo_py.math.sqrt = linkonce 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 diff --git a/cl/cltest/cltest.go b/cl/cltest/cltest.go index 4b21cb04..436b272e 100644 --- a/cl/cltest/cltest.go +++ b/cl/cltest/cltest.go @@ -159,6 +159,11 @@ func TestCompileEx(t *testing.T, src any, fname, expected string) { if err != nil { t.Fatal("cl.NewPackage failed:", err) } + + if prog.NeedPyInit() { // call PyInit if needed + ret.PyInit() + } + if v := ret.String(); v != expected { t.Fatalf("\n==> got:\n%s\n==> expected:\n%s\n", v, expected) } diff --git a/cl/compile.go b/cl/compile.go index d762356a..1b1a97bd 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -380,8 +380,7 @@ const ( ) func callRuntimeInit(b llssa.Builder, pkg llssa.Package) { - sig := types.NewSignatureType(nil, nil, nil, nil, nil, false) - fn := pkg.NewFunc(RuntimeInit, sig, llssa.InC) // don't need to convert runtime.init + fn := pkg.NewFunc(RuntimeInit, llssa.NoArgsNoRet, llssa.InC) // don't need to convert runtime.init b.Call(fn.Expr) } diff --git a/cl/compile_test.go b/cl/compile_test.go index 1af95938..14ad7339 100644 --- a/cl/compile_test.go +++ b/cl/compile_test.go @@ -33,7 +33,7 @@ func TestFromTestpy(t *testing.T) { } func TestFromTestlibc(t *testing.T) { - cltest.FromDir(t, "", "./_testlibc", false) + cltest.FromDir(t, "", "./_testlibc", true) } func TestFromTestrt(t *testing.T) { diff --git a/cl/import.go b/cl/import.go index fe70af9a..1ed645ab 100644 --- a/cl/import.go +++ b/cl/import.go @@ -214,7 +214,7 @@ func (p *context) initLink(line string, prefix int, f func(inPkgName string) (fu } else { panic(line + ": no specified call convention. eg. //go:linkname Printf C.printf") } - } else { + } else if c := inPkgName[0]; c >= 'A' && c <= 'Z' { fmt.Fprintln(os.Stderr, "==>", line) fmt.Fprintf(os.Stderr, "llgo: linkname %s not found and ignored\n", inPkgName) } diff --git a/internal/build/build.go b/internal/build/build.go index 2e18e97f..38ccc5a8 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -160,12 +160,22 @@ func Do(args []string, conf *Config) { } } -func setNeedRuntime(pkg *packages.Package) { - pkg.ID = "" // just use pkg.Module to mark it needs runtime +func setNeedRuntimeOrPyInit(pkg *packages.Package, needRuntime, needPyInit bool) { + v := []byte{'0', '0'} + if needRuntime { + v[0] = '1' + } + if needPyInit { + v[1] = '1' + } + pkg.ID = string(v) // just use pkg.ID to mark it needs runtime } -func isNeedRuntime(pkg *packages.Package) bool { - return pkg.ID == "" +func isNeedRuntimeOrPyInit(pkg *packages.Package) (needRuntime, needPyInit bool) { + if len(pkg.ID) == 2 { + return pkg.ID[0] == '1', pkg.ID[1] == '1' + } + return } func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, verbose bool) (pkgs []*aPackage) { @@ -204,9 +214,7 @@ func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, ve pkg.ExportFile = command default: buildPkg(prog, aPkg, mode, verbose) - if prog.NeedRuntime() { - setNeedRuntime(pkg) - } + setNeedRuntimeOrPyInit(pkg, prog.NeedRuntime(), prog.NeedPyInit()) } } return @@ -225,27 +233,43 @@ func linkMainPkg(pkg *packages.Package, pkgs []*aPackage, runtimeFiles []string, args[1] = app args[2] = "-Wno-override-module" needRuntime := false + needPyInit := false packages.Visit([]*packages.Package{pkg}, nil, func(p *packages.Package) { if p.ExportFile != "" && !isRuntimePkg(p.PkgPath) { // skip packages that only contain declarations args = appendLinkFiles(args, p.ExportFile) + need1, need2 := isNeedRuntimeOrPyInit(p) if !needRuntime { - needRuntime = isNeedRuntime(p) + needRuntime = need1 + } + if !needPyInit { + needPyInit = need2 } } }) + + var aPkg *aPackage + for _, v := range pkgs { + if v.Package == pkg { // found this package + aPkg = v + break + } + } + + dirty := false if needRuntime && runtimeFiles != nil { args = append(args, runtimeFiles...) } else { - for _, aPkg := range pkgs { - if aPkg.Package == pkg { // make empty runtime.init if no runtime needed - lpkg := aPkg.LPkg - lpkg.FuncOf(cl.RuntimeInit).MakeBody(1).Return() - if needLLFile(mode) { - os.WriteFile(pkg.ExportFile, []byte(lpkg.String()), 0644) - } - break - } - } + dirty = true + fn := aPkg.LPkg.FuncOf(cl.RuntimeInit) + fn.MakeBody(1).Return() + } + if needPyInit { + dirty = aPkg.LPkg.PyInit() + } + + if dirty && needLLFile(mode) { + lpkg := aPkg.LPkg + os.WriteFile(pkg.ExportFile, []byte(lpkg.String()), 0644) } if verbose || mode != ModeRun { diff --git a/internal/llgen/llgen.go b/internal/llgen/llgen.go index a9e70e63..801a81f0 100644 --- a/internal/llgen/llgen.go +++ b/internal/llgen/llgen.go @@ -79,6 +79,10 @@ func Gen(pkgPath, inFile string, src any) string { ret, err := cl.NewPackage(prog, ssaPkg, files) check(err) + if prog.NeedPyInit() { // call PyInit if needed + ret.PyInit() + } + return ret.String() } diff --git a/internal/llgen/llgenf.go b/internal/llgen/llgenf.go index b7eeddaf..64a06f55 100644 --- a/internal/llgen/llgenf.go +++ b/internal/llgen/llgenf.go @@ -82,6 +82,10 @@ func GenFrom(fileOrPkg string) string { ret, err := cl.NewPackage(prog, ssaPkg, pkg.Syntax) check(err) + if prog.NeedPyInit() { // call PyInit if needed + ret.PyInit() + } + return ret.String() } diff --git a/ssa/cl_test.go b/ssa/cl_test.go index 4d79ec49..9be95684 100644 --- a/ssa/cl_test.go +++ b/ssa/cl_test.go @@ -23,7 +23,7 @@ import ( ) func TestFromTestpy(t *testing.T) { - cltest.FromDir(t, "", "../cl/_testpy", false) + cltest.FromDir(t, "", "../cl/_testpy", true) } func TestFromTestrt(t *testing.T) { diff --git a/ssa/decl.go b/ssa/decl.go index 7c2b6933..f23d23a4 100644 --- a/ssa/decl.go +++ b/ssa/decl.go @@ -299,6 +299,7 @@ func (p Package) NewPyFunc(name string, sig *types.Signature) PyFunction { return v } prog := p.Prog + prog.needPyInit = true obj := p.NewVar(name, prog.PyObjectPtrPtr().RawType(), InC) obj.Init(prog.Null(obj.Type)) obj.impl.SetLinkage(llvm.LinkOnceAnyLinkage) diff --git a/ssa/package.go b/ssa/package.go index e64df9c3..bb976c89 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -194,6 +194,11 @@ func (p Program) NeedRuntime() bool { return p.needRuntime } +// NeedPyInit returns if the current package needs Python initialization. +func (p Program) NeedPyInit() bool { + return p.needPyInit +} + func (p Program) runtime() *types.Package { if p.rt == nil { p.rt = p.rtget() @@ -262,8 +267,11 @@ func (p Program) NewPackage(name, pkgPath string) Package { fns := make(map[string]Function) stubs := make(map[string]Function) pyfns := make(map[string]PyFunction) + pymods := make(map[string]Global) p.needRuntime = false - return &aPackage{mod, gbls, fns, stubs, pyfns, p} + // Don't need reset p.needPyInit here + // p.needPyInit = false + return &aPackage{mod, gbls, fns, stubs, pyfns, pymods, p} } // PyObjectPtrPtr returns the **py.Object type. @@ -363,12 +371,13 @@ func (p Program) Float64() Type { // initializer) and "init#%d", the nth declared init function, // and unspecified other things too. type aPackage struct { - mod llvm.Module - vars map[string]Global - fns map[string]Function - stubs map[string]Function - pyfns map[string]PyFunction - Prog Program + mod llvm.Module + vars map[string]Global + fns map[string]Function + stubs map[string]Function + pyfns map[string]PyFunction + pymods map[string]Global + Prog Program } type Package = *aPackage @@ -506,23 +515,38 @@ func (p Program) tyCallOneArg() *types.Signature { return p.callOneArg } -// ImportPyMod imports a Python module. -func (b Builder) ImportPyMod(path string) Expr { - pkg := b.Func.Pkg - fnImp := pkg.pyFunc("PyImport_ImportModule", b.Prog.tyImportPyModule()) - return b.Call(fnImp, b.CStr(path)) +// PyInit initializes Python for a main package. +func (p Package) PyInit() bool { + if fn := p.FuncOf("main"); fn != nil { + b := fn.NewBuilder() + b.SetBlockEx(fn.Block(0), AtStart).CallPyInit() + b.Dispose() + return true + } + return false } // NewPyModVar creates a new global variable for a Python module. func (p Package) NewPyModVar(name string) Global { + if v, ok := p.pymods[name]; ok { + return v + } prog := p.Prog objPtr := prog.PyObjectPtrPtr().raw.Type g := p.NewVar(name, objPtr, InC) g.Init(prog.Null(g.Type)) g.impl.SetLinkage(llvm.LinkOnceAnyLinkage) + p.pymods[name] = g return g } +// ImportPyMod imports a Python module. +func (b Builder) ImportPyMod(path string) Expr { + pkg := b.Func.Pkg + fnImp := pkg.pyFunc("PyImport_ImportModule", b.Prog.tyImportPyModule()) + return b.Call(fnImp, b.CStr(path)) +} + func (b Builder) pyCall(fn Expr, args []Expr) (ret Expr) { prog := b.Prog pkg := b.Func.Pkg @@ -542,4 +566,14 @@ func (b Builder) pyCall(fn Expr, args []Expr) (ret Expr) { return } +// CallPyInit calls Py_Initialize. +func (b Builder) CallPyInit() (ret Expr) { + fn := b.Func.Pkg.pyFunc("Py_Initialize", NoArgsNoRet) + return b.Call(fn) +} + +var ( + NoArgsNoRet = types.NewSignatureType(nil, nil, nil, nil, nil, false) +) + // ----------------------------------------------------------------------------- diff --git a/ssa/stmt_builder.go b/ssa/stmt_builder.go index bb1744b8..817d6524 100644 --- a/ssa/stmt_builder.go +++ b/ssa/stmt_builder.go @@ -57,15 +57,40 @@ type aBuilder struct { // Builder represents a builder for creating instructions in a function. type Builder = *aBuilder -// SetBlock sets the current block to the specified basic block. +// Dispose disposes of the builder. +func (b Builder) Dispose() { + b.impl.Dispose() +} + +// SetBlock means SetBlockEx(blk, AtEnd). func (b Builder) SetBlock(blk BasicBlock) Builder { - if b.Func != blk.fn { - panic("mismatched function") - } if debugInstr { log.Printf("Block _llgo_%v:\n", blk.idx) } - b.impl.SetInsertPointAtEnd(blk.impl) + b.SetBlockEx(blk, AtEnd) + return b +} + +type InsertPoint int + +const ( + AtEnd InsertPoint = iota + AtStart +) + +// SetBlockEx sets blk as current basic block and pos as its insert point. +func (b Builder) SetBlockEx(blk BasicBlock, pos InsertPoint) Builder { + if b.Func != blk.fn { + panic("mismatched function") + } + switch pos { + case AtEnd: + b.impl.SetInsertPointAtEnd(blk.impl) + case AtStart: + b.impl.SetInsertPointBefore(blk.impl.FirstInstruction()) + default: + panic("SetBlockEx: invalid pos") + } return b } From fbb2150d88cc52bc39896264e2ffbb63aedc292f Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 12 May 2024 11:13:04 +0800 Subject: [PATCH 3/5] TestFromTestpy --- ssa/cl_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ssa/cl_test.go b/ssa/cl_test.go index 9be95684..4d79ec49 100644 --- a/ssa/cl_test.go +++ b/ssa/cl_test.go @@ -23,7 +23,7 @@ import ( ) func TestFromTestpy(t *testing.T) { - cltest.FromDir(t, "", "../cl/_testpy", true) + cltest.FromDir(t, "", "../cl/_testpy", false) } func TestFromTestrt(t *testing.T) { From f9ef9cab8157c0f225d2444ce9a81c53947e8a50 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 12 May 2024 11:22:55 +0800 Subject: [PATCH 4/5] TestSetBlockEx --- ssa/ssa_test.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/ssa/ssa_test.go b/ssa/ssa_test.go index 17b7ccf5..08f00f2d 100644 --- a/ssa/ssa_test.go +++ b/ssa/ssa_test.go @@ -25,6 +25,28 @@ import ( "github.com/goplus/llvm" ) +func TestSetBlock(t *testing.T) { + defer func() { + if r := recover(); r == nil { + t.Log("SetBlock: no error?") + } + }() + fn := &aFunction{} + b := &aBuilder{Func: fn} + b.SetBlock(&aBasicBlock{}) +} + +func TestSetBlockEx(t *testing.T) { + defer func() { + if r := recover(); r == nil { + t.Log("SetBlockEx: no error?") + } + }() + fn := &aFunction{} + b := &aBuilder{Func: fn} + b.SetBlockEx(&aBasicBlock{fn: fn}, -1) +} + func TestSetPython(t *testing.T) { prog := NewProgram(nil) typ := types.NewPackage("foo", "foo") From 0b058bc2e8f6e2a85770c7a336302e1e2e2395c9 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 12 May 2024 11:26:09 +0800 Subject: [PATCH 5/5] test NewPyModVar --- ssa/ssa_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ssa/ssa_test.go b/ssa/ssa_test.go index 08f00f2d..ef60f7af 100644 --- a/ssa/ssa_test.go +++ b/ssa/ssa_test.go @@ -147,6 +147,10 @@ func TestPyFunc(t *testing.T) { if pkg.NewPyFunc("a", sig) != a { t.Fatal("NewPyFunc(a) failed") } + foo := pkg.NewPyModVar("foo") + if pkg.NewPyModVar("foo") != foo { + t.Fatal("NewPyModVar(foo) failed") + } } func TestVar(t *testing.T) {