llgo/ssa: PyNewVar; pyLoad
This commit is contained in:
@@ -6,5 +6,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c.Printf(c.Str("pi = %f\n"), math.Pi)
|
c.Printf(c.Str("pi = %f\n"), math.Pi.Float64())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,5 +6,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c.Printf(c.Str("pi = %f\n"), math.Pi)
|
c.Printf(c.Str("pi = %f\n"), math.Pi.Float64())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
; ModuleID = 'main'
|
||||||
|
source_filename = "main"
|
||||||
|
|
||||||
|
@"main.init$guard" = global ptr null
|
||||||
|
@__llgo_argc = global ptr null
|
||||||
|
@__llgo_argv = global ptr null
|
||||||
|
@0 = private unnamed_addr constant [9 x i8] c"pi = %f\0A\00", align 1
|
||||||
|
@__llgo_py.math = external global ptr
|
||||||
|
@1 = private unnamed_addr constant [3 x i8] c"pi\00", align 1
|
||||||
|
|
||||||
|
define void @main.init() {
|
||||||
|
_llgo_0:
|
||||||
|
%0 = load i1, ptr @"main.init$guard", align 1
|
||||||
|
br i1 %0, label %_llgo_2, label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_0
|
||||||
|
store i1 true, ptr @"main.init$guard", align 1
|
||||||
|
call void @"github.com/goplus/llgo/py/math.init"()
|
||||||
|
br label %_llgo_2
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
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"()
|
||||||
|
call void @main.init()
|
||||||
|
%2 = load ptr, ptr @__llgo_py.math, align 8
|
||||||
|
%3 = call ptr @PyObject_GetAttrString(ptr %2, ptr @1)
|
||||||
|
%4 = call double @PyFloat_AsDouble(ptr %3)
|
||||||
|
%5 = call i32 (ptr, ...) @printf(ptr @0, double %4)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/py/math.init"()
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
|
||||||
|
declare ptr @PyObject_GetAttrString(ptr, ptr)
|
||||||
|
|
||||||
|
declare double @PyFloat_AsDouble(ptr)
|
||||||
|
|
||||||
|
declare i32 @printf(ptr, ...)
|
||||||
|
|
||||||
|
declare void @Py_Initialize()
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ func (p *context) funcOf(fn *ssa.Function) (aFn llssa.Function, pyFn llssa.PyObj
|
|||||||
pkg := p.pkg
|
pkg := p.pkg
|
||||||
fnName := pysymPrefix + mod + "." + name
|
fnName := pysymPrefix + mod + "." + name
|
||||||
if pyFn = pkg.PyObjOf(fnName); pyFn == nil {
|
if pyFn = pkg.PyObjOf(fnName); pyFn == nil {
|
||||||
pyFn = pkg.NewPyFunc(fnName, fn.Signature, true)
|
pyFn = pkg.PyNewFunc(fnName, fn.Signature, true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func testCompile(t *testing.T, src, expected string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTestpy(t *testing.T) {
|
func TestFromTestpy(t *testing.T) {
|
||||||
cltest.FromDir(t, "pi", "./_testpy", false)
|
cltest.FromDir(t, "", "./_testpy", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTestlibc(t *testing.T) {
|
func TestFromTestlibc(t *testing.T) {
|
||||||
|
|||||||
@@ -379,7 +379,7 @@ func (p *context) varOf(b llssa.Builder, v *ssa.Global) llssa.Expr {
|
|||||||
name, vtype := p.varName(pkgTypes, v)
|
name, vtype := p.varName(pkgTypes, v)
|
||||||
if vtype == pyVar {
|
if vtype == pyVar {
|
||||||
if kind, mod := pkgKindByScope(pkgTypes.Scope()); kind == PkgPyModule {
|
if kind, mod := pkgKindByScope(pkgTypes.Scope()); kind == PkgPyModule {
|
||||||
return b.PyLoadVar(pysymPrefix+mod, name)
|
return b.PyNewVar(pysymPrefix+mod, name).Expr
|
||||||
}
|
}
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|||||||
27
ssa/decl.go
27
ssa/decl.go
@@ -282,6 +282,29 @@ func (p Function) Block(idx int) BasicBlock {
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type aPyGlobal struct {
|
||||||
|
Expr
|
||||||
|
}
|
||||||
|
|
||||||
|
type PyGlobal = *aPyGlobal
|
||||||
|
|
||||||
|
// PyNewVar creates a Python variable.
|
||||||
|
func (b Builder) PyNewVar(modName, name string) PyGlobal {
|
||||||
|
pkg := b.Func.Pkg
|
||||||
|
modPtr := pkg.PyNewModVar(modName, false).Expr
|
||||||
|
mod := b.Load(modPtr)
|
||||||
|
return &aPyGlobal{pyVarExpr(mod, name)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b Builder) pyLoad(ptr Expr) Expr {
|
||||||
|
pkg := b.Func.Pkg
|
||||||
|
t := ptr.raw.Type.(*pyVarTy)
|
||||||
|
fn := pkg.pyFunc("PyObject_GetAttrString", b.Prog.tyGetAttrString())
|
||||||
|
return b.Call(fn, t.mod, b.CStr(t.name))
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
type aPyObjRef struct {
|
type aPyObjRef struct {
|
||||||
Expr
|
Expr
|
||||||
Obj Global
|
Obj Global
|
||||||
@@ -290,8 +313,8 @@ type aPyObjRef struct {
|
|||||||
// PyObjRef represents a python object reference.
|
// PyObjRef represents a python object reference.
|
||||||
type PyObjRef = *aPyObjRef
|
type PyObjRef = *aPyObjRef
|
||||||
|
|
||||||
// NewPyFunc creates a new python function.
|
// PyNewFunc creates a new python function.
|
||||||
func (p Package) NewPyFunc(name string, sig *types.Signature, doInit bool) PyObjRef {
|
func (p Package) PyNewFunc(name string, sig *types.Signature, doInit bool) PyObjRef {
|
||||||
if v, ok := p.pyobjs[name]; ok {
|
if v, ok := p.pyobjs[name]; ok {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|||||||
26
ssa/expr.go
26
ssa/expr.go
@@ -54,6 +54,26 @@ func (v Expr) Do(b Builder) Expr {
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type pyVarTy struct {
|
||||||
|
mod Expr
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p pyVarTy) Underlying() types.Type {
|
||||||
|
panic("don't call")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p pyVarTy) String() string {
|
||||||
|
return "pyVar"
|
||||||
|
}
|
||||||
|
|
||||||
|
func pyVarExpr(mod Expr, name string) Expr {
|
||||||
|
tvar := &aType{raw: rawType{&pyVarTy{mod, name}}, kind: vkPyVarRef}
|
||||||
|
return Expr{Type: tvar}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
type phisExprTy struct {
|
type phisExprTy struct {
|
||||||
phis []llvm.Value
|
phis []llvm.Value
|
||||||
Type
|
Type
|
||||||
@@ -68,7 +88,8 @@ func (p phisExprTy) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func phisExpr(t Type, phis []llvm.Value) Expr {
|
func phisExpr(t Type, phis []llvm.Value) Expr {
|
||||||
return Expr{Type: &aType{raw: rawType{&phisExprTy{phis, t}}, kind: vkPhisExpr}}
|
tphi := &aType{raw: rawType{&phisExprTy{phis, t}}, kind: vkPhisExpr}
|
||||||
|
return Expr{Type: tphi}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@@ -513,6 +534,9 @@ func (b Builder) Load(ptr Expr) Expr {
|
|||||||
if debugInstr {
|
if debugInstr {
|
||||||
log.Printf("Load %v\n", ptr.impl)
|
log.Printf("Load %v\n", ptr.impl)
|
||||||
}
|
}
|
||||||
|
if ptr.kind == vkPyVarRef {
|
||||||
|
return b.pyLoad(ptr)
|
||||||
|
}
|
||||||
telem := b.Prog.Elem(ptr.Type)
|
telem := b.Prog.Elem(ptr.Type)
|
||||||
return Expr{llvm.CreateLoad(b.impl, telem.ll, ptr.impl), telem}
|
return Expr{llvm.CreateLoad(b.impl, telem.ll, ptr.impl), telem}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ type aProgram struct {
|
|||||||
callOneArg *types.Signature
|
callOneArg *types.Signature
|
||||||
callFOArgs *types.Signature
|
callFOArgs *types.Signature
|
||||||
loadPyModS *types.Signature
|
loadPyModS *types.Signature
|
||||||
|
getAttrStr *types.Signature
|
||||||
|
|
||||||
paramObjPtr_ *types.Var
|
paramObjPtr_ *types.Var
|
||||||
|
|
||||||
@@ -497,6 +498,7 @@ func (p Program) paramObjPtr() *types.Var {
|
|||||||
return p.paramObjPtr_
|
return p.paramObjPtr_
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func(*char) *Object
|
||||||
func (p Program) tyImportPyModule() *types.Signature {
|
func (p Program) tyImportPyModule() *types.Signature {
|
||||||
if p.pyImpTy == nil {
|
if p.pyImpTy == nil {
|
||||||
charPtr := types.NewPointer(types.Typ[types.Int8])
|
charPtr := types.NewPointer(types.Typ[types.Int8])
|
||||||
@@ -507,6 +509,7 @@ func (p Program) tyImportPyModule() *types.Signature {
|
|||||||
return p.pyImpTy
|
return p.pyImpTy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func(*Object) *Object
|
||||||
func (p Program) tyCallNoArgs() *types.Signature {
|
func (p Program) tyCallNoArgs() *types.Signature {
|
||||||
if p.callNoArgs == nil {
|
if p.callNoArgs == nil {
|
||||||
params := types.NewTuple(p.paramObjPtr())
|
params := types.NewTuple(p.paramObjPtr())
|
||||||
@@ -515,6 +518,7 @@ func (p Program) tyCallNoArgs() *types.Signature {
|
|||||||
return p.callNoArgs
|
return p.callNoArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func(*Object, *Object) *Object
|
||||||
func (p Program) tyCallOneArg() *types.Signature {
|
func (p Program) tyCallOneArg() *types.Signature {
|
||||||
if p.callOneArg == nil {
|
if p.callOneArg == nil {
|
||||||
paramObjPtr := p.paramObjPtr()
|
paramObjPtr := p.paramObjPtr()
|
||||||
@@ -525,6 +529,7 @@ func (p Program) tyCallOneArg() *types.Signature {
|
|||||||
return p.callOneArg
|
return p.callOneArg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func(*Object, ...) *Object
|
||||||
func (p Program) tyCallFunctionObjArgs() *types.Signature {
|
func (p Program) tyCallFunctionObjArgs() *types.Signature {
|
||||||
if p.callFOArgs == nil {
|
if p.callFOArgs == nil {
|
||||||
paramObjPtr := p.paramObjPtr()
|
paramObjPtr := p.paramObjPtr()
|
||||||
@@ -536,6 +541,7 @@ func (p Program) tyCallFunctionObjArgs() *types.Signature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
// func(*Object, *Object, *Object) *Object
|
||||||
func (p Program) tyCall() *types.Signature {
|
func (p Program) tyCall() *types.Signature {
|
||||||
if p.callArgs == nil {
|
if p.callArgs == nil {
|
||||||
paramObjPtr := p.paramObjPtr()
|
paramObjPtr := p.paramObjPtr()
|
||||||
@@ -547,6 +553,7 @@ func (p Program) tyCall() *types.Signature {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// func(*Object, uintptr, *Object) cint
|
||||||
func (p Program) tyListSetItem() *types.Signature {
|
func (p Program) tyListSetItem() *types.Signature {
|
||||||
if p.pyListSetI == nil {
|
if p.pyListSetI == nil {
|
||||||
paramUintptr := types.NewParam(token.NoPos, nil, "", p.Uintptr().raw.Type)
|
paramUintptr := types.NewParam(token.NoPos, nil, "", p.Uintptr().raw.Type)
|
||||||
@@ -559,6 +566,7 @@ func (p Program) tyListSetItem() *types.Signature {
|
|||||||
return p.pyListSetI
|
return p.pyListSetI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func(uintptr) *Object
|
||||||
func (p Program) tyNewList() *types.Signature {
|
func (p Program) tyNewList() *types.Signature {
|
||||||
if p.pyNewList == nil {
|
if p.pyNewList == nil {
|
||||||
paramUintptr := types.NewParam(token.NoPos, nil, "", p.Uintptr().raw.Type)
|
paramUintptr := types.NewParam(token.NoPos, nil, "", p.Uintptr().raw.Type)
|
||||||
@@ -569,6 +577,7 @@ func (p Program) tyNewList() *types.Signature {
|
|||||||
return p.pyNewList
|
return p.pyNewList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func(float64) *Object
|
||||||
func (p Program) tyFloatFromDouble() *types.Signature {
|
func (p Program) tyFloatFromDouble() *types.Signature {
|
||||||
if p.callArgs == nil {
|
if p.callArgs == nil {
|
||||||
paramObjPtr := p.paramObjPtr()
|
paramObjPtr := p.paramObjPtr()
|
||||||
@@ -580,16 +589,28 @@ func (p Program) tyFloatFromDouble() *types.Signature {
|
|||||||
return p.callArgs
|
return p.callArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func(*Object, ...)
|
||||||
func (p Program) tyLoadPyModSyms() *types.Signature {
|
func (p Program) tyLoadPyModSyms() *types.Signature {
|
||||||
if p.loadPyModS == nil {
|
if p.loadPyModS == nil {
|
||||||
objPtr := p.PyObjectPtr().raw.Type
|
paramObjPtr := p.paramObjPtr()
|
||||||
paramObjPtr := types.NewParam(token.NoPos, nil, "mod", objPtr)
|
|
||||||
params := types.NewTuple(paramObjPtr, VArg())
|
params := types.NewTuple(paramObjPtr, VArg())
|
||||||
p.loadPyModS = types.NewSignatureType(nil, nil, nil, params, nil, true)
|
p.loadPyModS = types.NewSignatureType(nil, nil, nil, params, nil, true)
|
||||||
}
|
}
|
||||||
return p.loadPyModS
|
return p.loadPyModS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func(*Objecg, *char) *Object
|
||||||
|
func (p Program) tyGetAttrString() *types.Signature {
|
||||||
|
if p.getAttrStr == nil {
|
||||||
|
charPtr := types.NewPointer(types.Typ[types.Int8])
|
||||||
|
paramObjPtr := p.paramObjPtr()
|
||||||
|
params := types.NewTuple(paramObjPtr, types.NewParam(token.NoPos, nil, "", charPtr))
|
||||||
|
results := types.NewTuple(paramObjPtr)
|
||||||
|
p.getAttrStr = types.NewSignatureType(nil, nil, nil, params, results, false)
|
||||||
|
}
|
||||||
|
return p.getAttrStr
|
||||||
|
}
|
||||||
|
|
||||||
// PyInit initializes Python for a main package.
|
// PyInit initializes Python for a main package.
|
||||||
func (p Package) PyInit() bool {
|
func (p Package) PyInit() bool {
|
||||||
if fn := p.FuncOf("main"); fn != nil {
|
if fn := p.FuncOf("main"); fn != nil {
|
||||||
@@ -644,10 +665,6 @@ func (b Builder) PyLoadModSyms(modName string, objs ...PyObjRef) Expr {
|
|||||||
return b.Call(fnLoad, args...)
|
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) {
|
func (b Builder) pyCall(fn Expr, args []Expr) (ret Expr) {
|
||||||
prog := b.Prog
|
prog := b.Prog
|
||||||
pkg := b.Func.Pkg
|
pkg := b.Func.Pkg
|
||||||
|
|||||||
@@ -143,8 +143,8 @@ func TestPyFunc(t *testing.T) {
|
|||||||
prog.SetPython(py)
|
prog.SetPython(py)
|
||||||
pkg := prog.NewPackage("bar", "foo/bar")
|
pkg := prog.NewPackage("bar", "foo/bar")
|
||||||
sig := types.NewSignatureType(nil, nil, nil, nil, nil, false)
|
sig := types.NewSignatureType(nil, nil, nil, nil, nil, false)
|
||||||
a := pkg.NewPyFunc("a", sig, false)
|
a := pkg.PyNewFunc("a", sig, false)
|
||||||
if pkg.NewPyFunc("a", sig, false) != a {
|
if pkg.PyNewFunc("a", sig, false) != a {
|
||||||
t.Fatal("NewPyFunc(a) failed")
|
t.Fatal("NewPyFunc(a) failed")
|
||||||
}
|
}
|
||||||
foo := pkg.PyNewModVar("foo", false)
|
foo := pkg.PyNewModVar("foo", false)
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ const (
|
|||||||
vkFuncPtr
|
vkFuncPtr
|
||||||
vkClosure
|
vkClosure
|
||||||
vkPyFuncRef
|
vkPyFuncRef
|
||||||
|
vkPyVarRef
|
||||||
vkTuple
|
vkTuple
|
||||||
vkSlice
|
vkSlice
|
||||||
vkPhisExpr = -1
|
vkPhisExpr = -1
|
||||||
|
|||||||
Reference in New Issue
Block a user