From 098a8a7c522986ce250d4e52dc42182e5d9d7352 Mon Sep 17 00:00:00 2001 From: Scott Wadden Date: Mon, 7 Sep 2020 15:05:07 -0300 Subject: [PATCH] nimeval errorHook support (#15255) --- compiler/nimeval.nim | 11 +++++--- tests/compilerapi/invalid.nim | 1 + tests/compilerapi/tcompilerapi.nim | 41 ++++++++++++++++++++---------- 3 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 tests/compilerapi/invalid.nim diff --git a/compiler/nimeval.nim b/compiler/nimeval.nim index df3cb2079f..5d4fea9f35 100644 --- a/compiler/nimeval.nim +++ b/compiler/nimeval.nim @@ -10,9 +10,9 @@ ## exposes the Nim VM to clients. import ast, astalgo, modules, passes, condsyms, - options, sem, semdata, llstream, vm, vmdef, - modulegraphs, idents, os, pathutils, passaux, - scriptconfig + options, sem, semdata, llstream, lineinfos, vm, + vmdef, modulegraphs, idents, os, pathutils, + passaux, scriptconfig type Interpreter* = ref object ## Use Nim as an interpreter with this object @@ -134,6 +134,11 @@ proc destroyInterpreter*(i: Interpreter) = ## destructor. discard "currently nothing to do." +proc registerErrorHook*(i: Interpreter, hook: + proc (config: ConfigRef; info: TLineInfo; msg: string; + severity: Severity) {.gcsafe.}) = + i.graph.config.structuredErrorHook = hook + proc runRepl*(r: TLLRepl; searchPaths: openArray[string]; supportNimscript: bool) = diff --git a/tests/compilerapi/invalid.nim b/tests/compilerapi/invalid.nim new file mode 100644 index 0000000000..3c93644028 --- /dev/null +++ b/tests/compilerapi/invalid.nim @@ -0,0 +1 @@ +noSuchProc() diff --git a/tests/compilerapi/tcompilerapi.nim b/tests/compilerapi/tcompilerapi.nim index 9d5e0e3f21..d8489c763f 100644 --- a/tests/compilerapi/tcompilerapi.nim +++ b/tests/compilerapi/tcompilerapi.nim @@ -5,6 +5,7 @@ discard """ my secret 11 12 +raising VMQuit ''' joinable: "false" """ @@ -12,34 +13,35 @@ my secret ## Example program that demonstrates how to use the ## compiler as an API to embed into your own projects. -import "../../compiler" / [ast, vmdef, vm, nimeval, llstream] +import "../../compiler" / [ast, vmdef, vm, nimeval, llstream, lineinfos, options] import std / [os] -proc main() = +proc initInterpreter(script: string): Interpreter = let std = findNimStdLibCompileTime() - var intr = createInterpreter("myscript.nim", [std, parentDir(currentSourcePath), + result = createInterpreter(script , [std, parentDir(currentSourcePath), std / "pure", std / "core"]) - intr.implementRoutine("*", "exposed", "addFloats", proc (a: VmArgs) = + +proc main() = + let i = initInterpreter("myscript.nim") + i.implementRoutine("*", "exposed", "addFloats", proc (a: VmArgs) = setResult(a, getFloat(a, 0) + getFloat(a, 1) + getFloat(a, 2)) ) - - intr.evalScript() - - let foreignProc = selectRoutine(intr, "hostProgramRunsThis") + i.evalScript() + let foreignProc = i.selectRoutine("hostProgramRunsThis") if foreignProc == nil: quit "script does not export a proc of the name: 'hostProgramRunsThis'" - let res = intr.callRoutine(foreignProc, [newFloatNode(nkFloatLit, 0.9), - newFloatNode(nkFloatLit, 0.1)]) + let res = i.callRoutine(foreignProc, [newFloatNode(nkFloatLit, 0.9), + newFloatNode(nkFloatLit, 0.1)]) doAssert res.kind == nkFloatLit echo res.floatVal - let foreignValue = selectUniqueSymbol(intr, "hostProgramWantsThis") + let foreignValue = i.selectUniqueSymbol("hostProgramWantsThis") if foreignValue == nil: quit "script does not export a global of the name: hostProgramWantsThis" - let val = intr.getGlobalValue(foreignValue) + let val = i.getGlobalValue(foreignValue) doAssert val.kind in {nkStrLit..nkTripleStrLit} echo val.strVal - destroyInterpreter(intr) + i.destroyInterpreter() main() @@ -54,3 +56,16 @@ block issue9180: evalString("echo 10+1") evalString("echo 10+2") + +block error_hook: + type VMQuit = object of CatchableError + + let i = initInterpreter("invalid.nim") + i.registerErrorHook proc(config: ConfigRef; info: TLineInfo; msg: string; + severity: Severity) {.gcsafe.} = + if severity == Error and config.errorCounter >= config.errorMax: + echo "raising VMQuit" + raise newException(VMQuit, "Script error") + + doAssertRaises(VMQuit): + i.evalScript()