Skip to content

Commit

Permalink
Merge #252
Browse files Browse the repository at this point in the history
252: Replace `PCtx` parameters with `TCtx` in VM code r=alaviss a=zerbina

* Where `TCtx` is now used, also use `func` instead of `proc`, if applicable

Not all usages of `PCtx` are replaced. `PCtx` is still used in procedures
that form the border between non-VM/VM code. `vmops` also still uses
 `PCtx`, as some ops need to capture a reference to the context

Co-authored-by: zerbina <[email protected]>
  • Loading branch information
bors[bot] and zerbina authored Mar 14, 2022
2 parents 0e541ed + 53bc61e commit ce383f5
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 145 deletions.
10 changes: 5 additions & 5 deletions compiler/sem/macrocacheimpl.nim
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,32 @@ import
]


proc append(c: PCtx; n: PNode) =
func append(c: var TCtx; n: PNode) =
c.vmstateDiff.add((c.module, n))

proc recordInc*(c: PCtx; info: TLineInfo; key: string; by: BiggestInt) =
proc recordInc*(c: var TCtx; info: TLineInfo; key: string; by: BiggestInt) =
var recorded = newNodeI(nkReplayAction, info)
recorded.add newStrNode("inc", info)
recorded.add newStrNode(key, info)
recorded.add newIntNode(nkIntLit, by)
c.append(recorded)

proc recordPut*(c: PCtx; info: TLineInfo; key: string; k: string; val: PNode) =
proc recordPut*(c: var TCtx; info: TLineInfo; key: string; k: string; val: PNode) =
var recorded = newNodeI(nkReplayAction, info)
recorded.add newStrNode("put", info)
recorded.add newStrNode(key, info)
recorded.add newStrNode(k, info)
recorded.add copyTree(val)
c.append(recorded)

proc recordAdd*(c: PCtx; info: TLineInfo; key: string; val: PNode) =
proc recordAdd*(c: var TCtx; info: TLineInfo; key: string; val: PNode) =
var recorded = newNodeI(nkReplayAction, info)
recorded.add newStrNode("add", info)
recorded.add newStrNode(key, info)
recorded.add copyTree(val)
c.append(recorded)

proc recordIncl*(c: PCtx; info: TLineInfo; key: string; val: PNode) =
proc recordIncl*(c: var TCtx; info: TLineInfo; key: string; val: PNode) =
var recorded = newNodeI(nkReplayAction, info)
recorded.add newStrNode("incl", info)
recorded.add newStrNode(key, info)
Expand Down
9 changes: 6 additions & 3 deletions compiler/vm/nimeval.nim
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,17 @@ proc selectRoutine*(i: Interpreter; name: string): PSym =

proc callRoutine*(i: Interpreter; routine: PSym; args: openArray[PNode]): PNode =
assert i != nil
result = vm.execProc(PCtx i.graph.vm, routine, args)
let c = PCtx(i.graph.vm)
result = vm.execProc(c[], routine, args)

proc getGlobalValue*(i: Interpreter; letOrVar: PSym): PNode =
result = vm.getGlobalValue(PCtx i.graph.vm, letOrVar)
let c = PCtx(i.graph.vm)
result = vm.getGlobalValue(c[], letOrVar)

proc setGlobalValue*(i: Interpreter; letOrVar: PSym, val: PNode) =
## Sets a global value to a given PNode, does not do any type checking.
vm.setGlobalValue(PCtx i.graph.vm, letOrVar, val)
let c = PCtx(i.graph.vm)
vm.setGlobalValue(c[], letOrVar, val)

proc implementRoutine*(i: Interpreter; pkg, module, name: string;
impl: proc (a: VmArgs) {.closure, gcsafe.}) =
Expand Down
55 changes: 28 additions & 27 deletions compiler/vm/vm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,15 @@ const
errIllegalConvFromXtoY = "illegal conversion from '$1' to '$2'"

