diff options
author | Araq <rumpf_a@web.de> | 2013-07-27 01:28:31 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2013-07-27 01:28:31 +0200 |
commit | 27b7ecbbff073ad8df0a663960f69a87f10e1e35 (patch) | |
tree | 7753615245e74e096be02219a494a09f5b9a200c /compiler/vm.nim | |
parent | fca23d1675c8dd7487266a2478a4e7ee66807acc (diff) | |
download | Nim-27b7ecbbff073ad8df0a663960f69a87f10e1e35.tar.gz |
new vm: lots of fixes
Diffstat (limited to 'compiler/vm.nim')
-rw-r--r-- | compiler/vm.nim | 59 |
1 files changed, 44 insertions, 15 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim index 7ae5b7878..642bfd94c 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -10,7 +10,10 @@ ## This file implements the new evaluation engine for Nimrod code. ## An instruction is 1-2 int32s in memory, it is a register based VM. -import ast, astalgo, msgs, vmdef, vmgen, nimsets, types, passes, unsigned +import + strutils, ast, astalgo, msgs, vmdef, vmgen, nimsets, types, passes, unsigned + +from semfold import leValueConv type PStackFrame* = ref TStackFrame @@ -79,10 +82,6 @@ template decodeBx(k: expr) {.immediate, dirty.} = let rbx = instr.regBx - wordExcess ensureKind(k) -proc compile(c: PCtx, s: PSym): int = - result = vmgen.genProc(c, s) - #c.echoCode - proc myreset(n: PNode) = when defined(system.reset): var oldInfo = n.info @@ -130,18 +129,14 @@ proc pushSafePoint(f: PStackFrame; pc: int) = proc popSafePoint(f: PStackFrame) = discard f.safePoints.pop() -proc nextSafePoint(f: PStackFrame): int = - var f = f - while f.safePoints.isNil or f.safePoints.len == 0: - f = f.next - if f.isNil: return -1 - result = f.safePoints.pop - proc cleanUpOnException(c: PCtx; tos: PStackFrame; regs: TNodeSeq): int = let raisedType = c.currentExceptionA.typ.skipTypes(abstractPtrs) + var f = tos while true: - var pc2 = tos.nextSafePoint - if pc2 == -1: return -1 + while f.safePoints.isNil or f.safePoints.len == 0: + f = f.next + if f.isNil: return -1 + var pc2 = f.safePoints[f.safePoints.high] var nextExceptOrFinally = -1 if c.code[pc2].opcode == opcExcept: @@ -163,6 +158,8 @@ proc cleanUpOnException(c: PCtx; tos: PStackFrame; regs: TNodeSeq): int = if c.code[pc2].opcode == opcFinally: # execute the corresponding handler, but don't quit walking the stack: return pc2 + # not the right one: + discard f.safePoints.pop proc cleanUpOnReturn(c: PCtx; f: PStackFrame): int = if f.safePoints.isNil: return -1 @@ -174,6 +171,10 @@ proc cleanUpOnReturn(c: PCtx; f: PStackFrame): int = return pc return -1 +proc compile(c: PCtx, s: PSym): int = + result = vmgen.genProc(c, s) + #c.echoCode + proc execute(c: PCtx, start: int) = var pc = start var regs: TNodeSeq # alias to tos.slots for performance @@ -188,11 +189,12 @@ proc execute(c: PCtx, start: int) = of opcEof: break of opcRet: # XXX perform any cleanup actions + pc = tos.comesFrom tos = tos.next if tos.isNil: return + let retVal = regs[0] move(regs, tos.slots) - pc = tos.comesFrom assert c.code[pc].opcode in {opcIndCall, opcIndCallAsgn} if c.code[pc].opcode == opcIndCallAsgn: regs[c.code[pc].regA] = retVal @@ -222,6 +224,10 @@ proc execute(c: PCtx, start: int) = let idx = regs[rc].intVal # XXX what if the array is not 0-based? -> codegen should insert a sub regs[ra] = regs[rb].sons[idx.int] + of opcLdStrIdx: + decodeBC(nkIntLit) + let idx = regs[rc].intVal + regs[ra].intVal = regs[rb].strVal[idx.int].ord of opcWrArr: # a[b] = c let rb = instr.regB @@ -432,6 +438,15 @@ proc execute(c: PCtx, start: int) = regs[ra].strVal = getstr(regs[rb]) for i in rb+1..rb+rc-1: regs[ra].strVal.add getstr(regs[i]) + of opcAddStrCh: + decodeB(nkStrLit) + regs[ra].strVal.add(regs[rb].intVal.chr) + of opcAddStrStr: + decodeB(nkStrLit) + regs[ra].strVal.add(regs[rb].strVal) + of opcAddSeqElem: + decodeB(nkBracket) + regs[ra].add(copyTree(regs[rb])) of opcEcho: echo regs[ra].strVal of opcContainsSet: @@ -444,6 +459,14 @@ proc execute(c: PCtx, start: int) = let rd = c.code[pc].regA regs[ra].strVal = substr(regs[rb].strVal, regs[rc].intVal.int, regs[rd].intVal.int) + of opcRangeChck: + let rb = instr.regB + let rc = instr.regC + if not (leValueConv(regs[rb], regs[ra]) and + leValueConv(regs[ra], regs[rc])): + stackTrace(c, tos, pc, errGenerated, + msgKindToString(errIllegalConvFromXtoY) % [ + "unknown type" , "unknown type"]) of opcIndCall, opcIndCallAsgn: # dest = call regStart, n; where regStart = fn, arg1, ... let rb = instr.regB @@ -545,6 +568,12 @@ proc execute(c: PCtx, start: int) = regs[ra] = getNullValue(typ, c.debug[pc]) of opcLdConst: regs[ra] = c.constants.sons[instr.regBx - wordExcess] + of opcAsgnConst: + let rb = instr.regBx - wordExcess + if regs[ra].isNil: + regs[ra] = copyTree(c.constants.sons[rb]) + else: + asgnComplex(regs[ra], c.constants.sons[rb]) of opcNBindSym: # trivial implementation: let rb = instr.regB |