new VM: fixes for exception handling
This commit is contained in:
parent
6a055990f9
commit
033f2bbbf2
1 changed files with 17 additions and 8 deletions
|
|
@ -222,13 +222,14 @@ proc pushSafePoint(f: PStackFrame; pc: int) =
|
||||||
|
|
||||||
proc popSafePoint(f: PStackFrame) = discard f.safePoints.pop()
|
proc popSafePoint(f: PStackFrame) = discard f.safePoints.pop()
|
||||||
|
|
||||||
proc cleanUpOnException(c: PCtx; tos: PStackFrame; regs: seq[TFullReg]): int =
|
proc cleanUpOnException(c: PCtx; tos: PStackFrame):
|
||||||
|
tuple[pc: int, f: PStackFrame] =
|
||||||
let raisedType = c.currentExceptionA.typ.skipTypes(abstractPtrs)
|
let raisedType = c.currentExceptionA.typ.skipTypes(abstractPtrs)
|
||||||
var f = tos
|
var f = tos
|
||||||
while true:
|
while true:
|
||||||
while f.safePoints.isNil or f.safePoints.len == 0:
|
while f.safePoints.isNil or f.safePoints.len == 0:
|
||||||
f = f.next
|
f = f.next
|
||||||
if f.isNil: return -1
|
if f.isNil: return (-1, nil)
|
||||||
var pc2 = f.safePoints[f.safePoints.high]
|
var pc2 = f.safePoints[f.safePoints.high]
|
||||||
|
|
||||||
var nextExceptOrFinally = -1
|
var nextExceptOrFinally = -1
|
||||||
|
|
@ -244,13 +245,13 @@ proc cleanUpOnException(c: PCtx; tos: PStackFrame; regs: seq[TFullReg]): int =
|
||||||
c.currentExceptionB = c.currentExceptionA
|
c.currentExceptionB = c.currentExceptionA
|
||||||
c.currentExceptionA = nil
|
c.currentExceptionA = nil
|
||||||
# execute the corresponding handler:
|
# execute the corresponding handler:
|
||||||
return pc2
|
return (pc2, f)
|
||||||
inc pc2
|
inc pc2
|
||||||
if nextExceptOrFinally >= 0:
|
if nextExceptOrFinally >= 0:
|
||||||
pc2 = nextExceptOrFinally
|
pc2 = nextExceptOrFinally
|
||||||
if c.code[pc2].opcode == opcFinally:
|
if c.code[pc2].opcode == opcFinally:
|
||||||
# execute the corresponding handler, but don't quit walking the stack:
|
# execute the corresponding handler, but don't quit walking the stack:
|
||||||
return pc2
|
return (pc2, f)
|
||||||
# not the right one:
|
# not the right one:
|
||||||
discard f.safePoints.pop
|
discard f.safePoints.pop
|
||||||
|
|
||||||
|
|
@ -869,19 +870,27 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
of opcFinallyEnd:
|
of opcFinallyEnd:
|
||||||
if c.currentExceptionA != nil:
|
if c.currentExceptionA != nil:
|
||||||
# we are in a cleanup run:
|
# we are in a cleanup run:
|
||||||
pc = cleanUpOnException(c, tos, regs)-1
|
let (newPc, newTos) = cleanUpOnException(c, tos)
|
||||||
if pc < 0:
|
if newPc-1 < 0:
|
||||||
bailOut(c, tos)
|
bailOut(c, tos)
|
||||||
return
|
return
|
||||||
|
pc = newPc-1
|
||||||
|
if tos != newTos:
|
||||||
|
tos = newTos
|
||||||
|
move(regs, tos.slots)
|
||||||
of opcRaise:
|
of opcRaise:
|
||||||
let raised = regs[ra].node
|
let raised = regs[ra].node
|
||||||
c.currentExceptionA = raised
|
c.currentExceptionA = raised
|
||||||
c.exceptionInstr = pc
|
c.exceptionInstr = pc
|
||||||
|
let (newPc, newTos) = cleanUpOnException(c, tos)
|
||||||
# -1 because of the following 'inc'
|
# -1 because of the following 'inc'
|
||||||
pc = cleanUpOnException(c, tos, regs) - 1
|
if pc-1 < 0:
|
||||||
if pc < 0:
|
|
||||||
bailOut(c, tos)
|
bailOut(c, tos)
|
||||||
return
|
return
|
||||||
|
pc = newPc -1
|
||||||
|
if tos != newTos:
|
||||||
|
tos = newTos
|
||||||
|
move(regs, tos.slots)
|
||||||
of opcNew:
|
of opcNew:
|
||||||
ensureKind(rkNode)
|
ensureKind(rkNode)
|
||||||
let typ = c.types[instr.regBx - wordExcess]
|
let typ = c.types[instr.regBx - wordExcess]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue