@@ -838,16 +838,43 @@ func (p *context) deferStackOwner(fn *ssa.Function) llssa.Function {
838838 return owner
839839}
840840
841- func (p * context ) emitDo (b llssa.Builder , act llssa.DoAction , ds * explicitDeferStack , fn llssa.Expr , buildCall func (llssa.Builder , llssa.Expr , ... llssa.Expr ) llssa.Expr , args ... llssa.Expr ) llssa.Expr {
841+ func (p * context ) emitDo (b llssa.Builder , act llssa.DoAction , ds * explicitDeferStack , mayRecover bool , fn llssa.Expr , buildCall func (llssa.Builder , llssa.Expr , ... llssa.Expr ) llssa.Expr , args ... llssa.Expr ) llssa.Expr {
842842 if ds != nil {
843- b .DeferTo (ds .owner , ds .stack , fn , buildCall , args ... )
843+ b .DeferToRecover (ds .owner , ds .stack , mayRecover , fn , buildCall , args ... )
844844 return llssa .Nil
845845 }
846- return b .Do (act , fn , buildCall , args ... )
846+ switch act {
847+ case llssa .Call , llssa .Go :
848+ return b .Do (act , fn , buildCall , args ... )
849+ default :
850+ b .DeferRecover (act , mayRecover , fn , buildCall , args ... )
851+ return llssa .Nil
852+ }
853+ }
854+
855+ func (p * context ) callMayRecover (v ssa.Value ) bool {
856+ switch v := v .(type ) {
857+ case * ssa.Builtin :
858+ return false
859+ case * ssa.Function :
860+ return functionUsesRecover (v )
861+ case * ssa.MakeClosure :
862+ if fn , ok := v .Fn .(* ssa.Function ); ok {
863+ return functionUsesRecover (fn )
864+ }
865+ return true
866+ case * ssa.Call :
867+ if fn := v .Call .StaticCallee (); fn != nil {
868+ return functionUsesRecover (fn )
869+ }
870+ return true
871+ }
872+ return true
847873}
848874
849875func (p * context ) callEx (b llssa.Builder , act llssa.DoAction , call * ssa.CallCommon , ds * explicitDeferStack ) (ret llssa.Expr ) {
850876 cv := call .Value
877+ mayRecover := p .callMayRecover (cv )
851878 if mthd := call .Method ; mthd != nil {
852879 o := p .compileValue (b , cv )
853880 fn := b .Imethod (o , mthd )
@@ -856,7 +883,7 @@ func (p *context) callEx(b llssa.Builder, act llssa.DoAction, call *ssa.CallComm
856883 hasVArg = fnHasVArg
857884 }
858885 args := p .compileValues (b , call .Args , hasVArg )
859- ret = p .emitDo (b , act , ds , fn , llssa .Builder .Call , args ... )
886+ ret = p .emitDo (b , act , ds , true , fn , llssa .Builder .Call , args ... )
860887 return
861888 }
862889 kind := p .funcKind (cv )
@@ -879,7 +906,7 @@ func (p *context) callEx(b llssa.Builder, act llssa.DoAction, call *ssa.CallComm
879906 }
880907 }
881908 args := p .compileValues (b , args , kind )
882- ret = p .emitDo (b , act , ds , llssa .Builtin (fn ), llssa .Builder .Call , args ... )
909+ ret = p .emitDo (b , act , ds , false , llssa .Builtin (fn ), llssa .Builder .Call , args ... )
883910 case * ssa.Function :
884911 aFn , pyFn , ftype := p .compileFunction (cv )
885912 // TODO(xsw): check ca != llssa.Call
@@ -888,13 +915,13 @@ func (p *context) callEx(b llssa.Builder, act llssa.DoAction, call *ssa.CallComm
888915 p .inCFunc = true
889916 args := p .compileValues (b , args , kind )
890917 p .inCFunc = false
891- ret = p .emitDo (b , act , ds , aFn .Expr , llssa .Builder .Call , args ... )
918+ ret = p .emitDo (b , act , ds , mayRecover , aFn .Expr , llssa .Builder .Call , args ... )
892919 case goFunc :
893920 args := p .compileValues (b , args , kind )
894- ret = p .emitDo (b , act , ds , aFn .Expr , llssa .Builder .Call , args ... )
921+ ret = p .emitDo (b , act , ds , mayRecover , aFn .Expr , llssa .Builder .Call , args ... )
895922 case pyFunc :
896923 args := p .compileValues (b , args , kind )
897- ret = p .emitDo (b , act , ds , pyFn .Expr , llssa .Builder .Call , args ... )
924+ ret = p .emitDo (b , act , ds , mayRecover , pyFn .Expr , llssa .Builder .Call , args ... )
898925 case llgoPyList :
899926 args := p .compileValues (b , args , fnHasVArg )
900927 ret = b .PyList (args ... )
@@ -968,33 +995,33 @@ func (p *context) callEx(b llssa.Builder, act llssa.DoAction, call *ssa.CallComm
968995 b .Unreachable ()
969996 case llgoAtomicLoad :
970997 args := p .compileValues (b , args , kind )
971- ret = p .emitDo (b , act , ds , llssa .Nil , func (b llssa.Builder , _ llssa.Expr , args ... llssa.Expr ) llssa.Expr {
998+ ret = p .emitDo (b , act , ds , false , llssa .Nil , func (b llssa.Builder , _ llssa.Expr , args ... llssa.Expr ) llssa.Expr {
972999 return p .atomicLoad (b , args )
9731000 }, args ... )
9741001 case llgoAtomicStore :
9751002 args := p .compileValues (b , args , kind )
976- p .emitDo (b , act , ds , llssa .Nil , func (b llssa.Builder , _ llssa.Expr , args ... llssa.Expr ) llssa.Expr {
1003+ p .emitDo (b , act , ds , false , llssa .Nil , func (b llssa.Builder , _ llssa.Expr , args ... llssa.Expr ) llssa.Expr {
9771004 return p .atomicStore (b , args )
9781005 }, args ... )
9791006 case llgoAtomicCmpXchg :
9801007 args := p .compileValues (b , args , kind )
981- ret = p .emitDo (b , act , ds , llssa .Nil , func (b llssa.Builder , _ llssa.Expr , args ... llssa.Expr ) llssa.Expr {
1008+ ret = p .emitDo (b , act , ds , false , llssa .Nil , func (b llssa.Builder , _ llssa.Expr , args ... llssa.Expr ) llssa.Expr {
9821009 return p .atomicCmpXchg (b , args )
9831010 }, args ... )
9841011 case llgoAtomicCmpXchgOK :
9851012 args := p .compileValues (b , args , kind )
986- ret = p .emitDo (b , act , ds , llssa .Nil , func (b llssa.Builder , _ llssa.Expr , args ... llssa.Expr ) llssa.Expr {
1013+ ret = p .emitDo (b , act , ds , false , llssa .Nil , func (b llssa.Builder , _ llssa.Expr , args ... llssa.Expr ) llssa.Expr {
9871014 return p .atomicCmpXchgOK (b , args )
9881015 }, args ... )
9891016 case llgoAtomicAddReturnNew :
9901017 args := p .compileValues (b , args , kind )
991- ret = p .emitDo (b , act , ds , llssa .Nil , func (b llssa.Builder , _ llssa.Expr , args ... llssa.Expr ) llssa.Expr {
1018+ ret = p .emitDo (b , act , ds , false , llssa .Nil , func (b llssa.Builder , _ llssa.Expr , args ... llssa.Expr ) llssa.Expr {
9921019 return b .BinOp (token .ADD , p .atomic (b , llssa .OpAdd , args ), args [1 ])
9931020 }, args ... )
9941021 default :
9951022 if ftype >= llgoAtomicOpBase && ftype <= llgoAtomicOpLast {
9961023 args := p .compileValues (b , args , kind )
997- ret = p .emitDo (b , act , ds , llssa .Nil , func (b llssa.Builder , _ llssa.Expr , args ... llssa.Expr ) llssa.Expr {
1024+ ret = p .emitDo (b , act , ds , false , llssa .Nil , func (b llssa.Builder , _ llssa.Expr , args ... llssa.Expr ) llssa.Expr {
9981025 return p .atomic (b , llssa .AtomicOp (ftype - llgoAtomicOpBase ), args )
9991026 }, args ... )
10001027 } else {
@@ -1004,7 +1031,7 @@ func (p *context) callEx(b llssa.Builder, act llssa.DoAction, call *ssa.CallComm
10041031 default :
10051032 fn := p .compileValue (b , cv )
10061033 args := p .compileValues (b , args , kind )
1007- ret = p .emitDo (b , act , ds , fn , llssa .Builder .Call , args ... )
1034+ ret = p .emitDo (b , act , ds , mayRecover , fn , llssa .Builder .Call , args ... )
10081035 }
10091036 return
10101037}
0 commit comments