github.com/goplus/llgo@v0.8.3/ssa/package.go (about) 1 /* 2 * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package ssa 18 19 import ( 20 "go/token" 21 "go/types" 22 23 "github.com/goplus/llvm" 24 "golang.org/x/tools/go/types/typeutil" 25 ) 26 27 const ( 28 PkgPython = "github.com/goplus/llgo/py" 29 PkgRuntime = "github.com/goplus/llgo/internal/runtime" 30 ) 31 32 // ----------------------------------------------------------------------------- 33 34 type dbgFlags = int 35 36 const ( 37 DbgFlagInstruction dbgFlags = 1 << iota 38 39 DbgFlagAll = DbgFlagInstruction 40 ) 41 42 var ( 43 debugInstr bool 44 ) 45 46 // SetDebug sets debug flags. 47 func SetDebug(dbgFlags dbgFlags) { 48 debugInstr = (dbgFlags & DbgFlagInstruction) != 0 49 } 50 51 // ----------------------------------------------------------------------------- 52 53 // InitFlags is a set of flags for initializing the LLVM library. 54 type InitFlags int 55 56 const ( 57 InitNativeTarget InitFlags = 1 << iota 58 InitAllTargets 59 InitAllTargetInfos 60 InitAllTargetMCs 61 62 InitNativeAsmPrinter 63 InitAllAsmPrinters 64 65 InitAllAsmParsers 66 67 InitNative = InitNativeTarget | InitNativeAsmPrinter 68 InitAll = InitAllTargets | InitAllAsmParsers | InitAllAsmPrinters | InitAllTargetInfos | InitAllTargetMCs 69 ) 70 71 // Initialize initializes the LLVM library. 72 func Initialize(flags InitFlags) { 73 if flags&InitAllTargetInfos != 0 { 74 llvm.InitializeAllTargetInfos() 75 } 76 if flags&InitAllTargets != 0 { 77 llvm.InitializeAllTargets() 78 } 79 if flags&InitAllTargetMCs != 0 { 80 llvm.InitializeAllTargetMCs() 81 } 82 if flags&InitAllAsmParsers != 0 { 83 llvm.InitializeAllAsmParsers() 84 } 85 if flags&InitAllAsmPrinters != 0 { 86 llvm.InitializeAllAsmPrinters() 87 } 88 if flags&InitNativeTarget != 0 { 89 llvm.InitializeNativeTarget() 90 } 91 if flags&InitNativeAsmPrinter != 0 { 92 llvm.InitializeNativeAsmPrinter() 93 } 94 } 95 96 // ----------------------------------------------------------------------------- 97 98 type aProgram struct { 99 ctx llvm.Context 100 typs typeutil.Map // rawType -> Type 101 gocvt goTypes 102 103 rt *types.Package 104 rtget func() *types.Package 105 106 py *types.Package 107 pyget func() *types.Package 108 109 target *Target 110 td llvm.TargetData 111 // tm llvm.TargetMachine 112 named map[string]llvm.Type 113 114 intType llvm.Type 115 int1Type llvm.Type 116 int8Type llvm.Type 117 int16Type llvm.Type 118 int32Type llvm.Type 119 int64Type llvm.Type 120 voidType llvm.Type 121 voidPtrTy llvm.Type 122 123 rtStringTy llvm.Type 124 rtIfaceTy llvm.Type 125 rtSliceTy llvm.Type 126 rtMapTy llvm.Type 127 128 anyTy Type 129 voidTy Type 130 voidPtr Type 131 boolTy Type 132 cstrTy Type 133 cintTy Type 134 stringTy Type 135 uintptrTy Type 136 intTy Type 137 uintTy Type 138 f64Ty Type 139 byteTy Type 140 i32Ty Type 141 u32Ty Type 142 i64Ty Type 143 u64Ty Type 144 pyObjPtr Type 145 pyObjPPtr Type 146 147 pyImpTy *types.Signature 148 pyNewList *types.Signature 149 pyListSetI *types.Signature 150 callArgs *types.Signature 151 callNoArgs *types.Signature 152 callOneArg *types.Signature 153 callFOArgs *types.Signature 154 loadPyModS *types.Signature 155 getAttrStr *types.Signature 156 157 paramObjPtr_ *types.Var 158 159 NeedRuntime bool 160 NeedPyInit bool 161 } 162 163 // A Program presents a program. 164 type Program = *aProgram 165 166 // NewProgram creates a new program. 167 func NewProgram(target *Target) Program { 168 if target == nil { 169 target = &Target{} 170 } 171 ctx := llvm.NewContext() 172 td := llvm.NewTargetData("") // TODO(xsw): target config 173 /* 174 arch := target.GOARCH 175 if arch == "" { 176 arch = runtime.GOARCH 177 } 178 sizes := types.SizesFor("gc", arch) 179 180 // TODO(xsw): Finalize may cause panic, so comment it. 181 ctx.Finalize() 182 */ 183 return &aProgram{ctx: ctx, gocvt: newGoTypes(), target: target, td: td, named: make(map[string]llvm.Type)} 184 } 185 186 // SetPython sets the Python package. 187 // Its type can be *types.Package or func() *types.Package. 188 func (p Program) SetPython(py any) { 189 switch v := py.(type) { 190 case *types.Package: 191 p.py = v 192 case func() *types.Package: 193 p.pyget = v 194 } 195 } 196 197 // SetRuntime sets the runtime. 198 // Its type can be *types.Package or func() *types.Package. 199 func (p Program) SetRuntime(runtime any) { 200 switch v := runtime.(type) { 201 case *types.Package: 202 p.rt = v 203 case func() *types.Package: 204 p.rtget = v 205 } 206 } 207 208 func (p Program) runtime() *types.Package { 209 if p.rt == nil { 210 p.rt = p.rtget() 211 } 212 p.NeedRuntime = true 213 return p.rt 214 } 215 216 func (p Program) python() *types.Package { 217 if p.py == nil { 218 p.py = p.pyget() 219 } 220 return p.py 221 } 222 223 func (p Program) rtNamed(name string) *types.Named { 224 t := p.runtime().Scope().Lookup(name).Type().(*types.Named) 225 t, _ = p.gocvt.cvtNamed(t) 226 return t 227 } 228 229 func (p Program) pyNamed(name string) *types.Named { 230 // TODO(xsw): does python type need to convert? 231 t := p.python().Scope().Lookup(name).Type().(*types.Named) 232 return t 233 } 234 235 func (p Program) rtType(name string) Type { 236 return p.rawType(p.rtNamed(name)) 237 } 238 239 func (p Program) rtIface() llvm.Type { 240 if p.rtIfaceTy.IsNil() { 241 p.rtIfaceTy = p.rtType("Interface").ll 242 } 243 return p.rtIfaceTy 244 } 245 246 func (p Program) rtMap() llvm.Type { 247 if p.rtMapTy.IsNil() { 248 p.rtMapTy = p.rtType("Map").ll 249 } 250 return p.rtMapTy 251 } 252 253 func (p Program) rtSlice() llvm.Type { 254 if p.rtSliceTy.IsNil() { 255 p.rtSliceTy = p.rtType("Slice").ll 256 } 257 return p.rtSliceTy 258 } 259 260 func (p Program) rtString() llvm.Type { 261 if p.rtStringTy.IsNil() { 262 p.rtStringTy = p.rtType("String").ll 263 } 264 return p.rtStringTy 265 } 266 267 // NewPackage creates a new package. 268 func (p Program) NewPackage(name, pkgPath string) Package { 269 mod := p.ctx.NewModule(pkgPath) 270 // TODO(xsw): Finalize may cause panic, so comment it. 271 // mod.Finalize() 272 gbls := make(map[string]Global) 273 fns := make(map[string]Function) 274 stubs := make(map[string]Function) 275 pyobjs := make(map[string]PyObjRef) 276 pymods := make(map[string]Global) 277 p.NeedRuntime = false 278 // Don't need reset p.needPyInit here 279 // p.needPyInit = false 280 return &aPackage{mod, gbls, fns, stubs, pyobjs, pymods, p} 281 } 282 283 // PyObjectPtrPtr returns the **py.Object type. 284 func (p Program) PyObjectPtrPtr() Type { 285 if p.pyObjPPtr == nil { 286 p.pyObjPPtr = p.Pointer(p.PyObjectPtr()) 287 } 288 return p.pyObjPPtr 289 } 290 291 // PyObjectPtr returns the *py.Object type. 292 func (p Program) PyObjectPtr() Type { 293 if p.pyObjPtr == nil { 294 objPtr := types.NewPointer(p.pyNamed("Object")) 295 p.pyObjPtr = p.rawType(objPtr) 296 } 297 return p.pyObjPtr 298 } 299 300 // Void returns void type. 301 func (p Program) Void() Type { 302 if p.voidTy == nil { 303 p.voidTy = &aType{p.tyVoid(), rawType{types.Typ[types.Invalid]}, vkInvalid} 304 } 305 return p.voidTy 306 } 307 308 func (p Program) VoidPtr() Type { 309 if p.voidPtr == nil { 310 p.voidPtr = p.rawType(types.Typ[types.UnsafePointer]) 311 } 312 return p.voidPtr 313 } 314 315 // Bool returns bool type. 316 func (p Program) Bool() Type { 317 if p.boolTy == nil { 318 p.boolTy = p.rawType(types.Typ[types.Bool]) 319 } 320 return p.boolTy 321 } 322 323 func (p Program) CStr() Type { 324 if p.cstrTy == nil { // *int8 325 p.cstrTy = p.rawType(types.NewPointer(types.Typ[types.Int8])) 326 } 327 return p.cstrTy 328 } 329 330 func (p Program) String() Type { 331 if p.stringTy == nil { 332 p.stringTy = p.rawType(types.Typ[types.String]) 333 } 334 return p.stringTy 335 } 336 337 // Any returns any type. 338 func (p Program) Any() Type { 339 if p.anyTy == nil { 340 p.anyTy = p.rawType(tyAny) 341 } 342 return p.anyTy 343 } 344 345 func (p Program) CInt() Type { 346 if p.cintTy == nil { // C.int 347 p.cintTy = p.rawType(types.Typ[types.Int32]) // TODO(xsw): support 64-bit 348 } 349 return p.cintTy 350 } 351 352 // Int returns int type. 353 func (p Program) Int() Type { 354 if p.intTy == nil { 355 p.intTy = p.rawType(types.Typ[types.Int]) 356 } 357 return p.intTy 358 } 359 360 // Uint returns uint type. 361 func (p Program) Uint() Type { 362 if p.uintTy == nil { 363 p.uintTy = p.rawType(types.Typ[types.Uint]) 364 } 365 return p.uintTy 366 } 367 368 // Uintptr returns uintptr type. 369 func (p Program) Uintptr() Type { 370 if p.uintptrTy == nil { 371 p.uintptrTy = p.rawType(types.Typ[types.Uintptr]) 372 } 373 return p.uintptrTy 374 } 375 376 // Float64 returns float64 type. 377 func (p Program) Float64() Type { 378 if p.f64Ty == nil { 379 p.f64Ty = p.rawType(types.Typ[types.Float64]) 380 } 381 return p.f64Ty 382 } 383 384 // Byte returns byte type. 385 func (p Program) Byte() Type { 386 if p.byteTy == nil { 387 p.byteTy = p.rawType(types.Typ[types.Byte]) 388 } 389 return p.byteTy 390 } 391 392 // Int32 returns int32 type. 393 func (p Program) Int32() Type { 394 if p.i32Ty == nil { 395 p.i32Ty = p.rawType(types.Typ[types.Int32]) 396 } 397 return p.i32Ty 398 } 399 400 // Uint32 returns uint32 type. 401 func (p Program) Uint32() Type { 402 if p.u32Ty == nil { 403 p.u32Ty = p.rawType(types.Typ[types.Uint32]) 404 } 405 return p.u32Ty 406 } 407 408 // Int64 returns int64 type. 409 func (p Program) Int64() Type { 410 if p.i64Ty == nil { 411 p.i64Ty = p.rawType(types.Typ[types.Int64]) 412 } 413 return p.i64Ty 414 } 415 416 // Uint64 returns uint64 type. 417 func (p Program) Uint64() Type { 418 if p.u64Ty == nil { 419 p.u64Ty = p.rawType(types.Typ[types.Uint64]) 420 } 421 return p.u64Ty 422 } 423 424 // ----------------------------------------------------------------------------- 425 426 // A Package is a single analyzed Go package containing Members for 427 // all package-level functions, variables, constants and types it 428 // declares. These may be accessed directly via Members, or via the 429 // type-specific accessor methods Func, Type, Var and Const. 430 // 431 // Members also contains entries for "init" (the synthetic package 432 // initializer) and "init#%d", the nth declared init function, 433 // and unspecified other things too. 434 type aPackage struct { 435 mod llvm.Module 436 vars map[string]Global 437 fns map[string]Function 438 stubs map[string]Function 439 pyobjs map[string]PyObjRef 440 pymods map[string]Global 441 Prog Program 442 } 443 444 type Package = *aPackage 445 446 /* 447 // NewConst creates a new named constant. 448 func (p Package) NewConst(name string, val constant.Value) NamedConst { 449 return &aNamedConst{} 450 } 451 */ 452 453 func (p Package) rtFunc(fnName string) Expr { 454 fn := p.Prog.runtime().Scope().Lookup(fnName).(*types.Func) 455 name := FullName(fn.Pkg(), fnName) 456 sig := fn.Type().(*types.Signature) 457 return p.NewFunc(name, sig, InGo).Expr 458 } 459 460 func (p Package) pyFunc(fullName string, sig *types.Signature) Expr { 461 p.Prog.NeedPyInit = true 462 return p.NewFunc(fullName, sig, InC).Expr 463 } 464 465 func (p Package) closureStub(b Builder, t *types.Struct, v Expr) Expr { 466 name := v.impl.Name() 467 prog := b.Prog 468 nilVal := prog.Null(prog.VoidPtr()).impl 469 if fn, ok := p.stubs[name]; ok { 470 v = fn.Expr 471 } else { 472 sig := v.raw.Type.(*types.Signature) 473 n := sig.Params().Len() 474 nret := sig.Results().Len() 475 ctx := types.NewParam(token.NoPos, nil, ClosureCtx, types.Typ[types.UnsafePointer]) 476 sig = FuncAddCtx(ctx, sig) 477 fn := p.NewFunc(ClosureStub+name, sig, InC) 478 fn.impl.SetLinkage(llvm.LinkOnceAnyLinkage) 479 args := make([]Expr, n) 480 for i := 0; i < n; i++ { 481 args[i] = fn.Param(i + 1) 482 } 483 b := fn.MakeBody(1) 484 call := b.Call(v, args...) 485 call.impl.SetTailCall(true) 486 switch nret { 487 case 0: 488 b.impl.CreateRetVoid() 489 default: // TODO(xsw): support multiple return values 490 b.impl.CreateRet(call.impl) 491 } 492 p.stubs[name] = fn 493 v = fn.Expr 494 } 495 return b.aggregateValue(prog.rawType(t), v.impl, nilVal) 496 } 497 498 // ----------------------------------------------------------------------------- 499 500 // String returns a string representation of the package. 501 func (p Package) String() string { 502 return p.mod.String() 503 } 504 505 /* 506 type CodeGenFileType = llvm.CodeGenFileType 507 508 const ( 509 AssemblyFile = llvm.AssemblyFile 510 ObjectFile = llvm.ObjectFile 511 ) 512 513 func (p *Package) CodeGen(ft CodeGenFileType) (ret []byte, err error) { 514 buf, err := p.prog.targetMachine().EmitToMemoryBuffer(p.mod, ft) 515 if err != nil { 516 return 517 } 518 ret = buf.Bytes() 519 buf.Dispose() 520 return 521 } 522 523 func (p *Package) Bitcode() []byte { 524 buf := llvm.WriteBitcodeToMemoryBuffer(p.mod) 525 ret := buf.Bytes() 526 buf.Dispose() 527 return ret 528 } 529 530 func (p *Package) WriteTo(w io.Writer) (int64, error) { 531 n, err := w.Write(p.Bitcode()) 532 return int64(n), err 533 } 534 535 func (p *Package) WriteFile(file string) (err error) { 536 f, err := os.Create(file) 537 if err != nil { 538 return 539 } 540 defer f.Close() 541 return llvm.WriteBitcodeToFile(p.mod, f) 542 } 543 */ 544 545 // ----------------------------------------------------------------------------- 546 547 func (p Program) paramObjPtr() *types.Var { 548 if p.paramObjPtr_ == nil { 549 objPtr := p.PyObjectPtr().raw.Type 550 p.paramObjPtr_ = types.NewParam(token.NoPos, nil, "", objPtr) 551 } 552 return p.paramObjPtr_ 553 } 554 555 // func(*char) *Object 556 func (p Program) tyImportPyModule() *types.Signature { 557 if p.pyImpTy == nil { 558 charPtr := types.NewPointer(types.Typ[types.Int8]) 559 params := types.NewTuple(types.NewParam(token.NoPos, nil, "", charPtr)) 560 results := types.NewTuple(p.paramObjPtr()) 561 p.pyImpTy = types.NewSignatureType(nil, nil, nil, params, results, false) 562 } 563 return p.pyImpTy 564 } 565 566 // func(*Object) *Object 567 func (p Program) tyCallNoArgs() *types.Signature { 568 if p.callNoArgs == nil { 569 params := types.NewTuple(p.paramObjPtr()) 570 p.callNoArgs = types.NewSignatureType(nil, nil, nil, params, params, false) 571 } 572 return p.callNoArgs 573 } 574 575 // func(*Object, *Object) *Object 576 func (p Program) tyCallOneArg() *types.Signature { 577 if p.callOneArg == nil { 578 paramObjPtr := p.paramObjPtr() 579 params := types.NewTuple(paramObjPtr, paramObjPtr) 580 results := types.NewTuple(paramObjPtr) 581 p.callOneArg = types.NewSignatureType(nil, nil, nil, params, results, false) 582 } 583 return p.callOneArg 584 } 585 586 // func(*Object, ...) *Object 587 func (p Program) tyCallFunctionObjArgs() *types.Signature { 588 if p.callFOArgs == nil { 589 paramObjPtr := p.paramObjPtr() 590 params := types.NewTuple(paramObjPtr, VArg()) 591 results := types.NewTuple(paramObjPtr) 592 p.callFOArgs = types.NewSignatureType(nil, nil, nil, params, results, true) 593 } 594 return p.callFOArgs 595 } 596 597 /* 598 // func(*Object, *Object, *Object) *Object 599 func (p Program) tyCall() *types.Signature { 600 if p.callArgs == nil { 601 paramObjPtr := p.paramObjPtr() 602 params := types.NewTuple(paramObjPtr, paramObjPtr, paramObjPtr) 603 results := types.NewTuple(paramObjPtr) 604 p.callArgs = types.NewSignatureType(nil, nil, nil, params, results, false) 605 } 606 return p.callArgs 607 } 608 */ 609 610 // func(*Object, uintptr, *Object) cint 611 func (p Program) tyListSetItem() *types.Signature { 612 if p.pyListSetI == nil { 613 paramUintptr := types.NewParam(token.NoPos, nil, "", p.Uintptr().raw.Type) 614 paramCInt := types.NewParam(token.NoPos, nil, "", p.CInt().raw.Type) 615 paramObjPtr := p.paramObjPtr() 616 params := types.NewTuple(paramObjPtr, paramUintptr, paramObjPtr) 617 results := types.NewTuple(paramCInt) 618 p.pyListSetI = types.NewSignatureType(nil, nil, nil, params, results, false) 619 } 620 return p.pyListSetI 621 } 622 623 // func(uintptr) *Object 624 func (p Program) tyNewList() *types.Signature { 625 if p.pyNewList == nil { 626 paramUintptr := types.NewParam(token.NoPos, nil, "", p.Uintptr().raw.Type) 627 params := types.NewTuple(paramUintptr) 628 results := types.NewTuple(p.paramObjPtr()) 629 p.pyNewList = types.NewSignatureType(nil, nil, nil, params, results, false) 630 } 631 return p.pyNewList 632 } 633 634 // func(float64) *Object 635 func (p Program) tyFloatFromDouble() *types.Signature { 636 if p.callArgs == nil { 637 paramObjPtr := p.paramObjPtr() 638 paramFloat := types.NewParam(token.NoPos, nil, "", p.Float64().raw.Type) 639 params := types.NewTuple(paramFloat) 640 results := types.NewTuple(paramObjPtr) 641 p.callArgs = types.NewSignatureType(nil, nil, nil, params, results, false) 642 } 643 return p.callArgs 644 } 645 646 // func(*Object, ...) 647 func (p Program) tyLoadPyModSyms() *types.Signature { 648 if p.loadPyModS == nil { 649 paramObjPtr := p.paramObjPtr() 650 params := types.NewTuple(paramObjPtr, VArg()) 651 p.loadPyModS = types.NewSignatureType(nil, nil, nil, params, nil, true) 652 } 653 return p.loadPyModS 654 } 655 656 // func(*Objecg, *char) *Object 657 func (p Program) tyGetAttrString() *types.Signature { 658 if p.getAttrStr == nil { 659 charPtr := types.NewPointer(types.Typ[types.Int8]) 660 paramObjPtr := p.paramObjPtr() 661 params := types.NewTuple(paramObjPtr, types.NewParam(token.NoPos, nil, "", charPtr)) 662 results := types.NewTuple(paramObjPtr) 663 p.getAttrStr = types.NewSignatureType(nil, nil, nil, params, results, false) 664 } 665 return p.getAttrStr 666 } 667 668 // PyInit initializes Python for a main package. 669 func (p Package) PyInit() bool { 670 if fn := p.FuncOf("main"); fn != nil { 671 b := fn.NewBuilder() 672 b.SetBlockEx(fn.Block(0), AtStart).callPyInit() 673 b.Dispose() 674 return true 675 } 676 return false 677 } 678 679 // PyNewModVar creates a new global variable for a Python module. 680 func (p Package) PyNewModVar(name string, doInit bool) Global { 681 if v, ok := p.pymods[name]; ok { 682 return v 683 } 684 prog := p.Prog 685 objPtr := prog.PyObjectPtrPtr().raw.Type 686 g := p.NewVar(name, objPtr, InC) 687 if doInit { 688 g.Init(prog.Null(g.Type)) 689 g.impl.SetLinkage(llvm.LinkOnceAnyLinkage) 690 } 691 p.pymods[name] = g 692 return g 693 } 694 695 // PyImportMod imports a Python module. 696 func (b Builder) PyImportMod(path string) Expr { 697 pkg := b.Func.Pkg 698 fnImp := pkg.pyFunc("PyImport_ImportModule", b.Prog.tyImportPyModule()) 699 return b.Call(fnImp, b.CStr(path)) 700 } 701 702 // PyLoadModSyms loads python objects from specified module. 703 func (b Builder) PyLoadModSyms(modName string, objs ...PyObjRef) Expr { 704 pkg := b.Func.Pkg 705 fnLoad := pkg.pyFunc("llgoLoadPyModSyms", b.Prog.tyLoadPyModSyms()) 706 modPtr := pkg.PyNewModVar(modName, false).Expr 707 mod := b.Load(modPtr) 708 args := make([]Expr, 1, len(objs)*2+2) 709 args[0] = mod 710 nbase := len(modName) + 1 711 for _, o := range objs { 712 fullName := o.impl.Name() 713 name := fullName[nbase:] 714 args = append(args, b.CStr(name)) 715 args = append(args, o.Expr) 716 } 717 prog := b.Prog 718 args = append(args, prog.Null(prog.CStr())) 719 return b.Call(fnLoad, args...) 720 } 721 722 func (b Builder) pyCall(fn Expr, args []Expr) (ret Expr) { 723 prog := b.Prog 724 pkg := b.Func.Pkg 725 fn = b.Load(fn) 726 sig := fn.raw.Type.(*types.Signature) 727 params := sig.Params() 728 n := params.Len() 729 switch n { 730 case 0: 731 call := pkg.pyFunc("PyObject_CallNoArgs", prog.tyCallNoArgs()) 732 ret = b.Call(call, fn) 733 case 1: 734 if !sig.Variadic() { 735 call := pkg.pyFunc("PyObject_CallOneArg", prog.tyCallOneArg()) 736 return b.Call(call, fn, args[0]) 737 } 738 fallthrough 739 default: 740 call := pkg.pyFunc("PyObject_CallFunctionObjArgs", prog.tyCallFunctionObjArgs()) 741 n = len(args) 742 callargs := make([]Expr, n+2) 743 callargs[0] = fn 744 copy(callargs[1:], args) 745 callargs[n+1] = prog.PyNull() 746 ret = b.Call(call, callargs...) 747 } 748 return 749 } 750 751 // PyNewList(n uintptr) *Object 752 func (b Builder) PyNewList(n Expr) (ret Expr) { 753 prog := b.Prog 754 pkg := b.Func.Pkg 755 fn := pkg.pyFunc("PyList_New", prog.tyNewList()) 756 return b.Call(fn, n) 757 } 758 759 // PyListSetItem(list *Object, index uintptr, item *Object) c.Int 760 func (b Builder) PyListSetItem(list, index, item Expr) (ret Expr) { 761 prog := b.Prog 762 pkg := b.Func.Pkg 763 fn := pkg.pyFunc("PyList_SetItem", prog.tyListSetItem()) 764 return b.Call(fn, list, index, item) 765 } 766 767 // PyList(args ...Expr) *Object 768 func (b Builder) PyList(args ...Expr) (ret Expr) { 769 prog := b.Prog 770 n := len(args) 771 uintPtr := prog.Uintptr() 772 list := b.PyNewList(prog.IntVal(uint64(n), uintPtr)) 773 for i, arg := range args { 774 b.PyListSetItem(list, prog.IntVal(uint64(i), uintPtr), b.PyVal(arg)) 775 } 776 return list 777 } 778 779 // PyVal(v any) *Object 780 func (b Builder) PyVal(v Expr) (ret Expr) { 781 switch t := v.raw.Type.(type) { 782 case *types.Basic: 783 switch t.Kind() { 784 case types.Float64: 785 return b.PyFloat(v) 786 default: 787 panic("PyVal: todo") 788 } 789 default: 790 return v 791 } 792 } 793 794 // PyFloat(fltVal float64) *Object 795 func (b Builder) PyFloat(fltVal Expr) (ret Expr) { 796 prog := b.Prog 797 pkg := b.Func.Pkg 798 fn := pkg.pyFunc("PyFloat_FromDouble", prog.tyFloatFromDouble()) 799 return b.Call(fn, fltVal) 800 } 801 802 // callPyInit calls Py_Initialize. 803 func (b Builder) callPyInit() (ret Expr) { 804 fn := b.Func.Pkg.pyFunc("Py_Initialize", NoArgsNoRet) 805 return b.Call(fn) 806 } 807 808 var ( 809 NoArgsNoRet = types.NewSignatureType(nil, nil, nil, nil, nil, false) 810 ) 811 812 // -----------------------------------------------------------------------------