proc stackTraceImpl(
c: PCtx,
c: TCtx,
sframe: PStackFrame,
pc: int,
lineInfo: TLineInfo,
infoOrigin: InstantiationInfo,
recursionLimit: int = 100
) =

proc aux(sframe: PStackFrame, pc, depth: int, res: var SemReport) =
proc aux(c: TCtx, sframe: PStackFrame, pc, depth: int, res: var SemReport) =
if sframe != nil:
if recursionLimit < depth:
var calls = 0
Expand All @@ -91,14 +91,14 @@ proc stackTraceImpl(

return

aux(sframe.next, sframe.comesFrom, depth + 1, res)
aux(c, sframe.next, sframe.comesFrom, depth + 1, res)
res.stacktrace.add((sym: sframe.prc, location: c.debug[pc]))

var res = SemReport(kind: rsemVmStackTrace)
res.currentExceptionA = c.currentExceptionA
res.currentExceptionB = c.currentExceptionB

aux(sframe, pc, 0, res)
aux(c, sframe, pc, 0, res)

let action = if c.mode == emRepl: doRaise else: doNothing

Expand All @@ -108,7 +108,7 @@ proc stackTraceImpl(


template stackTrace(
c: PCtx,
c: TCtx,
tos: PStackFrame,
pc: int,
sem: ReportTypes,
Expand All @@ -119,7 +119,7 @@ template stackTrace(
return

template stackTrace(
c: PCtx,
c: TCtx,
tos: PStackFrame,
pc: int,
sem: ReportTypes,
Expand All @@ -128,7 +128,7 @@ template stackTrace(
localReport(c.config, c.debug[pc], sem)
return

proc reportException(c: PCtx; tos: PStackFrame, raised: PNode) =
proc reportException(c: TCtx; tos: PStackFrame, raised: PNode) =
# REFACTOR VM implementation relies on the `stackTrace` calling return,
# but in this proc we are retuning only from it's body, so calling
# `reportException()` does not stop vm loops. This needs to be cleaned up
Expand Down Expand Up @@ -340,7 +340,7 @@ type
ExceptionGotoFinally,
ExceptionGotoUnhandled

proc findExceptionHandler(c: PCtx, f: PStackFrame, exc: PNode):
proc findExceptionHandler(c: TCtx, f: PStackFrame, exc: PNode):
tuple[why: ExceptionGoto, where: int] =
let raisedType = exc.typ.skipTypes(abstractPtrs)

Expand Down Expand Up @@ -411,7 +411,7 @@ proc findExceptionHandler(c: PCtx, f: PStackFrame, exc: PNode):

return (ExceptionGotoUnhandled, 0)

proc cleanUpOnReturn(c: PCtx; f: PStackFrame): int =
proc cleanUpOnReturn(c: TCtx; f: PStackFrame): int =
# Walk up the chain of safepoints and return the PC of the first `finally`
# block we find or -1 if no such block is found.
# Note that the safepoint is removed once the function returns!
Expand All @@ -428,7 +428,7 @@ proc cleanUpOnReturn(c: PCtx; f: PStackFrame): int =
discard f.safePoints.pop
return pc + 1

proc opConv(c: PCtx; dest: var TFullReg, src: TFullReg, desttyp, srctyp: PType): bool =
proc opConv(c: TCtx; dest: var TFullReg, src: TFullReg, desttyp, srctyp: PType): bool =
if desttyp.kind == tyString:
dest.ensureKind(rkNode)
dest.node = newNode(nkStrLit)
Expand Down Expand Up @@ -518,7 +518,7 @@ proc opConv(c: PCtx; dest: var TFullReg, src: TFullReg, desttyp, srctyp: PType):
else:
asgnComplex(dest, src)

proc compile(c: PCtx, s: PSym): int =
proc compile(c: var TCtx, s: PSym): int =
result = vmgen.genProc(c, s)
when debugEchoCode:
c.codeListing(s, nil, start = result)
Expand All @@ -540,7 +540,7 @@ proc recSetFlagIsRef(arg: PNode) =
for i in 0..<arg.safeLen:
arg[i].recSetFlagIsRef

proc setLenSeq(c: PCtx; node: PNode; newLen: int; info: TLineInfo) =
proc setLenSeq(c: TCtx; node: PNode; newLen: int; info: TLineInfo) =
let typ = node.typ.skipTypes(abstractInst+{tyRange}-{tyTypeDesc})
let oldLen = node.len
setLen(node.sons, newLen)
Expand Down Expand Up @@ -572,7 +572,7 @@ template takeAddress(reg, source) =
when defined(gcDestructors):
GC_ref source

proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
proc rawExecute(c: var TCtx, start: int, tos: PStackFrame): TFullReg =
var pc = start
var tos = tos
# Used to keep track of where the execution is resumed.
Expand Down Expand Up @@ -2321,12 +2321,12 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =

inc pc

proc execute(c: PCtx, start: int): PNode =
proc execute(c: var TCtx, start: int): PNode =
var tos = PStackFrame(prc: nil, comesFrom: 0, next: nil)
newSeq(tos.slots, c.prc.regInfo.len)
result = rawExecute(c, start, tos).regToNode

proc execProc*(c: PCtx; sym: PSym; args: openArray[PNode]): PNode =
proc execProc*(c: var TCtx; sym: PSym; args: openArray[PNode]): PNode =
c.loopIterations = c.config.maxLoopIterationsVM
if sym.kind in routineKinds:
if sym.typ.len-1 != args.len:
Expand Down Expand Up @@ -2355,15 +2355,15 @@ proc execProc*(c: PCtx; sym: PSym; args: openArray[PNode]): PNode =
else:
localReport(c.config, sym.info, reportSym(rsemVmCallingNonRoutine, sym))

proc evalStmt*(c: PCtx, n: PNode) =
proc evalStmt*(c: var TCtx, n: PNode) =
let n = transformExpr(c.graph, c.idgen, c.module, n)
let start = genStmt(c, n)
# execute new instructions; this redundant opcEof check saves us lots
# of allocations in 'execute':
if c.code[start].opcode != opcEof:
discard execute(c, start)

proc evalExpr*(c: PCtx, n: PNode): PNode =
proc evalExpr*(c: var TCtx, n: PNode): PNode =
# deadcode
# `nim --eval:"expr"` might've used it at some point for idetools; could
# be revived for nimsuggest
Expand All @@ -2372,11 +2372,11 @@ proc evalExpr*(c: PCtx, n: PNode): PNode =
assert c.code[start].opcode != opcEof
result = execute(c, start)

proc getGlobalValue*(c: PCtx; s: PSym): PNode =
proc getGlobalValue*(c: TCtx; s: PSym): PNode =
internalAssert(c.config, s.kind in {skLet, skVar} and sfGlobal in s.flags)
result = c.globals[s.position-1]

proc setGlobalValue*(c: PCtx; s: PSym, val: PNode) =
proc setGlobalValue*(c: var TCtx; s: PSym, val: PNode) =
## Does not do type checking so ensure the `val` matches the `s.typ`
internalAssert(c.config, s.kind in {skLet, skVar} and sfGlobal in s.flags)
c.globals[s.position-1] = val
Expand All @@ -2389,7 +2389,8 @@ proc setupGlobalCtx*(module: PSym; graph: ModuleGraph; idgen: IdGenerator) =
graph.vm = newCtx(module, graph.cache, graph, idgen)
registerAdditionalOps(PCtx graph.vm)
else:
refresh(PCtx graph.vm, module, idgen)
let c = PCtx(graph.vm)
refresh(c[], module, idgen)

proc myOpen(graph: ModuleGraph; module: PSym; idgen: IdGenerator): PPassContext {.nosinks.} =
#var c = newEvalContext(module, emRepl)
Expand All @@ -2404,7 +2405,7 @@ proc myProcess(c: PPassContext, n: PNode): PNode =
let c = PCtx(c)
# don't eval errornous code:
if c.oldErrorCount == c.config.errorCounter:
evalStmt(c, n)
evalStmt(c[], n)
result = newNodeI(nkEmpty, n.info)
else:
result = n
Expand All @@ -2422,10 +2423,10 @@ proc evalConstExprAux(module: PSym; idgen: IdGenerator;
#if g.config.errorCounter > 0: return n
let n = transformExpr(g, idgen, module, n)
setupGlobalCtx(module, g, idgen)
var c = PCtx g.vm
let c = PCtx g.vm
let oldMode = c.mode
c.mode = mode
let start = genExpr(c, n, requiresValue = mode!=emStaticStmt)
let start = genExpr(c[], n, requiresValue = mode!=emStaticStmt)
if c.code[start].opcode == opcEof: return newNodeI(nkEmpty, n.info)
assert c.code[start].opcode != opcEof
when debugEchoCode:
Expand All @@ -2434,7 +2435,7 @@ proc evalConstExprAux(module: PSym; idgen: IdGenerator;
var tos = PStackFrame(prc: prc, comesFrom: 0, next: nil)
newSeq(tos.slots, c.prc.regInfo.len)
#for i in 0..<c.prc.regInfo.len: tos.slots[i] = newNode(nkEmpty)
result = rawExecute(c, start, tos).regToNode
result = rawExecute(c[], start, tos).regToNode
if result.info.col < 0: result.info = n.info
c.mode = oldMode

Expand Down Expand Up @@ -2523,13 +2524,13 @@ proc evalMacroCall*(module: PSym; idgen: IdGenerator; g: ModuleGraph; templInstC
got: toInt128(n.safeLen - 1))))

setupGlobalCtx(module, g, idgen)
var c = PCtx g.vm
let c = PCtx g.vm
let oldMode = c.mode
c.mode = emStaticStmt
c.comesFromHeuristic.line = 0'u16
c.callsite = n
c.templInstCounter = templInstCounter
let start = genProc(c, sym)
let start = genProc(c[], sym)

var tos = PStackFrame(prc: sym, comesFrom: 0, next: nil)
let maxSlots = sym.offset
Expand Down Expand Up @@ -2564,7 +2565,7 @@ proc evalMacroCall*(module: PSym; idgen: IdGenerator; g: ModuleGraph; templInstC

# temporary storage:
#for i in L..<maxSlots: tos.slots[i] = newNode(nkEmpty)
result = rawExecute(c, start, tos).regToNode
result = rawExecute(c[], start, tos).regToNode
if result.info.line < 0: result.info = n.info
if cyclicTree(result):
globalReport(c.config, n.info, reportAst(rsemCyclicTree, n, sym = sym))
Expand Down
9 changes: 7 additions & 2 deletions compiler/vm/vmdef.nim
Original file line number Diff line number Diff line change
Expand Up @@ -189,17 +189,22 @@ proc newCtx*(module: PSym; cache: IdentCache; g: ModuleGraph; idgen: IdGenerator
idgen: idgen
)

proc refresh*(c: PCtx, module: PSym; idgen: IdGenerator) =
func refresh*(c: var TCtx, module: PSym; idgen: IdGenerator) =
addInNimDebugUtils(c.config, "refresh")
c.module = module
c.prc = PProc(blocks: @[])
c.loopIterations = c.config.maxLoopIterationsVM
c.idgen = idgen

proc registerCallback*(c: PCtx; name: string; callback: VmCallback): int {.discardable.} =
proc registerCallback*(c: var TCtx; name: string; callback: VmCallback): int {.discardable.} =
result = c.callbacks.len
c.callbacks.add((name, callback))

template registerCallback*(c: PCtx; name: string; callback: VmCallback): int {.deprecated.} =
## A transition helper. Use the `registerCallback` proc that takes
## `var TCtx` instead
registerCallback(c[], name, callback)

const
slotSomeTemp* = slotTempUnknown

Expand Down
Loading

0 comments on commit ce383f5

Please sign in to comment.