staticExec now supports caching

This commit is contained in:
Araq 2015-07-15 21:36:44 +02:00
commit 728fc441ef
4 changed files with 59 additions and 15 deletions

View file

@ -1168,9 +1168,12 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
c.module) c.module)
of opcGorge: of opcGorge:
decodeBC(rkNode) decodeBC(rkNode)
inc pc
let rd = c.code[pc].regA
createStr regs[ra] createStr regs[ra]
regs[ra].node.strVal = opGorge(regs[rb].node.strVal, regs[ra].node.strVal = opGorge(regs[rb].node.strVal,
regs[rc].node.strVal) regs[rc].node.strVal, regs[rd].node.strVal)
of opcNError: of opcNError:
stackTrace(c, tos, pc, errUser, regs[ra].node.strVal) stackTrace(c, tos, pc, errUser, regs[ra].node.strVal)
of opcNWarning: of opcNWarning:

View file

@ -7,7 +7,7 @@
# distribution, for details about the copyright. # distribution, for details about the copyright.
# #
import ast, types, msgs, osproc, streams, options, idents import ast, types, msgs, osproc, streams, options, idents, securehash
proc readOutput(p: Process): string = proc readOutput(p: Process): string =
result = "" result = ""
@ -19,7 +19,27 @@ proc readOutput(p: Process): string =
result.setLen(result.len - "\n".len) result.setLen(result.len - "\n".len)
discard p.waitForExit discard p.waitForExit
proc opGorge*(cmd, input: string): string = proc opGorge*(cmd, input, cache: string): string =
if cache.len > 0:# and optForceFullMake notin gGlobalOptions:
let h = secureHash(cmd & "\t" & input & "\t" & cache)
let filename = options.toGeneratedFile("gorge_" & $h, "txt")
var f: File
if open(f, filename):
result = f.readAll
f.close
return
var readSuccessful = false
try:
var p = startProcess(cmd, options={poEvalCommand})
if input.len != 0:
p.inputStream.write(input)
p.inputStream.close()
result = p.readOutput
readSuccessful = true
writeFile(filename, result)
except IOError, OSError:
if not readSuccessful: result = ""
else:
try: try:
var p = startProcess(cmd, options={poEvalCommand}) var p = startProcess(cmd, options={poEvalCommand})
if input.len != 0: if input.len != 0:

View file

@ -599,6 +599,18 @@ proc genBinaryABC(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
c.freeTemp(tmp) c.freeTemp(tmp)
c.freeTemp(tmp2) c.freeTemp(tmp2)
proc genBinaryABCD(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
let
tmp = c.genx(n.sons[1])
tmp2 = c.genx(n.sons[2])
tmp3 = c.genx(n.sons[3])
if dest < 0: dest = c.getTemp(n.typ)
c.gABC(n, opc, dest, tmp, tmp2)
c.gABC(n, opc, tmp3)
c.freeTemp(tmp)
c.freeTemp(tmp2)
c.freeTemp(tmp3)
proc genNarrow(c: PCtx; n: PNode; dest: TDest) = proc genNarrow(c: PCtx; n: PNode; dest: TDest) =
let t = skipTypes(n.typ, abstractVar-{tyTypeDesc}) let t = skipTypes(n.typ, abstractVar-{tyTypeDesc})
# uint is uint64 in the VM, we we only need to mask the result for # uint is uint64 in the VM, we we only need to mask the result for
@ -932,7 +944,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
c.gABC(n, opcTypeTrait, dest, tmp) c.gABC(n, opcTypeTrait, dest, tmp)
c.freeTemp(tmp) c.freeTemp(tmp)
of mSlurp: genUnaryABC(c, n, dest, opcSlurp) of mSlurp: genUnaryABC(c, n, dest, opcSlurp)
of mStaticExec: genBinaryABC(c, n, dest, opcGorge) of mStaticExec: genBinaryABCD(c, n, dest, opcGorge)
of mNLen: genUnaryABI(c, n, dest, opcLenSeq) of mNLen: genUnaryABI(c, n, dest, opcLenSeq)
of mNChild: genBinaryABC(c, n, dest, opcNChild) of mNChild: genBinaryABC(c, n, dest, opcNChild)
of mNSetChild, mNDel: of mNSetChild, mNDel:

View file

@ -3091,11 +3091,11 @@ proc staticRead*(filename: string): string {.magic: "Slurp".}
## ##
## `slurp <#slurp>`_ is an alias for ``staticRead``. ## `slurp <#slurp>`_ is an alias for ``staticRead``.
proc gorge*(command: string, input = ""): string {. proc gorge*(command: string, input = "", cache = ""): string {.
magic: "StaticExec".} = discard magic: "StaticExec".} = discard
## This is an alias for `staticExec <#staticExec>`_. ## This is an alias for `staticExec <#staticExec>`_.
proc staticExec*(command: string, input = ""): string {. proc staticExec*(command: string, input = "", cache = ""): string {.
magic: "StaticExec".} = discard magic: "StaticExec".} = discard
## Executes an external process at compile-time. ## Executes an external process at compile-time.
## if `input` is not an empty string, it will be passed as a standard input ## if `input` is not an empty string, it will be passed as a standard input
@ -3108,6 +3108,15 @@ proc staticExec*(command: string, input = ""): string {.
## `gorge <#gorge>`_ is an alias for ``staticExec``. Note that you can use ## `gorge <#gorge>`_ is an alias for ``staticExec``. Note that you can use
## this proc inside a pragma like `passC <nimc.html#passc-pragma>`_ or `passL ## this proc inside a pragma like `passC <nimc.html#passc-pragma>`_ or `passL
## <nimc.html#passl-pragma>`_. ## <nimc.html#passl-pragma>`_.
##
## If ``cache`` is not empty, the results of ``staticExec`` are cached within
## the ``nimcache`` directory. Use ``--forceBuild`` to get rid of this caching
## behaviour then. ``command & input & cache`` (the concatenated string) is
## used to determine wether the entry in the cache is still valid. You can
## use versioning information for ``cache``:
##
## .. code-block:: nim
## const stateMachine = staticExec("dfaoptimizer", "input", "0.8.0")
proc `+=`*[T: SomeOrdinal|uint|uint64](x: var T, y: T) {.magic: "Inc", noSideEffect.} proc `+=`*[T: SomeOrdinal|uint|uint64](x: var T, y: T) {.magic: "Inc", noSideEffect.}
## Increments an ordinal ## Increments an ordinal