llgo/ssa: PyNewVar; pyLoad

This commit is contained in:
xushiwei
2024-05-15 18:32:50 +08:00
parent 91513a12b4
commit 29e4af4fb2
11 changed files with 130 additions and 16 deletions

View File

@@ -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 {
Expr
Obj Global
@@ -290,8 +313,8 @@ type aPyObjRef struct {
// 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) PyObjRef {
// PyNewFunc creates a new python function.
func (p Package) PyNewFunc(name string, sig *types.Signature, doInit bool) PyObjRef {
if v, ok := p.pyobjs[name]; ok {
return v
}

View File

@@ -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 {
phis []llvm.Value
Type
@@ -68,7 +88,8 @@ func (p phisExprTy) String() string {
}
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 {
log.Printf("Load %v\n", ptr.impl)
}
if ptr.kind == vkPyVarRef {
return b.pyLoad(ptr)
}
telem := b.Prog.Elem(ptr.Type)
return Expr{llvm.CreateLoad(b.impl, telem.ll, ptr.impl), telem}
}

View File

@@ -146,6 +146,7 @@ type aProgram struct {
callOneArg *types.Signature
callFOArgs *types.Signature
loadPyModS *types.Signature
getAttrStr *types.Signature
paramObjPtr_ *types.Var
@@ -497,6 +498,7 @@ func (p Program) paramObjPtr() *types.Var {
return p.paramObjPtr_
}
// func(*char) *Object
func (p Program) tyImportPyModule() *types.Signature {
if p.pyImpTy == nil {
charPtr := types.NewPointer(types.Typ[types.Int8])
@@ -507,6 +509,7 @@ func (p Program) tyImportPyModule() *types.Signature {
return p.pyImpTy
}
// func(*Object) *Object
func (p Program) tyCallNoArgs() *types.Signature {
if p.callNoArgs == nil {
params := types.NewTuple(p.paramObjPtr())
@@ -515,6 +518,7 @@ func (p Program) tyCallNoArgs() *types.Signature {
return p.callNoArgs
}
// func(*Object, *Object) *Object
func (p Program) tyCallOneArg() *types.Signature {
if p.callOneArg == nil {
paramObjPtr := p.paramObjPtr()
@@ -525,6 +529,7 @@ func (p Program) tyCallOneArg() *types.Signature {
return p.callOneArg
}
// func(*Object, ...) *Object
func (p Program) tyCallFunctionObjArgs() *types.Signature {
if p.callFOArgs == nil {
paramObjPtr := p.paramObjPtr()
@@ -536,6 +541,7 @@ func (p Program) tyCallFunctionObjArgs() *types.Signature {
}
/*
// func(*Object, *Object, *Object) *Object
func (p Program) tyCall() *types.Signature {
if p.callArgs == nil {
paramObjPtr := p.paramObjPtr()
@@ -547,6 +553,7 @@ func (p Program) tyCall() *types.Signature {
}
*/
// func(*Object, uintptr, *Object) cint
func (p Program) tyListSetItem() *types.Signature {
if p.pyListSetI == nil {
paramUintptr := types.NewParam(token.NoPos, nil, "", p.Uintptr().raw.Type)
@@ -559,6 +566,7 @@ func (p Program) tyListSetItem() *types.Signature {
return p.pyListSetI
}
// func(uintptr) *Object
func (p Program) tyNewList() *types.Signature {
if p.pyNewList == nil {
paramUintptr := types.NewParam(token.NoPos, nil, "", p.Uintptr().raw.Type)
@@ -569,6 +577,7 @@ func (p Program) tyNewList() *types.Signature {
return p.pyNewList
}
// func(float64) *Object
func (p Program) tyFloatFromDouble() *types.Signature {
if p.callArgs == nil {
paramObjPtr := p.paramObjPtr()
@@ -580,16 +589,28 @@ func (p Program) tyFloatFromDouble() *types.Signature {
return p.callArgs
}
// func(*Object, ...)
func (p Program) tyLoadPyModSyms() *types.Signature {
if p.loadPyModS == nil {
objPtr := p.PyObjectPtr().raw.Type
paramObjPtr := types.NewParam(token.NoPos, nil, "mod", objPtr)
paramObjPtr := p.paramObjPtr()
params := types.NewTuple(paramObjPtr, VArg())
p.loadPyModS = types.NewSignatureType(nil, nil, nil, params, nil, true)
}
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.
func (p Package) PyInit() bool {
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...)
}
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

View File

@@ -143,8 +143,8 @@ func TestPyFunc(t *testing.T) {
prog.SetPython(py)
pkg := prog.NewPackage("bar", "foo/bar")
sig := types.NewSignatureType(nil, nil, nil, nil, nil, false)
a := pkg.NewPyFunc("a", sig, false)
if pkg.NewPyFunc("a", sig, false) != a {
a := pkg.PyNewFunc("a", sig, false)
if pkg.PyNewFunc("a", sig, false) != a {
t.Fatal("NewPyFunc(a) failed")
}
foo := pkg.PyNewModVar("foo", false)

View File

@@ -44,6 +44,7 @@ const (
vkFuncPtr
vkClosure
vkPyFuncRef
vkPyVarRef
vkTuple
vkSlice
vkPhisExpr = -1