Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions lib/std/assertions.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions lib/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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.}
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:.
Expand Down
19 changes: 16 additions & 3 deletions lib/system/assign.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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.}
Expand Down Expand Up @@ -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")
63 changes: 38 additions & 25 deletions lib/system/chcks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -95,25 +108,25 @@ 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:
return x
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):

Expand All @@ -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]

Expand Down Expand Up @@ -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")
25 changes: 20 additions & 5 deletions lib/system/embedded.nim
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,29 @@ const
proc quitOrDebug() {.noreturn, importc: "abort", header: "<stdlib.h>", 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

Expand All @@ -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")
24 changes: 17 additions & 7 deletions lib/system/fatal.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions lib/system/fatal_shared.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
when not declared(gotoBasedExceptions):
const gotoBasedExceptions* = compileOption("exceptions", "goto")

when not declared(quirkyExceptions):
const quirkyExceptions* = compileOption("exceptions", "quirky")
5 changes: 4 additions & 1 deletion lib/system/indices.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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..<L: a[Idx(i + xa)] = b[i]
else:
sysFatal(RangeDefect, "different lengths for slice assignment")
when declared(sysFatal):
sysFatal(RangeDefect, "different lengths for slice assignment")
else:
raise newException(RangeDefect, "different lengths for slice assignment")

proc `[]`*[T; U, V: Ordinal](s: openArray[T], x: HSlice[U, V]): seq[T] {.systemRaisesDefect.} =
## Slice operation for sequences.
Expand Down
25 changes: 20 additions & 5 deletions lib/system/integerops.nim
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,16 @@

proc raiseOverflow {.compilerproc, noinline.} =
# a single proc to reduce code size to a minimum
sysFatal(OverflowDefect, "over- or underflow")
when declared(sysFatal):
sysFatal(OverflowDefect, "over- or underflow")
else:
raise newException(OverflowDefect, "over- or underflow")

proc raiseDivByZero {.compilerproc, noinline.} =
sysFatal(DivByZeroDefect, "division by zero")
when declared(sysFatal):
sysFatal(DivByZeroDefect, "division by zero")
else:
raise newException(DivByZeroDefect, "division by zero")

{.pragma: nimbaseH, importc, nodecl, noSideEffect, compilerproc.}

Expand Down Expand Up @@ -124,10 +130,19 @@ divImplFallback(nimDivInt, int)
divImplFallback(nimDivInt64, int64)

proc raiseFloatInvalidOp {.compilerproc, noinline.} =
sysFatal(FloatInvalidOpDefect, "FPU operation caused a NaN result")
when declared(sysFatal):
sysFatal(FloatInvalidOpDefect, "FPU operation caused a NaN result")
else:
raise newException(FloatInvalidOpDefect, "FPU operation caused a NaN result")

proc raiseFloatOverflow(x: float64) {.compilerproc, noinline.} =
if x > 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")
2 changes: 1 addition & 1 deletion tests/errmsgs/t14444.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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]
'''
"""
Expand Down
2 changes: 1 addition & 1 deletion tests/errmsgs/t23536.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
"""


Expand Down
2 changes: 1 addition & 1 deletion tests/errmsgs/t24974.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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]
'''
"""
Expand Down
Loading
Loading