vm: properly unload context on exception

Do not copy exception context on CALL*.
This commit is contained in:
Evgenii Stratonikov 2020-08-22 12:01:57 +03:00
parent fa1d1a8b00
commit 04f5fdefa0
2 changed files with 8 additions and 1 deletions

View file

@ -1476,6 +1476,7 @@ func (v *VM) Call(ctx *Context, offset int) {
newCtx.CheckReturn = false newCtx.CheckReturn = false
newCtx.local = nil newCtx.local = nil
newCtx.arguments = nil newCtx.arguments = nil
newCtx.tryStack = NewStack("exception")
v.istack.PushVal(newCtx) v.istack.PushVal(newCtx)
v.Jump(newCtx, offset) v.Jump(newCtx, offset)
} }
@ -1517,7 +1518,7 @@ func (v *VM) handleException() {
pop := 0 pop := 0
ictx := v.istack.Peek(0).Value().(*Context) ictx := v.istack.Peek(0).Value().(*Context)
for ictx != nil { for ictx != nil {
e := ictx.tryStack.Peek(pop) e := ictx.tryStack.Peek(0)
for e != nil { for e != nil {
ectx := e.Value().(*exceptionHandlingContext) ectx := e.Value().(*exceptionHandlingContext)
if ectx.State == eFinally || (ectx.State == eCatch && !ectx.HasFinally()) { if ectx.State == eFinally || (ectx.State == eCatch && !ectx.HasFinally()) {

View file

@ -1336,6 +1336,12 @@ func TestTRY(t *testing.T) {
checkVMFailed(t, vm) checkVMFailed(t, vm)
}) })
}) })
t.Run("ThrowInCall", func(t *testing.T) {
catchP := []byte{byte(opcode.CALL), 2, byte(opcode.PUSH1), byte(opcode.ADD), byte(opcode.THROW), byte(opcode.RET)}
inner := getTRYProgram(throw, catchP, []byte{byte(opcode.PUSH2)})
// add 5 to the exception, mul to the result of inner finally (2)
getTRYTestFunc(47, inner, append(add5, byte(opcode.MUL)), add9)(t)
})
} }
func TestMEMCPY(t *testing.T) { func TestMEMCPY(t *testing.T) {