diff --git a/lib/std/assertions.nim b/lib/std/assertions.nim index f31a8465afb97..771e7473b0818 100644 --- a/lib/std/assertions.nim +++ b/lib/std/assertions.nim @@ -9,7 +9,8 @@ when not defined(nimPreviewSlimSystem) and not declared(sysFatal): include "system/rawquits" - include "system/fatal" + when hostOS != "standalone": + include "system/fatal" ## This module implements assertion handling. @@ -37,7 +38,10 @@ proc raiseAssert*(msg: string) {.noinline, noreturn, nosinks.} = when defined(nimPreviewSlimSystem): raise newException(AssertionDefect, msg) else: - sysFatal(AssertionDefect, msg) + when declared(sysFatal): + sysFatal(AssertionDefect, msg) + else: + raise newException(AssertionDefect, msg) proc failedAssertImpl*(msg: string) {.raises: [], tags: [].} = ## Raises an `AssertionDefect` with `msg`, but this is hidden diff --git a/lib/system.nim b/lib/system.nim index 9ef8128c2d468..8a0abdd20dddd 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -32,6 +32,7 @@ func zeroDefault*[T](_: typedesc[T]): T {.magic: "ZeroDefault".} = ## * `default <#default,typedesc[T]>`_ include "system/compilation" +include "system/fatal_shared" {.push warning[GcMem]: off, warning[Uninit]: off.} # {.push hints: off.} @@ -1139,6 +1140,10 @@ include system/rawquits when defined(genode): export GenodeEnv +when not declared(sysFatal) and hostOS != "standalone": + include "system/fatal" + + template sysAssert(cond: bool, msg: string) = when defined(useSysAssert): if not cond: @@ -2570,6 +2575,11 @@ type NimNode* {.magic: "PNimrodNode".} = ref NimNodeObj ## Represents a Nim AST node. Macros operate on this type. +when not declared(sysFatal): + include "system/fatal" + when hostOS == "standalone" and declared(includePanicoverrideIfReady): + includePanicoverrideIfReady() + type ForLoopStmt* {.compilerproc.} = object ## \ ## A special type that marks a macro as a `for-loop macro`:idx:. diff --git a/lib/system/assign.nim b/lib/system/assign.nim index 9f4cbc0feb2df..009a4a1bcff4a 100644 --- a/lib/system/assign.nim +++ b/lib/system/assign.nim @@ -9,6 +9,19 @@ include seqs_v2_reimpl +when not declared(sysFatal): + template sysFatalOrRaise(exceptn: typedesc[Defect], message: string, arg: string = ""): untyped = + if arg == "": + raise newException(exceptn, message) + else: + raise newException(exceptn, message & arg) +else: + template sysFatalOrRaise(exceptn: typedesc[Defect], message: string, arg: string = ""): untyped = + if arg == "": + sysFatal(exceptn, message) + else: + sysFatal(exceptn, message, arg) + proc genericResetAux(dest: pointer, n: ptr TNimNode) {.benign.} proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) {.benign.} @@ -289,10 +302,10 @@ proc FieldDiscriminantCheck(oldDiscVal, newDiscVal: int, let newBranch = selectBranch(newDiscVal, L, a) when defined(nimOldCaseObjects): if newBranch != oldBranch and oldDiscVal != 0: - sysFatal(FieldDefect, "assignment to discriminant changes object branch") + sysFatalOrRaise(FieldDefect, "assignment to discriminant changes object branch") else: if newBranch != oldBranch: if oldDiscVal != 0: - sysFatal(FieldDefect, "assignment to discriminant changes object branch") + sysFatalOrRaise(FieldDefect, "assignment to discriminant changes object branch") else: - sysFatal(FieldDefect, "assignment to discriminant changes object branch; compile with -d:nimOldCaseObjects for a transition period") + sysFatalOrRaise(FieldDefect, "assignment to discriminant changes object branch; compile with -d:nimOldCaseObjects for a transition period") diff --git a/lib/system/chcks.nim b/lib/system/chcks.nim index 1a7d7f0a90388..27009188858d7 100644 --- a/lib/system/chcks.nim +++ b/lib/system/chcks.nim @@ -12,62 +12,75 @@ include system/indexerrors when defined(nimPreviewSlimSystem): import std/formatfloat +when not declared(sysFatal): + template sysFatalOrRaise(exceptn: typedesc[Defect], message: string, arg: string = ""): untyped = + if arg == "": + raise newException(exceptn, message) + else: + raise newException(exceptn, message & arg) +else: + template sysFatalOrRaise(exceptn: typedesc[Defect], message: string, arg: string = ""): untyped = + if arg == "": + sysFatal(exceptn, message) + else: + sysFatal(exceptn, message, arg) + proc raiseRangeError(val: BiggestInt) {.compilerproc, noinline.} = when hostOS == "standalone": - sysFatal(RangeDefect, "value out of range") + sysFatalOrRaise(RangeDefect, "value out of range") else: - sysFatal(RangeDefect, "value out of range: ", $val) + sysFatalOrRaise(RangeDefect, "value out of range: ", $val) proc raiseIndexError4(l1, h1, h2: int) {.compilerproc, noinline.} = - sysFatal(IndexDefect, "index out of bounds: " & $l1 & ".." & $h1 & " notin 0.." & $(h2 - 1)) + sysFatalOrRaise(IndexDefect, "index out of bounds: " & $l1 & ".." & $h1 & " notin 0.." & $(h2 - 1)) proc raiseIndexError3(i, a, b: int) {.compilerproc, noinline.} = - sysFatal(IndexDefect, formatErrorIndexBound(i, a, b)) + sysFatalOrRaise(IndexDefect, formatErrorIndexBound(i, a, b)) proc raiseIndexError2(i, n: int) {.compilerproc, noinline.} = - sysFatal(IndexDefect, formatErrorIndexBound(i, n)) + sysFatalOrRaise(IndexDefect, formatErrorIndexBound(i, n)) proc raiseIndexError() {.compilerproc, noinline.} = - sysFatal(IndexDefect, "index out of bounds") + sysFatalOrRaise(IndexDefect, "index out of bounds") proc raiseFieldError(f: string) {.compilerproc, noinline.} = ## remove after bootstrap > 1.5.1 - sysFatal(FieldDefect, f) + sysFatalOrRaise(FieldDefect, f) when defined(nimV2): proc raiseFieldError2(f: string, discVal: int) {.compilerproc, noinline.} = ## raised when field is inaccessible given runtime value of discriminant - sysFatal(FieldDefect, f & $discVal & "'") + sysFatalOrRaise(FieldDefect, f & $discVal & "'") proc raiseFieldErrorStr(f: string, discVal: string) {.compilerproc, noinline.} = ## raised when field is inaccessible given runtime value of discriminant - sysFatal(FieldDefect, formatFieldDefect(f, discVal)) + sysFatalOrRaise(FieldDefect, formatFieldDefect(f, discVal)) else: proc raiseFieldError2(f: string, discVal: string) {.compilerproc, noinline.} = ## raised when field is inaccessible given runtime value of discriminant - sysFatal(FieldDefect, formatFieldDefect(f, discVal)) + sysFatalOrRaise(FieldDefect, formatFieldDefect(f, discVal)) proc raiseRangeErrorI(i, a, b: BiggestInt) {.compilerproc, noinline.} = when defined(standalone): - sysFatal(RangeDefect, "value out of range") + sysFatalOrRaise(RangeDefect, "value out of range") else: - sysFatal(RangeDefect, "value out of range: " & $i & " notin " & $a & " .. " & $b) + sysFatalOrRaise(RangeDefect, "value out of range: " & $i & " notin " & $a & " .. " & $b) proc raiseRangeErrorF(i, a, b: float) {.compilerproc, noinline.} = when defined(standalone): - sysFatal(RangeDefect, "value out of range") + sysFatalOrRaise(RangeDefect, "value out of range") else: - sysFatal(RangeDefect, "value out of range: " & $i & " notin " & $a & " .. " & $b) + sysFatalOrRaise(RangeDefect, "value out of range: " & $i & " notin " & $a & " .. " & $b) proc raiseRangeErrorU(i, a, b: uint64) {.compilerproc, noinline.} = # todo: better error reporting - sysFatal(RangeDefect, "value out of range") + sysFatalOrRaise(RangeDefect, "value out of range") proc raiseRangeErrorNoArgs() {.compilerproc, noinline.} = - sysFatal(RangeDefect, "value out of range") + sysFatalOrRaise(RangeDefect, "value out of range") proc raiseObjectConversionError() {.compilerproc, noinline.} = - sysFatal(ObjectConversionDefect, "invalid object conversion") + sysFatalOrRaise(ObjectConversionDefect, "invalid object conversion") proc chckIndx(i, a, b: int): int = if i >= a and i <= b: @@ -95,7 +108,7 @@ proc chckRangeU(i, a, b: uint64): uint64 {.compilerproc.} = return i else: result = 0 - sysFatal(RangeDefect, "value out of range") + sysFatalOrRaise(RangeDefect, "value out of range") proc chckRangeF(x, a, b: float): float = if x >= a and x <= b: @@ -103,17 +116,17 @@ proc chckRangeF(x, a, b: float): float = else: result = 0.0 when hostOS == "standalone": - sysFatal(RangeDefect, "value out of range") + sysFatalOrRaise(RangeDefect, "value out of range") else: - sysFatal(RangeDefect, "value out of range: ", $x) + sysFatalOrRaise(RangeDefect, "value out of range: ", $x) proc chckNil(p: pointer) = if p == nil: - sysFatal(NilAccessDefect, "attempt to write to a nil address") + sysFatalOrRaise(NilAccessDefect, "attempt to write to a nil address") proc chckNilDisp(p: pointer) {.compilerproc.} = if p == nil: - sysFatal(NilAccessDefect, "cannot dispatch; dispatcher is nil") + sysFatalOrRaise(NilAccessDefect, "cannot dispatch; dispatcher is nil") when not defined(nimV2): @@ -123,12 +136,12 @@ when not defined(nimV2): if x == subclass: return # optimized fast path while x != subclass: if x == nil: - sysFatal(ObjectConversionDefect, "invalid object conversion") + sysFatalOrRaise(ObjectConversionDefect, "invalid object conversion") x = x.base proc chckObjAsgn(a, b: PNimType) {.compilerproc, inline.} = if a != b: - sysFatal(ObjectAssignmentDefect, "invalid object assignment") + sysFatalOrRaise(ObjectAssignmentDefect, "invalid object assignment") type ObjCheckCache = array[0..1, PNimType] @@ -163,4 +176,4 @@ when not defined(nimV2): when defined(nimV2): proc raiseObjectCaseTransition() {.compilerproc.} = - sysFatal(FieldDefect, "assignment to discriminant changes object branch") + sysFatalOrRaise(FieldDefect, "assignment to discriminant changes object branch") diff --git a/lib/system/embedded.nim b/lib/system/embedded.nim index 5d1d12accb0af..d0d7d8f44add0 100644 --- a/lib/system/embedded.nim +++ b/lib/system/embedded.nim @@ -34,17 +34,29 @@ const proc quitOrDebug() {.noreturn, importc: "abort", header: "", nodecl.} proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} = - sysFatal(ReraiseDefect, "exception handling is not available") + when declared(sysFatal): + sysFatal(ReraiseDefect, "exception handling is not available") + else: + raise newException(ReraiseDefect, "exception handling is not available") proc raiseExceptionEx(e: sink(ref Exception), ename, procname, filename: cstring, line: int) {.compilerRtl.} = - sysFatal(ReraiseDefect, "exception handling is not available") + when declared(sysFatal): + sysFatal(ReraiseDefect, "exception handling is not available") + else: + raise newException(ReraiseDefect, "exception handling is not available") proc reraiseException() {.compilerRtl.} = - sysFatal(ReraiseDefect, "no exception to reraise") + when declared(sysFatal): + sysFatal(ReraiseDefect, "no exception to reraise") + else: + raise newException(ReraiseDefect, "no exception to reraise") proc raiseDefect() {.compilerRtl.} = - sysFatal(ReraiseDefect, "exception handling is not available") + when declared(sysFatal): + sysFatal(ReraiseDefect, "exception handling is not available") + else: + raise newException(ReraiseDefect, "exception handling is not available") proc writeStackTrace() = discard @@ -59,4 +71,7 @@ when gotoBasedExceptions: proc nimTestErrorFlag() {.compilerRtl.} = if nimInErrorMode: - sysFatal(ReraiseDefect, "exception handling is not available") + when declared(sysFatal): + sysFatal(ReraiseDefect, "exception handling is not available") + else: + raise newException(ReraiseDefect, "exception handling is not available") diff --git a/lib/system/fatal.nim b/lib/system/fatal.nim index 25c05e52d9cc8..87308550bf7b5 100644 --- a/lib/system/fatal.nim +++ b/lib/system/fatal.nim @@ -9,19 +9,29 @@ {.push profiler: off.} -const - gotoBasedExceptions = compileOption("exceptions", "goto") - quirkyExceptions = compileOption("exceptions", "quirky") +include "system/fatal_shared" when hostOS == "standalone": - include "$projectpath/panicoverride" + when declared(repr) and declared(NimNode): + include "$projectpath/panicoverride" + else: + template includePanicoverrideIfReady() = + when declared(repr) and declared(NimNode): + include "$projectpath/panicoverride" func sysFatal(exceptn: typedesc[Defect], message: string) {.inline.} = - panic(message) + when declared(panic): + panic(message) + else: + raise newException(exceptn, message) func sysFatal(exceptn: typedesc[Defect], message, arg: string) {.inline.} = - rawoutput(message) - panic(arg) + when declared(rawoutput): + rawoutput(message) + when declared(panic): + panic(arg) + else: + raise newException(exceptn, message & arg) elif quirkyExceptions and not defined(nimscript): import ansi_c diff --git a/lib/system/fatal_shared.nim b/lib/system/fatal_shared.nim new file mode 100644 index 0000000000000..26467b943978b --- /dev/null +++ b/lib/system/fatal_shared.nim @@ -0,0 +1,5 @@ +when not declared(gotoBasedExceptions): + const gotoBasedExceptions* = compileOption("exceptions", "goto") + +when not declared(quirkyExceptions): + const quirkyExceptions* = compileOption("exceptions", "quirky") \ No newline at end of file diff --git a/lib/system/indices.nim b/lib/system/indices.nim index f2bad2528f770..6c4b40735f3d5 100644 --- a/lib/system/indices.nim +++ b/lib/system/indices.nim @@ -130,7 +130,10 @@ proc `[]=`*[Idx, T; U, V: Ordinal](a: var array[Idx, T], x: HSlice[U, V], b: ope if L == b.len: for i in 0.. 0.0: - sysFatal(FloatOverflowDefect, "FPU operation caused an overflow") + when declared(sysFatal): + sysFatal(FloatOverflowDefect, "FPU operation caused an overflow") + else: + raise newException(FloatOverflowDefect, "FPU operation caused an overflow") else: - sysFatal(FloatUnderflowDefect, "FPU operations caused an underflow") + when declared(sysFatal): + sysFatal(FloatUnderflowDefect, "FPU operations caused an underflow") + else: + raise newException(FloatUnderflowDefect, "FPU operations caused an underflow") diff --git a/tests/errmsgs/t14444.nim b/tests/errmsgs/t14444.nim index 27365236ed5ac..f9bef08d80be8 100644 --- a/tests/errmsgs/t14444.nim +++ b/tests/errmsgs/t14444.nim @@ -3,7 +3,7 @@ discard """ exitcode: "1" output: ''' t14444.nim(13) t14444 -fatal.nim(53) sysFatal +fatal.nim(63) sysFatal Error: unhandled exception: index out of bounds, the container is empty [IndexDefect] ''' """ diff --git a/tests/errmsgs/t23536.nim b/tests/errmsgs/t23536.nim index d8f143333132f..654e92490faa1 100644 --- a/tests/errmsgs/t23536.nim +++ b/tests/errmsgs/t23536.nim @@ -8,7 +8,7 @@ t23536.nim(22) t23536 t23536.nim(17) foo assertions.nim(45) failedAssertImpl assertions.nim(40) raiseAssert -fatal.nim(53) sysFatal +fatal.nim(63) sysFatal """ diff --git a/tests/errmsgs/t24974.nim b/tests/errmsgs/t24974.nim index 39d473a89e343..4f98e49f62db2 100644 --- a/tests/errmsgs/t24974.nim +++ b/tests/errmsgs/t24974.nim @@ -6,7 +6,7 @@ t24974.nim(19) d t24974.nim(16) s assertions.nim(45) failedAssertImpl assertions.nim(40) raiseAssert -fatal.nim(53) sysFatal +fatal.nim(63) sysFatal Error: unhandled exception: t24974.nim(16, 26) `false` [AssertionDefect] ''' """ diff --git a/tests/exception/t22469.nim b/tests/exception/t22469.nim index a76c749678c2c..c0752aeba3b76 100644 --- a/tests/exception/t22469.nim +++ b/tests/exception/t22469.nim @@ -3,7 +3,7 @@ discard """ output: ''' First top-level statement of ModuleB m22469.nim(3) m22469 -fatal.nim(53) sysFatal +fatal.nim(63) sysFatal Error: unhandled exception: over- or underflow [OverflowDefect] ''' """