From 9ac0450255c70b5a4cf8fbbc7ea4c2e24ebe45a2 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 12 May 2024 18:27:23 +0800 Subject: [PATCH] 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