1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
#
#
# Nim's Runtime Library
# (c) Copyright 2013 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
# Implementation of some runtime checks.
include system/indexerrors
when defined(nimPreviewSlimSystem):
import std/formatfloat
proc raiseRangeError(val: BiggestInt) {.compilerproc, noinline.} =
when hostOS == "standalone":
sysFatal(RangeDefect, "value out of range")
else:
sysFatal(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))
proc raiseIndexError3(i, a, b: int) {.compilerproc, noinline.} =
sysFatal(IndexDefect, formatErrorIndexBound(i, a, b))
proc raiseIndexError2(i, n: int) {.compilerproc, noinline.} =
sysFatal(IndexDefect, formatErrorIndexBound(i, n))
proc raiseIndexError() {.compilerproc, noinline.} =
sysFatal(IndexDefect, "index out of bounds")
proc raiseFieldError(f: string) {.compilerproc, noinline.} =
## remove after bootstrap > 1.5.1
sysFatal(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 & "'")
proc raiseFieldErrorStr(f: string, discVal: string) {.compilerproc, noinline.} =
## raised when field is inaccessible given runtime value of discriminant
sysFatal(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))
proc raiseRangeErrorI(i, a, b: BiggestInt) {.compilerproc, noinline.} =
when defined(standalone):
sysFatal(RangeDefect, "value out of range")
else:
sysFatal(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")
else:
sysFatal(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")
proc raiseRangeErrorNoArgs() {.compilerproc, noinline.} =
sysFatal(RangeDefect, "value out of range")
proc raiseObjectConversionError() {.compilerproc, noinline.} =
sysFatal(ObjectConversionDefect, "invalid object conversion")
proc chckIndx(i, a, b: int): int =
if i >= a and i <= b:
return i
else:
raiseIndexError3(i, a, b)
proc chckRange(i, a, b: int): int =
if i >= a and i <= b:
return i
else:
raiseRangeError(i)
proc chckRange64(i, a, b: int64): int64 {.compilerproc.} =
if i >= a and i <= b:
return i
else:
raiseRangeError(i)
proc chckRangeU(i, a, b: uint64): uint64 {.compilerproc.} =
if i >= a and i <= b:
return i
else:
sysFatal(RangeDefect, "value out of range")
proc chckRangeF(x, a, b: float): float =
if x >= a and x <= b:
return x
else:
when hostOS == "standalone":
sysFatal(RangeDefect, "value out of range")
else:
sysFatal(RangeDefect, "value out of range: ", $x)
proc chckNil(p: pointer) =
if p == nil:
sysFatal(NilAccessDefect, "attempt to write to a nil address")
proc chckNilDisp(p: pointer) {.compilerproc.} =
if p == nil:
sysFatal(NilAccessDefect, "cannot dispatch; dispatcher is nil")
when not defined(nimV2):
proc chckObj(obj, subclass: PNimType) {.compilerproc.} =
# checks if obj is of type subclass:
var x = obj
if x == subclass: return # optimized fast path
while x != subclass:
if x == nil:
sysFatal(ObjectConversionDefect, "invalid object conversion")
x = x.base
proc chckObjAsgn(a, b: PNimType) {.compilerproc, inline.} =
if a != b:
sysFatal(ObjectAssignmentDefect, "invalid object assignment")
type ObjCheckCache = array[0..1, PNimType]
proc isObjSlowPath(obj, subclass: PNimType;
cache: var ObjCheckCache): bool {.noinline.} =
# checks if obj is of type subclass:
var x = obj.base
while x != subclass:
if x == nil:
cache[0] = obj
return false
x = x.base
cache[1] = obj
return true
proc isObjWithCache(obj, subclass: PNimType;
cache: var ObjCheckCache): bool {.compilerproc, inline.} =
if obj == subclass: return true
if obj.base == subclass: return true
if cache[0] == obj: return false
if cache[1] == obj: return true
return isObjSlowPath(obj, subclass, cache)
proc isObj(obj, subclass: PNimType): bool {.compilerproc.} =
# checks if obj is of type subclass:
var x = obj
if x == subclass: return true # optimized fast path
while x != subclass:
if x == nil: return false
x = x.base
return true
when defined(nimV2):
proc raiseObjectCaseTransition() {.compilerproc.} =
sysFatal(FieldDefect, "assignment to discriminant changes object branch")
|