diff options
Diffstat (limited to 'compiler/vm.nim')
-rw-r--r-- | compiler/vm.nim | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim index e40acca6c..e5b357a11 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -133,6 +133,8 @@ proc createStrKeepNode(x: var TFullReg) = # cause of bugs like these is that the VM does not properly distinguish # between variable defintions (var foo = e) and variable updates (foo = e). +include vmhooks + template createStr(x) = x.node = newNode(nkStrLit) @@ -256,8 +258,16 @@ proc cleanUpOnException(c: PCtx; tos: PStackFrame): c.currentExceptionB = c.currentExceptionA c.currentExceptionA = nil # execute the corresponding handler: + while c.code[pc2].opcode == opcExcept: inc pc2 return (pc2, f) inc pc2 + if c.code[pc2].opcode != opcExcept and nextExceptOrFinally >= 0: + # we're at the end of the *except list*, but maybe there is another + # *except branch*? + pc2 = nextExceptOrFinally+1 + if c.code[pc2].opcode == opcExcept: + nextExceptOrFinally = pc2 + c.code[pc2].regBx - wordExcess + if nextExceptOrFinally >= 0: pc2 = nextExceptOrFinally if c.code[pc2].opcode == opcFinally: @@ -801,7 +811,11 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = let bb = regs[rb].node let isClosure = bb.kind == nkPar let prc = if not isClosure: bb.sym else: bb.sons[0].sym - if sfImportc in prc.flags: + if prc.offset < -1: + # it's a callback: + c.callbacks[-prc.offset-2].value( + VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[pointer](regs))) + elif sfImportc in prc.flags: if allowFFI notin c.features: globalError(c.debug[pc], errGenerated, "VM not allowed to do FFI") # we pass 'tos.slots' instead of 'regs' so that the compiler can keep @@ -832,9 +846,6 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = if isClosure: newFrame.slots[rc].kind = rkNode newFrame.slots[rc].node = regs[rb].node.sons[1] - # allocate the temporaries: - #for i in rc+ord(isClosure) .. <prc.offset: - # newFrame.slots[i] = newNode(nkEmpty) tos = newFrame move(regs, newFrame.slots) # -1 for the following 'inc pc' @@ -888,10 +899,13 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcTry: let rbx = instr.regBx - wordExcess tos.pushSafePoint(pc + rbx) + assert c.code[pc+rbx].opcode in {opcExcept, opcFinally} of opcExcept: # just skip it; it's followed by a jump; # we'll execute in the 'raise' handler - discard + let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc' + inc pc, rbx + assert c.code[pc+1].opcode in {opcExcept, opcFinally} of opcFinally: # just skip it; it's followed by the code we need to execute anyway tos.popSafePoint() @@ -1033,8 +1047,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = internalError(c.debug[pc], "too implement") of opcNarrowS: decodeB(rkInt) - let min = -(1 shl (rb-1)) - let max = (1 shl (rb-1))-1 + let min = -(1.BiggestInt shl (rb-1)) + let max = (1.BiggestInt shl (rb-1))-1 if regs[ra].intVal < min or regs[ra].intVal > max: stackTrace(c, tos, pc, errGenerated, msgKindToString(errUnhandledExceptionX) % "value out of range") @@ -1132,14 +1146,14 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcParseExprToAst: decodeB(rkNode) # c.debug[pc].line.int - countLines(regs[rb].strVal) ? - let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFilename, + let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFullPath, c.debug[pc].line.int) if sonsLen(ast) != 1: globalError(c.debug[pc], errExprExpected, "multiple statements") regs[ra].node = ast.sons[0] of opcParseStmtToAst: decodeB(rkNode) - let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFilename, + let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFullPath, c.debug[pc].line.int) regs[ra].node = ast of opcCallSite: @@ -1316,6 +1330,8 @@ proc evalExpr*(c: PCtx, n: PNode): PNode = assert c.code[start].opcode != opcEof result = execute(c, start) +include vmops + # for now we share the 'globals' environment. XXX Coming soon: An API for # storing&loading the 'globals' environment to get what a component system # requires. @@ -1325,6 +1341,7 @@ var proc setupGlobalCtx(module: PSym) = if globalCtx.isNil: globalCtx = newCtx(module) else: refresh(globalCtx, module) + registerAdditionalOps(globalCtx) proc myOpen(module: PSym): PPassContext = #var c = newEvalContext(module, emRepl) |