From c62e23014a5a7d91648a5cf3a8da53712d5c6c58 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 17 Jul 2021 17:12:50 +0800 Subject: [PATCH] TestCallInlineClosure: ReturnErr(outer=true) --- codebuild.go | 29 +++++++++++++++++++++-------- package_test.go | 13 ++++++++++--- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/codebuild.go b/codebuild.go index 6a06efe4..149704f9 100644 --- a/codebuild.go +++ b/codebuild.go @@ -186,7 +186,7 @@ func (p *CodeBuilder) ReturnErr(outer bool) *CodeBuilder { if last.Type() == TyError { // last result is error err := p.stk.Pop() for i := 0; i < n-1; i++ { - p.ZeroLit(results.At(i).Type()) + p.doZeroLit(results.At(i).Type(), false) } p.stk.Push(err) p.returnResults(n) @@ -223,9 +223,9 @@ func (p *CodeBuilder) Return(n int) *CodeBuilder { for i := n - 1; i >= 0; i-- { key := closureParamInst{fn, results.At(i)} elem := p.stk.Pop() - p.VarRef(p.paramInsts[key]) + p.doVarRef(p.paramInsts[key], false) p.stk.Push(elem) - p.Assign(1) + p.doAssign(1, nil, false) } p.Goto(p.getEndingLabel(fn)) } else { @@ -420,8 +420,12 @@ func (p *CodeBuilder) NewAutoVar(name string, pv **types.Var) *CodeBuilder { // VarRef func: p.VarRef(nil) means underscore (_) func (p *CodeBuilder) VarRef(ref interface{}) *CodeBuilder { + return p.doVarRef(ref, true) +} + +func (p *CodeBuilder) doVarRef(ref interface{}, allowDebug bool) *CodeBuilder { if ref == nil { - if debug { + if allowDebug && debug { log.Println("VarRef _") } p.stk.Push(internal.Elem{ @@ -430,7 +434,7 @@ func (p *CodeBuilder) VarRef(ref interface{}) *CodeBuilder { } else { switch v := ref.(type) { case *types.Var: - if debug { + if allowDebug && debug { log.Println("VarRef", v.Name()) } fn := p.current.fn @@ -460,8 +464,13 @@ func (p *CodeBuilder) None() *CodeBuilder { return p } +// ZeroLit func func (p *CodeBuilder) ZeroLit(typ types.Type) *CodeBuilder { - if debug { + return p.doZeroLit(typ, true) +} + +func (p *CodeBuilder) doZeroLit(typ types.Type, allowDebug bool) *CodeBuilder { + if allowDebug && debug { log.Println("ZeroLit") } switch t := typ.(type) { @@ -916,14 +925,18 @@ func indirect(typ types.Type) types.Type { } // Assign func -func (p *CodeBuilder) Assign(lhs int, v ...int) *CodeBuilder { +func (p *CodeBuilder) Assign(lhs int, rhs ...int) *CodeBuilder { + return p.doAssign(lhs, rhs, true) +} + +func (p *CodeBuilder) doAssign(lhs int, v []int, allowDebug bool) *CodeBuilder { var rhs int if v != nil { rhs = v[0] } else { rhs = lhs } - if debug { + if allowDebug && debug { log.Println("Assign", lhs, rhs) } args := p.stk.GetArgs(lhs + rhs) diff --git a/package_test.go b/package_test.go index e8129e85..def2097a 100644 --- a/package_test.go +++ b/package_test.go @@ -1572,11 +1572,15 @@ func TestCallInlineClosure(t *testing.T) { pkg := newMainPackage() fmt := pkg.Import("fmt") ret := pkg.NewAutoParam("ret") - sig := types.NewSignature(nil, nil, gox.NewTuple(ret), false) - pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). + err := pkg.NewParam("", gox.TyError) + sig := types.NewSignature(nil, nil, types.NewTuple(ret), false) + pkg.NewFunc(nil, "foo", nil, types.NewTuple(err), false).BodyStart(pkg). Val(fmt.Ref("Println")). CallInlineClosureStart(sig, 0, false). /**/ DefineVarStart("n", "err").Val(fmt.Ref("Println")).Val("Hi").Call(1).EndInit(1). + /**/ If().Val(ctxRef(pkg, "err")).CompareNil(token.NEQ).Then(). + /******/ Val(ctxRef(pkg, "err")).ReturnErr(true). + /******/ End(). /**/ Val(ctxRef(pkg, "n")).Return(1). /**/ End(). Call(1).EndStmt(). @@ -1585,10 +1589,13 @@ func TestCallInlineClosure(t *testing.T) { import fmt "fmt" -func main() { +func foo() error { var _autoGo_1 int { n, err := fmt.Println("Hi") + if err != nil { + return err + } _autoGo_1 = n goto _autoGo_2 _autoGo_2: