llgo/ssa: RunDefers
This commit is contained in:
@@ -254,11 +254,6 @@ func (p Function) Name() string {
|
||||
return p.impl.Name()
|
||||
}
|
||||
|
||||
// DeferFuncName returns the name of the defer procedure.
|
||||
func (p Function) DeferFuncName() string {
|
||||
return p.Name() + "._llgo_defer"
|
||||
}
|
||||
|
||||
// Params returns the function's ith parameter.
|
||||
func (p Function) Param(i int) Expr {
|
||||
i += p.base // skip if hasFreeVars
|
||||
|
||||
26
ssa/expr.go
26
ssa/expr.go
@@ -113,6 +113,16 @@ func (p Program) Zero(t Type) Expr {
|
||||
ret = llvm.ConstStruct(flds, false)
|
||||
case *types.Slice:
|
||||
ret = p.Zero(p.rtType("Slice")).impl
|
||||
/* TODO(xsw):
|
||||
case *types.Interface:
|
||||
var name string
|
||||
if u.Empty() {
|
||||
name = "Eface"
|
||||
} else {
|
||||
name = "Iface"
|
||||
}
|
||||
ret = p.Zero(p.rtType(name)).impl
|
||||
*/
|
||||
default:
|
||||
log.Panicln("todo:", u)
|
||||
}
|
||||
@@ -818,6 +828,11 @@ func (b Builder) Do(da DoAction, fn Expr, args ...Expr) (ret Expr) {
|
||||
// Go spec (excluding "make" and "new").
|
||||
func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
|
||||
switch fn {
|
||||
case "String": // unsafe.String
|
||||
return b.unsafeString(args[0].impl, args[1].impl)
|
||||
case "Slice": // unsafe.Slice
|
||||
size := args[1].impl
|
||||
return b.unsafeSlice(args[0], size, size)
|
||||
case "len":
|
||||
if len(args) == 1 {
|
||||
arg := args[0]
|
||||
@@ -857,8 +872,6 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
case "print", "println":
|
||||
return b.PrintEx(fn == "println", args...)
|
||||
case "copy":
|
||||
if len(args) == 2 {
|
||||
dst := args[0]
|
||||
@@ -874,11 +887,10 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
case "String": // unsafe.String
|
||||
return b.unsafeString(args[0].impl, args[1].impl)
|
||||
case "Slice": // unsafe.Slice
|
||||
size := args[1].impl
|
||||
return b.unsafeSlice(args[0], size, size)
|
||||
//case "recover":
|
||||
// return b.Recover()
|
||||
case "print", "println":
|
||||
return b.PrintEx(fn == "println", args...)
|
||||
}
|
||||
panic("todo: " + fn)
|
||||
}
|
||||
|
||||
@@ -333,16 +333,6 @@ func (p Program) Struct(typs ...Type) Type {
|
||||
return p.rawType(types.NewStruct(els, nil))
|
||||
}
|
||||
|
||||
/*
|
||||
// Eface returns the empty interface type.
|
||||
func (p Program) Eface() Type {
|
||||
if p.efaceTy == nil {
|
||||
p.efaceTy = p.rawType(tyAny)
|
||||
}
|
||||
return p.efaceTy
|
||||
}
|
||||
*/
|
||||
|
||||
// DeferPtr returns *runtime.Defer.
|
||||
func (p Program) DeferPtr() Type {
|
||||
if p.deferPtr == nil {
|
||||
@@ -436,7 +426,7 @@ func (p Program) String() Type {
|
||||
return p.stringTy
|
||||
}
|
||||
|
||||
// Any returns any type.
|
||||
// Any returns the any (empty interface) type.
|
||||
func (p Program) Any() Type {
|
||||
if p.anyTy == nil {
|
||||
p.anyTy = p.rawType(tyAny)
|
||||
@@ -444,6 +434,12 @@ func (p Program) Any() Type {
|
||||
return p.anyTy
|
||||
}
|
||||
|
||||
// Eface returns the empty interface type.
|
||||
// It is equivalent to Any.
|
||||
func (p Program) Eface() Type {
|
||||
return p.Any()
|
||||
}
|
||||
|
||||
// CIntPtr returns *c.Int type.
|
||||
func (p Program) CIntPtr() Type {
|
||||
if p.cintPtr == nil {
|
||||
|
||||
@@ -175,6 +175,17 @@ func (p Package) newDeferKey() Global {
|
||||
return p.NewVarEx(deferKey, p.Prog.CIntPtr())
|
||||
}
|
||||
|
||||
// DeferFuncName returns the name of the defer procedure.
|
||||
func (p Function) DeferFuncName() string {
|
||||
return p.Name() + "._llgo_defer"
|
||||
}
|
||||
|
||||
// DeferFunc returns the defer procedure of this function.
|
||||
func (p Function) DeferFunc() Function {
|
||||
name := p.DeferFuncName()
|
||||
return p.Pkg.NewFunc(name, p.Prog.tyDeferFunc(), InC)
|
||||
}
|
||||
|
||||
func (b Builder) deferKey() Expr {
|
||||
return b.Load(b.Pkg.newDeferKey().Expr)
|
||||
}
|
||||
@@ -192,8 +203,7 @@ func (b Builder) Defer(fn Expr, args ...Expr) {
|
||||
zero := prog.Val(uintptr(0))
|
||||
key := b.deferKey()
|
||||
if next == 0 {
|
||||
name := self.DeferFuncName()
|
||||
deferfn := pkg.NewFunc(name, b.Prog.tyDeferFunc(), InC)
|
||||
deferfn := self.DeferFunc()
|
||||
deferb := deferfn.MakeBody(1)
|
||||
pkg.deferb = unsafe.Pointer(deferb)
|
||||
pkg.deferparam = deferfn.Param(0)
|
||||
@@ -218,8 +228,27 @@ func (b Builder) Defer(fn Expr, args ...Expr) {
|
||||
})
|
||||
}
|
||||
|
||||
// RunDefers emits instructions to run deferred instructions.
|
||||
func (b Builder) RunDefers() {
|
||||
self := b.Func
|
||||
deferfn := self.DeferFunc()
|
||||
bitsPtr := b.FieldAddr(self.deferData, 1)
|
||||
b.Call(deferfn.Expr, b.Load(bitsPtr))
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
// Recover emits a recover instruction.
|
||||
func (b Builder) Recover() (v Expr) {
|
||||
if debugInstr {
|
||||
log.Println("Recover")
|
||||
}
|
||||
prog := b.Prog
|
||||
return prog.Zero(prog.Eface())
|
||||
}
|
||||
*/
|
||||
|
||||
// Panic emits a panic instruction.
|
||||
func (b Builder) Panic(v Expr) {
|
||||
if debugInstr {
|
||||
|
||||
Reference in New Issue
Block a user