WIP: an API for VM replay global state support

This commit is contained in:
Andreas Rumpf 2018-06-03 20:18:43 +02:00
commit b5194f592c
8 changed files with 288 additions and 35 deletions

View file

@ -19,7 +19,7 @@ import ast except getstr
import
strutils, astalgo, msgs, vmdef, vmgen, nimsets, types, passes,
parser, vmdeps, idents, trees, renderer, options, transf, parseutils,
vmmarshal, gorgeimpl, lineinfos
vmmarshal, gorgeimpl, lineinfos, tables, btrees, macrocacheimpl
from semfold import leValueConv, ordinalValToString
from evaltempl import evalTemplate
@ -1572,6 +1572,95 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
var sym = newSym(k.TSymKind, getIdent(c.cache, name), c.module.owner, c.debug[pc])
incl(sym.flags, sfGenSym)
regs[ra].node = newSymNode(sym)
of opcNccValue:
decodeB(rkInt)
let destKey = regs[rb].node.strVal
regs[ra].intVal = getOrDefault(c.cacheCounters, destKey)
of opcNccInc:
let rb = instr.regB
let destKey = regs[ra].node.strVal
let by = regs[rb].intVal
let v = getOrDefault(c.cacheCounters, destKey)
c.cacheCounters[destKey] = v+by
recordInc(c, c.debug[pc], destKey, by)
of opcNcsAdd:
let destKey = regs[ra].node.strVal
let val = regs[instr.regB].node
if not contains(c.cacheSeqs, destKey):
c.cacheSeqs[destKey] = newTree(nkStmtList, val)
# newNodeI(nkStmtList, c.debug[pc])
else:
c.cacheSeqs[destKey].add val
recordAdd(c, c.debug[pc], destKey, val)
of opcNcsIncl:
let destKey = regs[ra].node.strVal
let val = regs[instr.regB].node
if not contains(c.cacheSeqs, destKey):
c.cacheSeqs[destKey] = newTree(nkStmtList, val)
else:
block search:
for existing in c.cacheSeqs[destKey]:
if exprStructuralEquivalent(existing, val, strictSymEquality=true):
break search
c.cacheSeqs[destKey].add val
recordIncl(c, c.debug[pc], destKey, val)
of opcNcsLen:
decodeB(rkInt)
let destKey = regs[rb].node.strVal
regs[ra].intVal =
if contains(c.cacheSeqs, destKey): c.cacheSeqs[destKey].len else: 0
of opcNcsAt:
decodeBC(rkNode)
let idx = regs[rc].intVal
let destKey = regs[rb].node.strVal
if contains(c.cacheSeqs, destKey) and idx <% c.cacheSeqs[destKey].len:
regs[ra].node = c.cacheSeqs[destKey][idx.int]
else:
stackTrace(c, tos, pc, errIndexOutOfBounds)
of opcNctPut:
let destKey = regs[ra].node.strVal
let key = regs[instr.regB].node.strVal
let val = regs[instr.regC].node
if not contains(c.cacheTables, destKey):
c.cacheTables[destKey] = initBTree[string, PNode]()
if not contains(c.cacheTables[destKey], key):
c.cacheTables[destKey].add(key, val)
recordPut(c, c.debug[pc], destKey, key, val)
else:
stackTrace(c, tos, pc, "key already exists: " & key)
of opcNctLen:
decodeB(rkInt)
let destKey = regs[rb].node.strVal
regs[ra].intVal =
if contains(c.cacheTables, destKey): c.cacheTables[destKey].len else: 0
of opcNctGet:
decodeBC(rkNode)
let destKey = regs[rb].node.strVal
let key = regs[rc].node.strVal
if contains(c.cacheTables, destKey):
if contains(c.cacheTables[destKey], key):
regs[ra].node = getOrDefault(c.cacheTables[destKey], key)
else:
stackTrace(c, tos, pc, "key does not exist: " & key)
else:
stackTrace(c, tos, pc, "key does not exist: " & destKey)
of opcNctHasNext:
decodeBC(rkInt)
let destKey = regs[rb].node.strVal
regs[ra].intVal =
btrees.hasNext(c.cacheTables[destKey], regs[rc].intVal.int) else: 0
of opcNctNext:
decodeBC(rkNode)
let destKey = regs[rb].node.strVal
let index = regs[rc].intVal
if contains(c.cacheTables, destKey):
let (k, v, nextIndex) = btrees.next(c.cacheTables[destKey], index.int)
regs[ra].node = newTree(nkTupleConstr, newStrNode(k, c.debug[pc]), v,
newIntNode(nkIntLit, nextIndex))
else:
stackTrace(c, tos, pc, "key does not exist: " & destKey)
of opcTypeTrait:
# XXX only supports 'name' for now; we can use regC to encode the
# type trait operation