diff options
-rw-r--r-- | compiler/vm.nim | 5 | ||||
-rw-r--r-- | compiler/vmdeps.nim | 40 | ||||
-rw-r--r-- | compiler/vmgen.nim | 14 | ||||
-rw-r--r-- | lib/system.nim | 15 |
4 files changed, 59 insertions, 15 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim index 6d496d6e1..40d273ceb 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1168,9 +1168,12 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = c.module) of opcGorge: decodeBC(rkNode) + inc pc + let rd = c.code[pc].regA + createStr regs[ra] regs[ra].node.strVal = opGorge(regs[rb].node.strVal, - regs[rc].node.strVal) + regs[rc].node.strVal, regs[rd].node.strVal) of opcNError: stackTrace(c, tos, pc, errUser, regs[ra].node.strVal) of opcNWarning: diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index 88bb7ae24..73016108d 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -7,7 +7,7 @@ # 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 = result = "" @@ -19,15 +19,35 @@ proc readOutput(p: Process): string = result.setLen(result.len - "\n".len) discard p.waitForExit -proc opGorge*(cmd, input: string): string = - try: - var p = startProcess(cmd, options={poEvalCommand}) - if input.len != 0: - p.inputStream.write(input) - p.inputStream.close() - result = p.readOutput - except IOError, OSError: - result = "" +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: + var p = startProcess(cmd, options={poEvalCommand}) + if input.len != 0: + p.inputStream.write(input) + p.inputStream.close() + result = p.readOutput + except IOError, OSError: + result = "" proc opSlurp*(file: string, info: TLineInfo, module: PSym): string = try: diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 004adedb9..7abcbdb92 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -599,6 +599,18 @@ proc genBinaryABC(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) = c.freeTemp(tmp) 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) = let t = skipTypes(n.typ, abstractVar-{tyTypeDesc}) # 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.freeTemp(tmp) 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 mNChild: genBinaryABC(c, n, dest, opcNChild) of mNSetChild, mNDel: diff --git a/lib/system.nim b/lib/system.nim index 27338b3b4..f8a4f7fcf 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -3091,11 +3091,11 @@ proc staticRead*(filename: string): string {.magic: "Slurp".} ## ## `slurp <#slurp>`_ is an alias for ``staticRead``. -proc gorge*(command: string, input = ""): string {. +proc gorge*(command: string, input = "", cache = ""): string {. magic: "StaticExec".} = discard ## This is an alias for `staticExec <#staticExec>`_. -proc staticExec*(command: string, input = ""): string {. +proc staticExec*(command: string, input = "", cache = ""): string {. magic: "StaticExec".} = discard ## Executes an external process at compile-time. ## 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 ## this proc inside a pragma like `passC <nimc.html#passc-pragma>`_ or `passL ## <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.} ## Increments an ordinal @@ -3329,7 +3338,7 @@ when declared(initDebugger): when hasAlloc: # XXX: make these the default (or implement the NilObject optimization) proc safeAdd*[T](x: var seq[T], y: T) {.noSideEffect.} = - ## Adds ``y`` to ``x`` unless ``x`` is not yet initialized; in that case, + ## Adds ``y`` to ``x`` unless ``x`` is not yet initialized; in that case, ## ``x`` becomes ``@[y]`` if x == nil: x = @[y] else: x.add(y) |