Merge pull request #716 from aisk/py-tuple-helper

feat(py): Add Python tuple constructor helper
This commit is contained in:
xushiwei
2024-08-15 18:21:51 +08:00
committed by GitHub
7 changed files with 83 additions and 2 deletions

View File

@@ -12,4 +12,8 @@ func main() {
list := py.List(3.0, 9.0, 23.0, 100.0)
y := std.Max(std.Iter(list))
std.Print(y)
tuple := py.Tuple(1.0, 2.0, 3.0)
z := std.Max(std.Iter(tuple))
std.Print(z)
}

View File

@@ -58,6 +58,19 @@ _llgo_0:
%22 = call ptr (ptr, ...) @PyObject_CallFunctionObjArgs(ptr %21, ptr %20, ptr null)
%23 = load ptr, ptr @__llgo_py.builtins.print, align 8
%24 = call ptr (ptr, ...) @PyObject_CallFunctionObjArgs(ptr %23, ptr %22, ptr null)
%25 = call ptr @PyTuple_New(i64 3)
%26 = call ptr @PyFloat_FromDouble(double 1.000000e+00)
%27 = call i32 @PyTuple_SetItem(ptr %25, i64 0, ptr %26)
%28 = call ptr @PyFloat_FromDouble(double 2.000000e+00)
%29 = call i32 @PyTuple_SetItem(ptr %25, i64 1, ptr %28)
%30 = call ptr @PyFloat_FromDouble(double 3.000000e+00)
%31 = call i32 @PyTuple_SetItem(ptr %25, i64 2, ptr %30)
%32 = load ptr, ptr @__llgo_py.builtins.iter, align 8
%33 = call ptr @PyObject_CallOneArg(ptr %32, ptr %25)
%34 = load ptr, ptr @__llgo_py.builtins.max, align 8
%35 = call ptr (ptr, ...) @PyObject_CallFunctionObjArgs(ptr %34, ptr %33, ptr null)
%36 = load ptr, ptr @__llgo_py.builtins.print, align 8
%37 = call ptr (ptr, ...) @PyObject_CallFunctionObjArgs(ptr %36, ptr %35, ptr null)
ret i32 0
}
@@ -75,6 +88,10 @@ declare i32 @PyList_SetItem(ptr, i64, ptr)
declare ptr @PyObject_CallOneArg(ptr, ptr)
declare ptr @PyTuple_New(i64)
declare i32 @PyTuple_SetItem(ptr, i64, ptr)
declare void @llgoLoadPyModSyms(ptr, ...)
declare void @Py_Initialize()

View File

@@ -393,6 +393,7 @@ const (
llgoPyList = llgoInstrBase + 0x10
llgoPyStr = llgoInstrBase + 0x11
llgoPyTuple = llgoInstrBase + 0x12
llgoAtomicLoad = llgoInstrBase + 0x1d
llgoAtomicStore = llgoInstrBase + 0x1e

View File

@@ -216,6 +216,7 @@ var llgoInstrs = map[string]int{
"funcAddr": llgoFuncAddr,
"pystr": llgoPyStr,
"pyList": llgoPyList,
"pyTuple": llgoPyTuple,
"sigjmpbuf": llgoSigjmpbuf,
"sigsetjmp": llgoSigsetjmp,
"siglongjmp": llgoSiglongjmp,
@@ -354,6 +355,9 @@ func (p *context) call(b llssa.Builder, act llssa.DoAction, call *ssa.CallCommon
case llgoPyList:
args := p.compileValues(b, args, fnHasVArg)
ret = b.PyList(args...)
case llgoPyTuple:
args := p.compileValues(b, args, fnHasVArg)
ret = b.PyTuple(args...)
case llgoPyStr:
ret = pystr(b, args)
case llgoCstr:

View File

@@ -22,6 +22,9 @@ import (
// https://docs.python.org/3/c-api/tuple.html
//go:linkname Tuple llgo.pyTuple
func Tuple(__llgo_va_list ...any) *Object
// Return a new tuple object of size len, or nil on failure.
//
//go:linkname NewTuple C.PyTuple_New

View File

@@ -169,6 +169,8 @@ type aProgram struct {
pyImpTy *types.Signature
pyNewList *types.Signature
pyListSetI *types.Signature
pyNewTuple *types.Signature
pyTupleSetI *types.Signature
floatFromDbl *types.Signature
callNoArgs *types.Signature
callOneArg *types.Signature

View File

@@ -162,6 +162,30 @@ func (p Program) tyNewList() *types.Signature {
return p.pyNewList
}
// func(*Object, uintptr, *Object) cint
func (p Program) tyTupleSetItem() *types.Signature {
if p.pyTupleSetI == nil {
paramUintptr := types.NewParam(token.NoPos, nil, "", p.Uintptr().raw.Type)
paramCInt := types.NewParam(token.NoPos, nil, "", p.CInt().raw.Type)
paramObjPtr := p.paramObjPtr()
params := types.NewTuple(paramObjPtr, paramUintptr, paramObjPtr)
results := types.NewTuple(paramCInt)
p.pyTupleSetI = types.NewSignatureType(nil, nil, nil, params, results, false)
}
return p.pyTupleSetI
}
// func(uintptr) *Object
func (p Program) tyNewTuple() *types.Signature {
if p.pyNewTuple == nil {
paramUintptr := types.NewParam(token.NoPos, nil, "", p.Uintptr().raw.Type)
params := types.NewTuple(paramUintptr)
results := types.NewTuple(p.paramObjPtr())
p.pyNewTuple = types.NewSignatureType(nil, nil, nil, params, results, false)
}
return p.pyNewTuple
}
// func(float64) *Object
func (p Program) tyFloatFromDouble() *types.Signature {
if p.floatFromDbl == nil {
@@ -316,6 +340,32 @@ func (b Builder) PyList(args ...Expr) (ret Expr) {
return list
}
// PyNewTuple(n int) *Object
func (b Builder) PyNewTuple(n Expr) (ret Expr) {
prog := b.Prog
fn := b.Pkg.pyFunc("PyTuple_New", prog.tyNewTuple())
return b.Call(fn, n)
}
// PyTupleSetItem(list *Object, index uintptr, item *Object) c.Int
func (b Builder) PyTupleSetItem(list, index, item Expr) (ret Expr) {
prog := b.Prog
fn := b.Pkg.pyFunc("PyTuple_SetItem", prog.tyTupleSetItem())
return b.Call(fn, list, index, item)
}
// PyTuple(args ...Expr) *Object
func (b Builder) PyTuple(args ...Expr) (ret Expr) {
prog := b.Prog
n := len(args)
uintPtr := prog.Uintptr()
list := b.PyNewTuple(prog.IntVal(uint64(n), uintPtr))
for i, arg := range args {
b.PyTupleSetItem(list, prog.IntVal(uint64(i), uintPtr), b.PyVal(arg))
}
return list
}
// PyVal(v any) *Object
func (b Builder) PyVal(v Expr) (ret Expr) {
switch t := v.raw.Type.(type) {