runtime: rethrow/panic; llgo/ssa: DeferData; Null => Nil

This commit is contained in:
xushiwei
2024-06-12 17:26:07 +08:00
parent 60dd33b48f
commit b787de0163
11 changed files with 176 additions and 71 deletions

View File

@@ -201,7 +201,7 @@ func (p *context) compileGlobal(pkg llssa.Package, gbl *ssa.Global) {
} }
g := pkg.NewVar(name, typ, llssa.Background(vtype)) g := pkg.NewVar(name, typ, llssa.Background(vtype))
if vtype == goVar { if vtype == goVar {
g.Init(p.prog.Null(g.Type)) g.Init(p.prog.Nil(g.Type))
} }
} }
@@ -338,6 +338,8 @@ func (p *context) funcOf(fn *ssa.Function) (aFn llssa.Function, pyFn llssa.PyObj
ftype = llgoSigsetjmp ftype = llgoSigsetjmp
case "siglongjmp": case "siglongjmp":
ftype = llgoSiglongjmp ftype = llgoSiglongjmp
case "deferData":
ftype = llgoDeferData
case "unreachable": case "unreachable":
ftype = llgoUnreachable ftype = llgoUnreachable
default: default:
@@ -378,8 +380,8 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do
fn := p.fn fn := p.fn
argc := pkg.NewVar("__llgo_argc", types.NewPointer(types.Typ[types.Int32]), llssa.InC) argc := pkg.NewVar("__llgo_argc", types.NewPointer(types.Typ[types.Int32]), llssa.InC)
argv := pkg.NewVar("__llgo_argv", types.NewPointer(argvTy), llssa.InC) argv := pkg.NewVar("__llgo_argv", types.NewPointer(argvTy), llssa.InC)
argc.Init(prog.Null(argc.Type)) argc.Init(prog.Nil(argc.Type))
argv.Init(prog.Null(argv.Type)) argv.Init(prog.Nil(argv.Type))
b.Store(argc.Expr, fn.Param(0)) b.Store(argc.Expr, fn.Param(0))
b.Store(argv.Expr, fn.Param(1)) b.Store(argv.Expr, fn.Param(1))
callRuntimeInit(b, pkg) callRuntimeInit(b, pkg)
@@ -395,7 +397,7 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do
modName := pysymPrefix + modPath modName := pysymPrefix + modPath
modPtr := pkg.PyNewModVar(modName, true).Expr modPtr := pkg.PyNewModVar(modName, true).Expr
mod := b.Load(modPtr) mod := b.Load(modPtr)
cond := b.BinOp(token.NEQ, mod, prog.Null(mod.Type)) cond := b.BinOp(token.NEQ, mod, prog.Nil(mod.Type))
newBlk := p.fn.MakeBlock() newBlk := p.fn.MakeBlock()
b.If(cond, jumpTo, newBlk) b.If(cond, jumpTo, newBlk)
b.SetBlockEx(newBlk, llssa.AtEnd, false) b.SetBlockEx(newBlk, llssa.AtEnd, false)
@@ -431,8 +433,11 @@ func intVal(v ssa.Value) int64 {
} }
func (p *context) isVArgs(vx ssa.Value) (ret []llssa.Expr, ok bool) { func (p *context) isVArgs(vx ssa.Value) (ret []llssa.Expr, ok bool) {
if va, vok := vx.(*ssa.Alloc); vok { switch vx := vx.(type) {
ret, ok = p.vargs[va] // varargs: this is a varargs index case *ssa.Alloc:
ret, ok = p.vargs[vx] // varargs: this is a varargs index
case *ssa.Const:
ok = vx.Value == nil
} }
return return
} }
@@ -642,6 +647,8 @@ func (p *context) call(b llssa.Builder, act llssa.DoAction, call *ssa.CallCommon
p.siglongjmp(b, args) p.siglongjmp(b, args)
case llgoSigjmpbuf: // func sigjmpbuf() case llgoSigjmpbuf: // func sigjmpbuf()
ret = b.AllocaSigjmpBuf() ret = b.AllocaSigjmpBuf()
case llgoDeferData: // func deferData() *Defer
ret = b.DeferData()
case llgoUnreachable: // func unreachable() case llgoUnreachable: // func unreachable()
b.Unreachable() b.Unreachable()
default: default:

View File

@@ -312,6 +312,7 @@ const (
llgoSigjmpbuf = llgoInstrBase + 10 llgoSigjmpbuf = llgoInstrBase + 10
llgoSigsetjmp = llgoInstrBase + 11 llgoSigsetjmp = llgoInstrBase + 11
llgoSiglongjmp = llgoInstrBase + 12 llgoSiglongjmp = llgoInstrBase + 12
llgoDeferData = llgoInstrBase + 13
) )
func (p *context) funcName(fn *ssa.Function, ignore bool) (*types.Package, string, int) { func (p *context) funcName(fn *ssa.Function, ignore bool) (*types.Package, string, int) {

View File

@@ -42,15 +42,30 @@ func Alloca(size uintptr) Pointer
//go:linkname AllocaCStr llgo.allocaCStr //go:linkname AllocaCStr llgo.allocaCStr
func AllocaCStr(s string) *Char func AllocaCStr(s string) *Char
//go:linkname GoDeferData llgo.deferData
func GoDeferData() Pointer
//go:linkname Unreachable llgo.unreachable //go:linkname Unreachable llgo.unreachable
func Unreachable() func Unreachable()
//go:linkname AllocaSigjmpBuf llgo.sigjmpbuf
func AllocaSigjmpBuf() Pointer
//go:linkname Sigsetjmp llgo.sigsetjmp
func Sigsetjmp(jb Pointer, savemask Int) Int
//go:linkname Siglongjmp llgo.siglongjmp
func Siglongjmp(jb Pointer, retval Int)
//go:linkname Rand C.rand //go:linkname Rand C.rand
func Rand() Int func Rand() Int
//go:linkname Malloc C.malloc //go:linkname Malloc C.malloc
func Malloc(size uintptr) Pointer func Malloc(size uintptr) Pointer
//go:linkname Free C.free
func Free(ptr Pointer)
//go:linkname Memcpy C.memcpy //go:linkname Memcpy C.memcpy
func Memcpy(dst, src Pointer, n uintptr) Pointer func Memcpy(dst, src Pointer, n uintptr) Pointer

View File

@@ -19,6 +19,7 @@ package runtime
import ( import (
"unsafe" "unsafe"
"github.com/goplus/llgo/c/pthread"
"github.com/goplus/llgo/internal/abi" "github.com/goplus/llgo/internal/abi"
"github.com/goplus/llgo/internal/runtime/c" "github.com/goplus/llgo/internal/runtime/c"
) )
@@ -27,19 +28,43 @@ import (
// Defer presents defer statements in a function. // Defer presents defer statements in a function.
type Defer struct { type Defer struct {
Addr unsafe.Pointer Addr unsafe.Pointer // sigjmpbuf
Bits uintptr Bits uintptr
Link *Defer Link *Defer
Rund int // index of RunDefers Rund int // index of RunDefers
} }
// ----------------------------------------------------------------------------- // Panic panics with a value.
func Panic(v Eface) {
ptr := c.Malloc(unsafe.Sizeof(v))
*(*Eface)(ptr) = v
excepKey.Set(ptr)
// Zeroinit initializes memory to zero. Rethrow((*Defer)(c.GoDeferData()))
func Zeroinit(p unsafe.Pointer, size uintptr) unsafe.Pointer {
return c.Memset(p, 0, size)
} }
// Rethrow rethrows a panic.
func Rethrow(link *Defer) {
if link == nil {
ptr := excepKey.Get()
TracePanic(*(*Eface)(ptr))
c.Free(ptr)
c.Unreachable()
} else {
c.Siglongjmp(link.Addr, 1)
}
}
var (
excepKey pthread.Key
)
func init() {
excepKey.Create(nil)
}
// -----------------------------------------------------------------------------
// TracePanic prints panic message. // TracePanic prints panic message.
func TracePanic(v Eface) { func TracePanic(v Eface) {
kind := v._type.Kind() kind := v._type.Kind()
@@ -56,3 +81,10 @@ func stringTracef(fp c.FilePtr, format *c.Char, s String) {
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Zeroinit initializes memory to zero.
func Zeroinit(p unsafe.Pointer, size uintptr) unsafe.Pointer {
return c.Memset(p, 0, size)
}
// -----------------------------------------------------------------------------

View File

@@ -303,7 +303,7 @@ func (p Package) abiTypeInit(g Global, t types.Type, pub bool) {
var eq Expr var eq Expr
var blks []BasicBlock var blks []BasicBlock
if pub { if pub {
eq = b.BinOp(token.EQL, b.Load(expr), b.Prog.Null(expr.Type)) eq = b.BinOp(token.EQL, b.Load(expr), b.Prog.Nil(expr.Type))
blks = b.Func.MakeBlocks(2) blks = b.Func.MakeBlocks(2)
b.If(eq, blks[0], blks[1]) b.If(eq, blks[0], blks[1])
b.SetBlockEx(blks[0], AtEnd, false) b.SetBlockEx(blks[0], AtEnd, false)
@@ -343,7 +343,7 @@ func (b Builder) abiType(t types.Type) Expr {
if g == nil { if g == nil {
prog := b.Prog prog := b.Prog
g = pkg.doNewVar(name, prog.AbiTypePtrPtr()) g = pkg.doNewVar(name, prog.AbiTypePtrPtr())
g.Init(prog.Null(g.Type)) g.Init(prog.Nil(g.Type))
if pub { if pub {
g.impl.SetLinkage(llvm.LinkOnceAnyLinkage) g.impl.SetLinkage(llvm.LinkOnceAnyLinkage)
} }

View File

@@ -22,7 +22,6 @@ import "C"
import ( import (
"go/token" "go/token"
"go/types" "go/types"
"log"
"unsafe" "unsafe"
"github.com/goplus/llvm" "github.com/goplus/llvm"
@@ -77,6 +76,7 @@ func (b Builder) Siglongjmp(jb, retval Expr) {
const ( const (
deferKey = "__llgo_defer" deferKey = "__llgo_defer"
excepKey = "__llgo_ex"
) )
func (p Function) deferInitBuilder() (b Builder, next BasicBlock) { func (p Function) deferInitBuilder() (b Builder, next BasicBlock) {
@@ -96,29 +96,33 @@ type aDefer struct {
stmts []func(bits Expr) stmts []func(bits Expr)
} }
func (p Package) deferInit() { func (p Package) keyInit(name string) {
keyVar := p.VarOf(deferKey) keyVar := p.VarOf(name)
if keyVar == nil { if keyVar == nil {
return return
} }
prog := p.Prog prog := p.Prog
keyNil := prog.Null(prog.DeferPtrPtr()) keyNil := prog.Nil(prog.CIntPtr())
keyVar.Init(keyNil) keyVar.Init(keyNil)
keyVar.impl.SetLinkage(llvm.LinkOnceAnyLinkage) keyVar.impl.SetLinkage(llvm.LinkOnceAnyLinkage)
b := p.afterBuilder() b := p.afterBuilder()
eq := b.BinOp(token.EQL, b.Load(keyVar.Expr), keyNil) eq := b.BinOp(token.EQL, b.Load(keyVar.Expr), prog.IntVal(0, prog.CInt()))
b.IfThen(eq, func() { b.IfThen(eq, func() {
b.pthreadKeyCreate(keyVar.Expr, prog.Null(prog.VoidPtr())) b.pthreadKeyCreate(keyVar.Expr, prog.Nil(prog.VoidPtr()))
}) })
} }
func (p Package) newDeferKey() Global { func (p Package) newKey(name string) Global {
return p.NewVarEx(deferKey, p.Prog.DeferPtrPtr()) return p.NewVarEx(name, p.Prog.CIntPtr())
} }
func (b Builder) deferKey() Expr { func (b Builder) deferKey() Expr {
return b.Load(b.Pkg.newDeferKey().Expr) return b.Load(b.Pkg.newKey(deferKey).Expr)
}
func (b Builder) excepKey() Expr {
return b.Load(b.Pkg.newKey(excepKey).Expr)
} }
func (b Builder) getDefer(kind DoAction) *aDefer { func (b Builder) getDefer(kind DoAction) *aDefer {
@@ -148,7 +152,7 @@ func (b Builder) getDefer(kind DoAction) *aDefer {
deferData := Expr{ptr, prog.DeferPtr()} deferData := Expr{ptr, prog.DeferPtr()}
b.pthreadSetspecific(key, deferData) b.pthreadSetspecific(key, deferData)
blks := self.MakeBlocks(2) blks := self.MakeBlocks(2)
procBlk, throwBlk := blks[0], blks[1] procBlk, rethrowBlk := blks[0], blks[1]
bitsPtr := b.FieldAddr(deferData, deferBits) bitsPtr := b.FieldAddr(deferData, deferBits)
rundPtr := b.FieldAddr(deferData, deferRund) rundPtr := b.FieldAddr(deferData, deferRund)
self.defer_ = &aDefer{ self.defer_ = &aDefer{
@@ -157,7 +161,7 @@ func (b Builder) getDefer(kind DoAction) *aDefer {
bitsPtr: bitsPtr, bitsPtr: bitsPtr,
rundPtr: rundPtr, rundPtr: rundPtr,
procBlk: procBlk, procBlk: procBlk,
runsNext: []BasicBlock{throwBlk}, runsNext: []BasicBlock{rethrowBlk},
} }
czero := prog.IntVal(0, prog.CInt()) czero := prog.IntVal(0, prog.CInt())
retval := b.Sigsetjmp(jb, czero) retval := b.Sigsetjmp(jb, czero)
@@ -168,12 +172,14 @@ func (b Builder) getDefer(kind DoAction) *aDefer {
next, rundBlk = blks[0], blks[1] next, rundBlk = blks[0], blks[1]
} }
b.If(b.BinOp(token.EQL, retval, czero), next, rundBlk) b.If(b.BinOp(token.EQL, retval, czero), next, rundBlk)
b.SetBlockEx(rundBlk, AtEnd, false) // exec runDefers and throw b.SetBlockEx(rundBlk, AtEnd, false) // exec runDefers and rethrow
b.Store(rundPtr, prog.Val(0)) b.Store(rundPtr, prog.Val(0))
b.Jump(procBlk) b.Jump(procBlk)
b.SetBlockEx(throwBlk, AtEnd, false) // throw
linkJBPtr := b.FieldAddr(link, deferSigjmpbuf) b.SetBlockEx(rethrowBlk, AtEnd, false) // rethrow
b.Siglongjmp(b.Load(linkJBPtr), prog.IntVal(1, prog.CInt())) b.Call(b.Pkg.rtFunc("Rethrow"), b.Load(link))
b.Unreachable() // TODO: func supports noreturn attribute
if kind == DeferAlways { if kind == DeferAlways {
b.SetBlockEx(next, AtEnd, false) b.SetBlockEx(next, AtEnd, false)
b.blk.last = next.last b.blk.last = next.last
@@ -182,6 +188,12 @@ func (b Builder) getDefer(kind DoAction) *aDefer {
return self.defer_ return self.defer_
} }
// DeferData returns the defer data (*runtime.Defer).
func (b Builder) DeferData() Expr {
key := b.deferKey()
return Expr{b.pthreadGetspecific(key).impl, b.Prog.DeferPtr()}
}
// Defer emits a defer instruction. // Defer emits a defer instruction.
func (b Builder) Defer(kind DoAction, fn Expr, args ...Expr) { func (b Builder) Defer(kind DoAction, fn Expr, args ...Expr) {
if debugInstr { if debugInstr {
@@ -249,13 +261,16 @@ func (p Function) endDefer(b Builder) {
link := b.getField(b.Load(self.data), 2) link := b.getField(b.Load(self.data), 2)
b.pthreadSetspecific(self.key, link) b.pthreadSetspecific(self.key, link)
// rund := b.Load(self.rundPtr)
b.IndirectJump(self.rundPtr, nexts) b.IndirectJump(self.rundPtr, nexts)
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Unreachable emits an unreachable instruction.
func (b Builder) Unreachable() {
b.impl.CreateUnreachable()
}
/* /*
// Recover emits a recover instruction. // Recover emits a recover instruction.
func (b Builder) Recover() (v Expr) { func (b Builder) Recover() (v Expr) {
@@ -263,22 +278,34 @@ func (b Builder) Recover() (v Expr) {
log.Println("Recover") log.Println("Recover")
} }
prog := b.Prog prog := b.Prog
return prog.Zero(prog.Eface()) return prog.Zero(prog.Any())
} }
*/ */
// Panic emits a panic instruction. // Panic emits a panic instruction.
func (b Builder) Panic(v Expr) { func (b Builder) Panic(v Expr) {
b.Call(b.Pkg.rtFunc("Panic"), v)
b.Unreachable() // TODO: func supports noreturn attribute
}
/*
// Panic emits a panic instruction.
func (b Builder) Panic(v Expr) {
vimpl := v.impl
if debugInstr { if debugInstr {
log.Printf("Panic %v\n", v.impl) log.Printf("Panic %v\n", vimpl)
} }
if v.kind != vkEface {
panic("Panic only accepts an any expression")
}
ptr := b.dupMalloc(v)
b.pthreadSetspecific(b.excepKey(), ptr)
}
func (b Builder) doPanic(v Expr) {
b.Call(b.Pkg.rtFunc("TracePanic"), v) b.Call(b.Pkg.rtFunc("TracePanic"), v)
b.impl.CreateUnreachable() b.impl.CreateUnreachable()
} }
*/
// Unreachable emits an unreachable instruction.
func (b Builder) Unreachable() {
b.impl.CreateUnreachable()
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@@ -83,6 +83,7 @@ func pyVarExpr(mod Expr, name string) Expr {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Zero returns a zero constant expression.
func (p Program) Zero(t Type) Expr { func (p Program) Zero(t Type) Expr {
var ret llvm.Value var ret llvm.Value
switch u := t.raw.Type.Underlying().(type) { switch u := t.raw.Type.Underlying().(type) {
@@ -127,16 +128,11 @@ func (p Program) Zero(t Type) Expr {
return Expr{ret, t} return Expr{ret, t}
} }
// Null returns a null constant expression. // Nil returns a null constant expression. t should be a pointer type.
func (p Program) Null(t Type) Expr { func (p Program) Nil(t Type) Expr {
return Expr{llvm.ConstNull(t.ll), t} return Expr{llvm.ConstNull(t.ll), t}
} }
// PyNull returns a null *PyObject constant expression.
func (p Program) PyNull() Expr {
return p.Null(p.PyObjectPtr())
}
// BoolVal returns a boolean constant expression. // BoolVal returns a boolean constant expression.
func (p Program) BoolVal(v bool) Expr { func (p Program) BoolVal(v bool) Expr {
t := p.Bool() t := p.Bool()
@@ -180,7 +176,7 @@ func (p Program) Val(v interface{}) Expr {
func (b Builder) Const(v constant.Value, typ Type) Expr { func (b Builder) Const(v constant.Value, typ Type) Expr {
prog := b.Prog prog := b.Prog
if v == nil { if v == nil {
return prog.Null(typ) return prog.Nil(typ)
} }
raw := typ.raw.Type raw := typ.raw.Type
switch t := raw.Underlying().(type) { switch t := raw.Underlying().(type) {

View File

@@ -86,7 +86,7 @@ func (b Builder) Go(fn Expr, args ...Expr) {
data := Expr{b.aggregateMalloc(t, flds...), voidPtr} data := Expr{b.aggregateMalloc(t, flds...), voidPtr}
size := prog.SizeOf(voidPtr) size := prog.SizeOf(voidPtr)
pthd := b.Alloca(prog.IntVal(uint64(size), prog.Uintptr())) pthd := b.Alloca(prog.IntVal(uint64(size), prog.Uintptr()))
b.pthreadCreate(pthd, prog.Null(voidPtr), pkg.routine(t, len(args)), data) b.pthreadCreate(pthd, prog.Nil(voidPtr), pkg.routine(t, len(args)), data)
} }
func (p Package) routineName() string { func (p Package) routineName() string {
@@ -107,7 +107,7 @@ func (p Package) routine(t Type, n int) Expr {
} }
b.Call(fn, args...) b.Call(fn, args...)
b.free(param) b.free(param)
b.Return(prog.Null(prog.VoidPtr())) b.Return(prog.Nil(prog.VoidPtr()))
return routine.Expr return routine.Expr
} }

View File

@@ -107,6 +107,17 @@ func aggregateInit(b llvm.Builder, ptr llvm.Value, tll llvm.Type, flds ...llvm.V
} }
} }
/*
func (b Builder) dupMalloc(v Expr) Expr {
prog := b.Prog
n := prog.SizeOf(v.Type)
tptr := prog.Pointer(v.Type)
ptr := b.malloc(prog.Val(uintptr(n))).impl
b.Store(Expr{ptr, tptr}, v)
return Expr{ptr, tptr}
}
*/
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// The Alloc instruction reserves space for a variable of the given type, // The Alloc instruction reserves space for a variable of the given type,

View File

@@ -132,13 +132,15 @@ type aProgram struct {
rtMapTy llvm.Type rtMapTy llvm.Type
anyTy Type anyTy Type
//anyPtr Type
//anyPPtr Type
voidTy Type voidTy Type
voidPtr Type voidPtr Type
voidPPtr Type voidPPtr Type
boolTy Type boolTy Type
cstrTy Type cstrTy Type
cintTy Type cintTy Type
//cintPtr Type cintPtr Type
stringTy Type stringTy Type
uintptrTy Type uintptrTy Type
intTy Type intTy Type
@@ -158,7 +160,6 @@ type aProgram struct {
abiTyPPtr Type abiTyPPtr Type
deferTy Type deferTy Type
deferPtr Type deferPtr Type
deferPPtr Type
pyImpTy *types.Signature pyImpTy *types.Signature
pyNewList *types.Signature pyNewList *types.Signature
@@ -328,14 +329,6 @@ func (p Program) DeferPtr() Type {
return p.deferPtr return p.deferPtr
} }
// DeferPtrPtr returns **runtime.Defer type.
func (p Program) DeferPtrPtr() Type {
if p.deferPPtr == nil {
p.deferPPtr = p.Pointer(p.DeferPtr())
}
return p.deferPPtr
}
// AbiTypePtr returns *abi.Type type. // AbiTypePtr returns *abi.Type type.
func (p Program) AbiTypePtr() Type { func (p Program) AbiTypePtr() Type {
if p.abiTyPtr == nil { if p.abiTyPtr == nil {
@@ -360,6 +353,7 @@ func (p Program) Void() Type {
return p.voidTy return p.voidTy
} }
// VoidPtr returns *void type.
func (p Program) VoidPtr() Type { func (p Program) VoidPtr() Type {
if p.voidPtr == nil { if p.voidPtr == nil {
p.voidPtr = p.rawType(types.Typ[types.UnsafePointer]) p.voidPtr = p.rawType(types.Typ[types.UnsafePointer])
@@ -367,6 +361,7 @@ func (p Program) VoidPtr() Type {
return p.voidPtr return p.voidPtr
} }
// VoidPtrPtr returns **void type.
func (p Program) VoidPtrPtr() Type { func (p Program) VoidPtrPtr() Type {
if p.voidPPtr == nil { if p.voidPPtr == nil {
p.voidPPtr = p.rawType(types.NewPointer(types.Typ[types.UnsafePointer])) p.voidPPtr = p.rawType(types.NewPointer(types.Typ[types.UnsafePointer]))
@@ -382,6 +377,7 @@ func (p Program) Bool() Type {
return p.boolTy return p.boolTy
} }
// CStr returns *int8 type.
func (p Program) CStr() Type { func (p Program) CStr() Type {
if p.cstrTy == nil { // *int8 if p.cstrTy == nil { // *int8
p.cstrTy = p.rawType(types.NewPointer(types.Typ[types.Int8])) p.cstrTy = p.rawType(types.NewPointer(types.Typ[types.Int8]))
@@ -389,6 +385,7 @@ func (p Program) CStr() Type {
return p.cstrTy return p.cstrTy
} }
// String returns string type.
func (p Program) String() Type { func (p Program) String() Type {
if p.stringTy == nil { if p.stringTy == nil {
p.stringTy = p.rawType(types.Typ[types.String]) p.stringTy = p.rawType(types.Typ[types.String])
@@ -396,6 +393,24 @@ func (p Program) String() Type {
return p.stringTy return p.stringTy
} }
/*
// AnyPtrPtr returns **any type.
func (p Program) AnyPtrPtr() Type {
if p.anyPPtr == nil {
p.anyPPtr = p.Pointer(p.AnyPtr())
}
return p.anyPPtr
}
// AnyPtr returns *any type.
func (p Program) AnyPtr() Type {
if p.anyPtr == nil {
p.anyPtr = p.Pointer(p.Any())
}
return p.anyPtr
}
*/
// Any returns the any (empty interface) type. // Any returns the any (empty interface) type.
func (p Program) Any() Type { func (p Program) Any() Type {
if p.anyTy == nil { if p.anyTy == nil {
@@ -410,6 +425,7 @@ func (p Program) Any() Type {
func (p Program) Eface() Type { func (p Program) Eface() Type {
return p.Any() return p.Any()
} }
*/
// CIntPtr returns *c.Int type. // CIntPtr returns *c.Int type.
func (p Program) CIntPtr() Type { func (p Program) CIntPtr() Type {
@@ -418,7 +434,6 @@ func (p Program) CIntPtr() Type {
} }
return p.cintPtr return p.cintPtr
} }
*/
// CInt returns c.Int type. // CInt returns c.Int type.
func (p Program) CInt() Type { func (p Program) CInt() Type {
@@ -550,7 +565,7 @@ func (p Package) cFunc(fullName string, sig *types.Signature) Expr {
func (p Package) closureStub(b Builder, t *types.Struct, v Expr) Expr { func (p Package) closureStub(b Builder, t *types.Struct, v Expr) Expr {
name := v.impl.Name() name := v.impl.Name()
prog := b.Prog prog := b.Prog
nilVal := prog.Null(prog.VoidPtr()).impl nilVal := prog.Nil(prog.VoidPtr()).impl
if fn, ok := p.stubs[name]; ok { if fn, ok := p.stubs[name]; ok {
v = fn.Expr v = fn.Expr
} else { } else {
@@ -605,7 +620,8 @@ func (p Package) afterBuilder() Builder {
// AfterInit is called after the package is initialized (init all packages that depends on). // AfterInit is called after the package is initialized (init all packages that depends on).
func (p Package) AfterInit(b Builder, ret BasicBlock) { func (p Package) AfterInit(b Builder, ret BasicBlock) {
p.deferInit() p.keyInit(deferKey)
p.keyInit(excepKey)
doAfterb := p.afterb != nil doAfterb := p.afterb != nil
doPyLoadModSyms := p.pyHasModSyms() doPyLoadModSyms := p.pyHasModSyms()
if doAfterb || doPyLoadModSyms { if doAfterb || doPyLoadModSyms {

View File

@@ -217,7 +217,7 @@ func (p Package) PyNewModVar(name string, doInit bool) Global {
objPtr := prog.PyObjectPtrPtr().raw.Type objPtr := prog.PyObjectPtrPtr().raw.Type
g := p.NewVar(name, objPtr, InC) g := p.NewVar(name, objPtr, InC)
if doInit { if doInit {
g.Init(prog.Null(g.Type)) g.Init(prog.Nil(g.Type))
g.impl.SetLinkage(llvm.LinkOnceAnyLinkage) g.impl.SetLinkage(llvm.LinkOnceAnyLinkage)
} }
p.pymods[name] = g p.pymods[name] = g
@@ -246,7 +246,7 @@ func (b Builder) PyLoadModSyms(modName string, objs ...PyObjRef) Expr {
args = append(args, o.Expr) args = append(args, o.Expr)
} }
prog := b.Prog prog := b.Prog
args = append(args, prog.Null(prog.CStr())) args = append(args, prog.Nil(prog.CStr()))
return b.Call(fnLoad, args...) return b.Call(fnLoad, args...)
} }
@@ -273,7 +273,7 @@ func (b Builder) pyCall(fn Expr, args []Expr) (ret Expr) {
callargs := make([]Expr, n+2) callargs := make([]Expr, n+2)
callargs[0] = fn callargs[0] = fn
copy(callargs[1:], args) copy(callargs[1:], args)
callargs[n+1] = prog.PyNull() callargs[n+1] = prog.Nil(prog.PyObjectPtr())
ret = b.Call(call, callargs...) ret = b.Call(call, callargs...)
} }
return return
@@ -372,7 +372,7 @@ func (p Package) PyNewFunc(name string, sig *types.Signature, doInit bool) PyObj
obj := p.NewVar(name, prog.PyObjectPtrPtr().RawType(), InC) obj := p.NewVar(name, prog.PyObjectPtrPtr().RawType(), InC)
if doInit { if doInit {
prog.NeedPyInit = true prog.NeedPyInit = true
obj.Init(prog.Null(obj.Type)) obj.Init(prog.Nil(obj.Type))
obj.impl.SetLinkage(llvm.LinkOnceAnyLinkage) obj.impl.SetLinkage(llvm.LinkOnceAnyLinkage)
} }
ty := &aType{obj.ll, rawType{types.NewPointer(sig)}, vkPyFuncRef} ty := &aType{obj.ll, rawType{types.NewPointer(sig)}, vkPyFuncRef}