* fixes #14409; fixes#10674 VM callbacks switch to table-index seqs * fixes package name * reduce runtime cost
This commit is contained in:
parent
fc068ee06d
commit
4647c7b596
5 changed files with 37 additions and 23 deletions
|
|
@ -1351,7 +1351,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
let prc = if not isClosure: bb.sym else: bb[0].sym
|
let prc = if not isClosure: bb.sym else: bb[0].sym
|
||||||
if prc.offset < -1:
|
if prc.offset < -1:
|
||||||
# it's a callback:
|
# it's a callback:
|
||||||
c.callbacks[-prc.offset-2].value(
|
c.callbacks[-prc.offset-2](
|
||||||
VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[ptr UncheckedArray[TFullReg]](addr regs[0]),
|
VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[ptr UncheckedArray[TFullReg]](addr regs[0]),
|
||||||
currentException: c.currentExceptionA,
|
currentException: c.currentExceptionA,
|
||||||
currentLineInfo: c.debug[pc])
|
currentLineInfo: c.debug[pc])
|
||||||
|
|
@ -1674,7 +1674,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
rb = instr.regB
|
rb = instr.regB
|
||||||
rc = instr.regC
|
rc = instr.regC
|
||||||
idx = int(regs[rb+rc-1].intVal)
|
idx = int(regs[rb+rc-1].intVal)
|
||||||
callback = c.callbacks[idx].value
|
callback = c.callbacks[idx]
|
||||||
args = VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[ptr UncheckedArray[TFullReg]](addr regs[0]),
|
args = VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[ptr UncheckedArray[TFullReg]](addr regs[0]),
|
||||||
currentException: c.currentExceptionA,
|
currentException: c.currentExceptionA,
|
||||||
currentLineInfo: c.debug[pc])
|
currentLineInfo: c.debug[pc])
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## This module contains the type definitions for the new evaluation engine.
|
## This module contains the type definitions for the new evaluation engine.
|
||||||
## An instruction is 1-3 int32s in memory, it is a register based VM.
|
## An instruction is 1-3 int32s in memory, it is a register based VM.
|
||||||
|
|
||||||
import tables
|
import std/[tables, strutils]
|
||||||
|
|
||||||
import ast, idents, options, modulegraphs, lineinfos
|
import ast, idents, options, modulegraphs, lineinfos
|
||||||
|
|
||||||
|
|
@ -259,7 +259,8 @@ type
|
||||||
traceActive*: bool
|
traceActive*: bool
|
||||||
loopIterations*: int
|
loopIterations*: int
|
||||||
comesFromHeuristic*: TLineInfo # Heuristic for better macro stack traces
|
comesFromHeuristic*: TLineInfo # Heuristic for better macro stack traces
|
||||||
callbacks*: seq[tuple[key: string, value: VmCallback]]
|
callbacks*: seq[VmCallback]
|
||||||
|
callbackIndex*: Table[string, int]
|
||||||
errorFlag*: string
|
errorFlag*: string
|
||||||
cache*: IdentCache
|
cache*: IdentCache
|
||||||
config*: ConfigRef
|
config*: ConfigRef
|
||||||
|
|
@ -292,7 +293,7 @@ proc newCtx*(module: PSym; cache: IdentCache; g: ModuleGraph; idgen: IdGenerator
|
||||||
PCtx(code: @[], debug: @[],
|
PCtx(code: @[], debug: @[],
|
||||||
globals: newNode(nkStmtListExpr), constants: newNode(nkStmtList), types: @[],
|
globals: newNode(nkStmtListExpr), constants: newNode(nkStmtList), types: @[],
|
||||||
prc: PProc(blocks: @[]), module: module, loopIterations: g.config.maxLoopIterationsVM,
|
prc: PProc(blocks: @[]), module: module, loopIterations: g.config.maxLoopIterationsVM,
|
||||||
comesFromHeuristic: unknownLineInfo, callbacks: @[], errorFlag: "",
|
comesFromHeuristic: unknownLineInfo, callbacks: @[], callbackIndex: initTable[string, int](), errorFlag: "",
|
||||||
cache: cache, config: g.config, graph: g, idgen: idgen)
|
cache: cache, config: g.config, graph: g, idgen: idgen)
|
||||||
|
|
||||||
proc refresh*(c: PCtx, module: PSym; idgen: IdGenerator) =
|
proc refresh*(c: PCtx, module: PSym; idgen: IdGenerator) =
|
||||||
|
|
@ -301,9 +302,18 @@ proc refresh*(c: PCtx, module: PSym; idgen: IdGenerator) =
|
||||||
c.loopIterations = c.config.maxLoopIterationsVM
|
c.loopIterations = c.config.maxLoopIterationsVM
|
||||||
c.idgen = idgen
|
c.idgen = idgen
|
||||||
|
|
||||||
|
proc reverseName(s: string): string =
|
||||||
|
result = newStringOfCap(s.len)
|
||||||
|
let y = s.split('.')
|
||||||
|
for i in 1..y.len:
|
||||||
|
result.add y[^i]
|
||||||
|
if i != y.len:
|
||||||
|
result.add '.'
|
||||||
|
|
||||||
proc registerCallback*(c: PCtx; name: string; callback: VmCallback): int {.discardable.} =
|
proc registerCallback*(c: PCtx; name: string; callback: VmCallback): int {.discardable.} =
|
||||||
result = c.callbacks.len
|
result = c.callbacks.len
|
||||||
c.callbacks.add((name, callback))
|
c.callbacks.add(callback)
|
||||||
|
c.callbackIndex[reverseName(name)] = result
|
||||||
|
|
||||||
const
|
const
|
||||||
firstABxInstr* = opcTJmp
|
firstABxInstr* = opcTJmp
|
||||||
|
|
|
||||||
|
|
@ -2011,25 +2011,29 @@ proc genTupleConstr(c: PCtx, n: PNode, dest: var TDest) =
|
||||||
|
|
||||||
proc genProc*(c: PCtx; s: PSym): int
|
proc genProc*(c: PCtx; s: PSym): int
|
||||||
|
|
||||||
proc matches(s: PSym; x: string): bool =
|
proc toKey(s: PSym): string =
|
||||||
let y = x.split('.')
|
|
||||||
var s = s
|
var s = s
|
||||||
for i in 1..y.len:
|
while s != nil:
|
||||||
if s == nil or (y[^i].cmpIgnoreStyle(s.name.s) != 0 and y[^i] != "*"):
|
result.add s.name.s
|
||||||
return false
|
if s.owner != nil:
|
||||||
s = if sfFromGeneric in s.flags: s.owner.owner else: s.owner
|
if sfFromGeneric in s.flags:
|
||||||
while s != nil and s.kind == skPackage and s.owner != nil: s = s.owner
|
s = s.owner.owner
|
||||||
result = true
|
else:
|
||||||
|
s = s.owner
|
||||||
|
result.add "."
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
proc procIsCallback(c: PCtx; s: PSym): bool =
|
proc procIsCallback(c: PCtx; s: PSym): bool =
|
||||||
if s.offset < -1: return true
|
if s.offset < -1: return true
|
||||||
var i = -2
|
let key = toKey(s)
|
||||||
for key, value in items(c.callbacks):
|
if c.callbackIndex.contains(key):
|
||||||
if s.matches(key):
|
let index = c.callbackIndex[key]
|
||||||
doAssert s.offset == -1
|
doAssert s.offset == -1
|
||||||
s.offset = i
|
s.offset = -2 - index
|
||||||
return true
|
result = true
|
||||||
dec i
|
else:
|
||||||
|
result = false
|
||||||
|
|
||||||
proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
|
proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
|
||||||
when defined(nimCompilerStacktraceHints):
|
when defined(nimCompilerStacktraceHints):
|
||||||
|
|
|
||||||
|
|
@ -256,7 +256,7 @@ proc registerAdditionalOps*(c: PCtx) =
|
||||||
wrap2si(readLines, ioop)
|
wrap2si(readLines, ioop)
|
||||||
systemop getCurrentExceptionMsg
|
systemop getCurrentExceptionMsg
|
||||||
systemop getCurrentException
|
systemop getCurrentException
|
||||||
registerCallback c, "stdlib.*.staticWalkDir", proc (a: VmArgs) {.nimcall.} =
|
registerCallback c, "stdlib.osdirs.staticWalkDir", proc (a: VmArgs) {.nimcall.} =
|
||||||
setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1)))
|
setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1)))
|
||||||
registerCallback c, "stdlib.compilesettings.querySetting", proc (a: VmArgs) =
|
registerCallback c, "stdlib.compilesettings.querySetting", proc (a: VmArgs) =
|
||||||
setResult(a, querySettingImpl(c.config, getInt(a, 0)))
|
setResult(a, querySettingImpl(c.config, getInt(a, 0)))
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ proc initInterpreter(script: string): Interpreter =
|
||||||
|
|
||||||
proc main() =
|
proc main() =
|
||||||
let i = initInterpreter("myscript.nim")
|
let i = initInterpreter("myscript.nim")
|
||||||
i.implementRoutine("*", "exposed", "addFloats", proc (a: VmArgs) =
|
i.implementRoutine("nim", "exposed", "addFloats", proc (a: VmArgs) =
|
||||||
setResult(a, getFloat(a, 0) + getFloat(a, 1) + getFloat(a, 2))
|
setResult(a, getFloat(a, 0) + getFloat(a, 1) + getFloat(a, 2))
|
||||||
)
|
)
|
||||||
i.evalScript()
|
i.evalScript()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue