diff --git a/cl/builtin_test.go b/cl/builtin_test.go index 30841981..160aa1b3 100644 --- a/cl/builtin_test.go +++ b/cl/builtin_test.go @@ -226,5 +226,5 @@ func TestErrVarOf(t *testing.T) { } ssaPkg := &ssa.Package{Pkg: pkgTypes} g := &ssa.Global{Pkg: ssaPkg} - ctx.varOf(g) + ctx.varOf(nil, g) } diff --git a/cl/compile.go b/cl/compile.go index ff024f27..edcc1fde 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -371,7 +371,7 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do b.SetBlockEx(ret, llssa.AfterInit) for _, modName := range modNames { objs := mods[modName] - b.LoadPyModSyms(modName, objs...) + b.PyLoadModSyms(modName, objs...) } } }) @@ -395,13 +395,13 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do jumpTo := p.jumpTo(jump) modPath := p.pyMod modName := pysymPrefix + modPath - modPtr := pkg.NewPyModVar(modName, true).Expr + modPtr := pkg.PyNewModVar(modName, true).Expr mod := b.Load(modPtr) cond := b.BinOp(token.NEQ, mod, prog.Null(mod.Type)) newBlk := p.fn.MakeBlock() b.If(cond, jumpTo, newBlk) b.SetBlock(newBlk) - b.Store(modPtr, b.ImportPyMod(modPath)) + b.Store(modPtr, b.PyImportMod(modPath)) b.Jump(jumpTo) } return ret @@ -831,7 +831,7 @@ func (p *context) compileValue(b llssa.Builder, v ssa.Value) llssa.Expr { } return pyFn.Expr case *ssa.Global: - return p.varOf(v) + return p.varOf(b, v) case *ssa.Const: t := types.Default(v.Type()) return b.Const(v.Value, p.prog.Type(t, llssa.InGo)) diff --git a/cl/import.go b/cl/import.go index 77d029c8..0f57b1c6 100644 --- a/cl/import.go +++ b/cl/import.go @@ -373,12 +373,15 @@ func (p *context) varName(pkg *types.Package, v *ssa.Global) (vName string, vtyp return name, goVar } -func (p *context) varOf(v *ssa.Global) llssa.Expr { +func (p *context) varOf(b llssa.Builder, v *ssa.Global) llssa.Expr { pkgTypes := p.ensureLoaded(v.Pkg.Pkg) pkg := p.pkg name, vtype := p.varName(pkgTypes, v) if vtype == pyVar { - panic("todo") + if kind, mod := pkgKindByScope(pkgTypes.Scope()); kind == PkgPyModule { + return b.PyLoadVar(pysymPrefix+mod, name) + } + panic("unreachable") } ret := pkg.VarOf(name) if ret == nil { diff --git a/ssa/package.go b/ssa/package.go index 11b68901..07cb0fa8 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -594,15 +594,15 @@ func (p Program) tyLoadPyModSyms() *types.Signature { func (p Package) PyInit() bool { if fn := p.FuncOf("main"); fn != nil { b := fn.NewBuilder() - b.SetBlockEx(fn.Block(0), AtStart).CallPyInit() + 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, doInit bool) Global { +// PyNewModVar creates a new global variable for a Python module. +func (p Package) PyNewModVar(name string, doInit bool) Global { if v, ok := p.pymods[name]; ok { return v } @@ -617,18 +617,18 @@ func (p Package) NewPyModVar(name string, doInit bool) Global { return g } -// ImportPyMod imports a Python module. -func (b Builder) ImportPyMod(path string) Expr { +// PyImportMod imports a Python module. +func (b Builder) PyImportMod(path string) Expr { pkg := b.Func.Pkg fnImp := pkg.pyFunc("PyImport_ImportModule", b.Prog.tyImportPyModule()) return b.Call(fnImp, b.CStr(path)) } -// LoadPyModSyms loads python objects from specified module. -func (b Builder) LoadPyModSyms(modName string, objs ...PyObjRef) Expr { +// PyLoadModSyms loads python objects from specified module. +func (b Builder) PyLoadModSyms(modName string, objs ...PyObjRef) Expr { pkg := b.Func.Pkg fnLoad := pkg.pyFunc("llgoLoadPyModSyms", b.Prog.tyLoadPyModSyms()) - modPtr := pkg.NewPyModVar(modName, false).Expr + modPtr := pkg.PyNewModVar(modName, false).Expr mod := b.Load(modPtr) args := make([]Expr, 1, len(objs)*2+2) args[0] = mod @@ -644,6 +644,10 @@ func (b Builder) LoadPyModSyms(modName string, objs ...PyObjRef) Expr { return b.Call(fnLoad, args...) } +func (b Builder) PyLoadVar(modName, name string) Expr { + panic("todo") +} + func (b Builder) pyCall(fn Expr, args []Expr) (ret Expr) { prog := b.Prog pkg := b.Func.Pkg @@ -724,8 +728,8 @@ func (b Builder) PyFloat(fltVal Expr) (ret Expr) { return b.Call(fn, fltVal) } -// CallPyInit calls Py_Initialize. -func (b Builder) CallPyInit() (ret Expr) { +// callPyInit calls Py_Initialize. +func (b Builder) callPyInit() (ret Expr) { fn := b.Func.Pkg.pyFunc("Py_Initialize", NoArgsNoRet) return b.Call(fn) } diff --git a/ssa/ssa_test.go b/ssa/ssa_test.go index be584c08..070344ea 100644 --- a/ssa/ssa_test.go +++ b/ssa/ssa_test.go @@ -147,8 +147,8 @@ func TestPyFunc(t *testing.T) { if pkg.NewPyFunc("a", sig, false) != a { t.Fatal("NewPyFunc(a) failed") } - foo := pkg.NewPyModVar("foo", false) - if pkg.NewPyModVar("foo", false) != foo { + foo := pkg.PyNewModVar("foo", false) + if pkg.PyNewModVar("foo", false) != foo { t.Fatal("NewPyModVar(foo) failed") } }