diff options
-rw-r--r-- | compiler/vm.nim | 5 | ||||
-rw-r--r-- | compiler/vmdef.nim | 1 | ||||
-rw-r--r-- | compiler/vmdeps.nim | 24 | ||||
-rw-r--r-- | compiler/vmops.nim | 6 | ||||
-rw-r--r-- | lib/system.nim | 5 | ||||
-rw-r--r-- | tests/vm/tgorge.nim | 20 | ||||
-rw-r--r-- | tests/vm/tgorgeex.bat | 2 | ||||
-rw-r--r-- | tests/vm/tgorgeex.sh | 3 |
8 files changed, 46 insertions, 20 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim index 1bb440c6c..91fe3d209 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -879,7 +879,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = # it's a callback: c.callbacks[-prc.offset-2].value( VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[pointer](regs), - currentException: c.currentExceptionB)) + currentException: c.currentExceptionB, + currentLineInfo: c.debug[pc])) elif sfImportc in prc.flags: if allowFFI notin c.features: globalError(c.debug[pc], errGenerated, "VM not allowed to do FFI") @@ -1246,7 +1247,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = createStr regs[ra] regs[ra].node.strVal = opGorge(regs[rb].node.strVal, regs[rc].node.strVal, regs[rd].node.strVal, - c.debug[pc]) + c.debug[pc])[0] of opcNError: decodeB(rkNode) let a = regs[ra].node diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim index 7fb35e890..263ec8378 100644 --- a/compiler/vmdef.nim +++ b/compiler/vmdef.nim @@ -181,6 +181,7 @@ type ra*, rb*, rc*: Natural slots*: pointer currentException*: PNode + currentLineInfo*: TLineInfo VmCallback* = proc (args: VmArgs) {.closure.} PCtx* = ref TCtx diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index bda2710dc..ebd2f557f 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -9,24 +9,24 @@ import ast, types, msgs, os, osproc, streams, options, idents, securehash -proc readOutput(p: Process): string = - result = "" +proc readOutput(p: Process): (string, int) = + result[0] = "" var output = p.outputStream while not output.atEnd: - result.add(output.readLine) - result.add("\n") - if result.len > 0: - result.setLen(result.len - "\n".len) - discard p.waitForExit + result[0].add(output.readLine) + result[0].add("\n") + if result[0].len > 0: + result[0].setLen(result[0].len - "\n".len) + result[1] = p.waitForExit -proc opGorge*(cmd, input, cache: string, info: TLineInfo): string = +proc opGorge*(cmd, input, cache: string, info: TLineInfo): (string, int) = let workingDir = parentDir(info.toFullPath) 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 + result = (f.readAll, 0) f.close return var readSuccessful = false @@ -38,9 +38,9 @@ proc opGorge*(cmd, input, cache: string, info: TLineInfo): string = p.inputStream.close() result = p.readOutput readSuccessful = true - writeFile(filename, result) + writeFile(filename, result[0]) except IOError, OSError: - if not readSuccessful: result = "" + if not readSuccessful: result = ("", -1) else: try: var p = startProcess(cmd, workingDir, @@ -50,7 +50,7 @@ proc opGorge*(cmd, input, cache: string, info: TLineInfo): string = p.inputStream.close() result = p.readOutput except IOError, OSError: - result = "" + result = ("", -1) proc opSlurp*(file: string, info: TLineInfo, module: PSym): string = try: diff --git a/compiler/vmops.nim b/compiler/vmops.nim index 1c2725a98..b0911579e 100644 --- a/compiler/vmops.nim +++ b/compiler/vmops.nim @@ -59,6 +59,11 @@ proc staticWalkDirImpl(path: string, relative: bool): PNode = result.add newTree(nkPar, newIntNode(nkIntLit, k.ord), newStrNode(nkStrLit, f)) +proc gorgeExWrapper(a: VmArgs) {.nimcall.} = + let (s, e) = opGorge(getString(a, 0), getString(a, 1), getString(a, 2), + a.currentLineInfo) + setResult a, newTree(nkPar, newStrNode(nkStrLit, s), newIntNode(nkIntLit, e)) + proc registerAdditionalOps*(c: PCtx) = wrap1f_math(sqrt) wrap1f_math(ln) @@ -92,3 +97,4 @@ proc registerAdditionalOps*(c: PCtx) = systemop getCurrentExceptionMsg registerCallback c, "stdlib.*.staticWalkDir", proc (a: VmArgs) {.nimcall.} = setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1))) + systemop gorgeEx diff --git a/lib/system.nim b/lib/system.nim index 309df7f84..83dc20869 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -3368,6 +3368,11 @@ proc staticExec*(command: string, input = "", cache = ""): string {. ## .. code-block:: nim ## const stateMachine = staticExec("dfaoptimizer", "input", "0.8.0") +proc gorgeEx*(command: string, input = "", cache = ""): tuple[output: string, + exitCode: int] = + ## Same as `gorge` but also returns the precious exit code. + discard + proc `+=`*[T: SomeOrdinal|uint|uint64](x: var T, y: T) {. magic: "Inc", noSideEffect.} ## Increments an ordinal diff --git a/tests/vm/tgorge.nim b/tests/vm/tgorge.nim index 596f5d667..694754f41 100644 --- a/tests/vm/tgorge.nim +++ b/tests/vm/tgorge.nim @@ -3,10 +3,18 @@ import os template getScriptDir(): string = parentDir(instantiationInfo(-1, true).filename) -const - execName = when defined(windows): "tgorge.bat" else: "sh tgorge.sh" - relOutput = gorge(execName) - absOutput = gorge(getScriptDir() / execName) +block gorge: + const + execName = when defined(windows): "tgorge.bat" else: "./tgorge.sh" + relOutput = gorge(execName) + absOutput = gorge(getScriptDir() / execName) -doAssert relOutput == "gorge test" -doAssert absOutput == "gorge test" + doAssert relOutput == "gorge test" + doAssert absOutput == "gorge test" + +block gorgeEx: + const + execName = when defined(windows): "tgorgeex.bat" else: "./tgorgeex.sh" + res = gorgeEx(execName) + doAssert res.output == "gorgeex test" + doAssert res.exitCode == 1 diff --git a/tests/vm/tgorgeex.bat b/tests/vm/tgorgeex.bat new file mode 100644 index 000000000..57f11fdd1 --- /dev/null +++ b/tests/vm/tgorgeex.bat @@ -0,0 +1,2 @@ +@echo gorgeex test +@exit /b 1 diff --git a/tests/vm/tgorgeex.sh b/tests/vm/tgorgeex.sh new file mode 100644 index 000000000..36ba0a02f --- /dev/null +++ b/tests/vm/tgorgeex.sh @@ -0,0 +1,3 @@ +#!/bin/sh +echo "gorgeex test" +exit 1 |