mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-11 22:08:54 +00:00
* quit value gets saturated to ranges * add documentation * minimal changes * refactor * small fix * add documentation * fixes * Update lib/system.nim Co-authored-by: Juan Carlos <juancarlospaco@gmail.com> Co-authored-by: Juan Carlos <juancarlospaco@gmail.com>
This commit is contained in:
@@ -111,7 +111,7 @@ proc osDeallocPages(p: pointer; size: int) =
|
||||
if m.attachment == p:
|
||||
if m.size != size:
|
||||
echo "cannot partially detach dataspace"
|
||||
quit -1
|
||||
rawQuit -1
|
||||
runtimeEnv.detachAddress m.attachment
|
||||
runtimeEnv.freeDataspace m.ds
|
||||
m[] = Map()
|
||||
|
||||
@@ -1087,32 +1087,7 @@ proc align(address, alignment: int): int =
|
||||
result = (address + (alignment - 1)) and not (alignment - 1)
|
||||
|
||||
when defined(nimNoQuit):
|
||||
proc quit*(errorcode: int = QuitSuccess) = discard "ignoring quit"
|
||||
## Stops the program immediately with an exit code.
|
||||
##
|
||||
## Before stopping the program the "exit procedures" are called in the
|
||||
## opposite order they were added with `addExitProc <exitprocs.html#addExitProc,proc)>`_.
|
||||
##
|
||||
## The proc `quit(QuitSuccess)` is called implicitly when your nim
|
||||
## program finishes without incident for platforms where this is the
|
||||
## expected behavior. A raised unhandled exception is
|
||||
## equivalent to calling `quit(QuitFailure)`.
|
||||
##
|
||||
## Note that this is a *runtime* call and using `quit` inside a macro won't
|
||||
## have any compile time effect. If you need to stop the compiler inside a
|
||||
## macro, use the `error <manual.html#pragmas-error-pragma>`_ or `fatal
|
||||
## <manual.html#pragmas-fatal-pragma>`_ pragmas.
|
||||
##
|
||||
## .. danger:: In almost all cases, in particular in library code, prefer
|
||||
## alternatives, e.g. `doAssert false` or raise a `Defect`.
|
||||
## `quit` bypasses regular control flow in particular `defer`,
|
||||
## `try`, `catch`, `finally` and `destructors`, and exceptions that may have been
|
||||
## raised by an `addExitProc` proc, as well as cleanup code in other threads.
|
||||
## It does *not* call the garbage collector to free all the memory,
|
||||
## unless an `addExitProc` proc calls `GC_fullCollect <#GC_fullCollect>`_.
|
||||
|
||||
elif defined(nimdoc):
|
||||
proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit", noreturn.}
|
||||
proc rawQuit(errorcode: int = QuitSuccess) = discard "ignoring quit"
|
||||
|
||||
elif defined(genode):
|
||||
import genode/env
|
||||
@@ -1122,28 +1097,28 @@ elif defined(genode):
|
||||
type GenodeEnv* = GenodeEnvPtr
|
||||
## Opaque type representing Genode environment.
|
||||
|
||||
proc quit*(env: GenodeEnv; errorcode: int) {.magic: "Exit", noreturn,
|
||||
proc rawQuit(env: GenodeEnv; errorcode: int) {.magic: "Exit", noreturn,
|
||||
importcpp: "#->parent().exit(@); Genode::sleep_forever()", header: "<base/sleep.h>".}
|
||||
|
||||
proc quit*(errorcode: int = QuitSuccess) =
|
||||
systemEnv.quit(errorcode)
|
||||
proc rawQuit(errorcode: int = QuitSuccess) {.inline, noreturn.} =
|
||||
systemEnv.rawQuit(errorcode)
|
||||
|
||||
|
||||
elif defined(js) and defined(nodejs) and not defined(nimscript):
|
||||
proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit",
|
||||
proc rawQuit(errorcode: int = QuitSuccess) {.magic: "Exit",
|
||||
importc: "process.exit", noreturn.}
|
||||
|
||||
else:
|
||||
proc quit*(errorcode: int = QuitSuccess) {.
|
||||
proc rawQuit(errorcode: int = QuitSuccess) {.
|
||||
magic: "Exit", importc: "exit", header: "<stdlib.h>", noreturn.}
|
||||
|
||||
|
||||
template sysAssert(cond: bool, msg: string) =
|
||||
when defined(useSysAssert):
|
||||
if not cond:
|
||||
cstderr.rawWrite "[SYSASSERT] "
|
||||
cstderr.rawWrite msg
|
||||
cstderr.rawWrite "\n"
|
||||
quit 1
|
||||
rawQuit 1
|
||||
|
||||
const hasAlloc = (hostOS != "standalone" or not defined(nogc)) and not defined(nimscript)
|
||||
|
||||
@@ -2280,6 +2255,62 @@ when defined(js):
|
||||
include "system/jssys"
|
||||
include "system/reprjs"
|
||||
|
||||
|
||||
when defined(nimNoQuit):
|
||||
proc quit*(errorcode: int = QuitSuccess) = discard "ignoring quit"
|
||||
## Stops the program immediately with an exit code.
|
||||
##
|
||||
## Before stopping the program the "exit procedures" are called in the
|
||||
## opposite order they were added with `addExitProc <exitprocs.html#addExitProc,proc)>`_.
|
||||
##
|
||||
## The proc `quit(QuitSuccess)` is called implicitly when your nim
|
||||
## program finishes without incident for platforms where this is the
|
||||
## expected behavior. A raised unhandled exception is
|
||||
## equivalent to calling `quit(QuitFailure)`.
|
||||
##
|
||||
## Note that this is a *runtime* call and using `quit` inside a macro won't
|
||||
## have any compile time effect. If you need to stop the compiler inside a
|
||||
## macro, use the `error <manual.html#pragmas-error-pragma>`_ or `fatal
|
||||
## <manual.html#pragmas-fatal-pragma>`_ pragmas.
|
||||
##
|
||||
## .. warning:: `errorcode` gets saturated when it exceeds the valid range
|
||||
## on the specific platform. On Posix, the valid range is `low(int8)..high(int8)`.
|
||||
## On Windows, the valid range is `low(int32)..high(int32)`. For instance,
|
||||
## `quit(int(0x100000000))` is equal to `quit(127)` on Linux.
|
||||
##
|
||||
## .. danger:: In almost all cases, in particular in library code, prefer
|
||||
## alternatives, e.g. `doAssert false` or raise a `Defect`.
|
||||
## `quit` bypasses regular control flow in particular `defer`,
|
||||
## `try`, `catch`, `finally` and `destructors`, and exceptions that may have been
|
||||
## raised by an `addExitProc` proc, as well as cleanup code in other threads.
|
||||
## It does *not* call the garbage collector to free all the memory,
|
||||
## unless an `addExitProc` proc calls `GC_fullCollect <#GC_fullCollect>`_.
|
||||
|
||||
elif defined(nimdoc):
|
||||
proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit", noreturn.}
|
||||
|
||||
elif defined(genode):
|
||||
proc quit*(errorcode: int = QuitSuccess) {.inline, noreturn.} =
|
||||
rawQuit(errorcode)
|
||||
|
||||
elif defined(js) and defined(nodejs) and not defined(nimscript):
|
||||
proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit",
|
||||
importc: "process.exit", noreturn.}
|
||||
|
||||
else:
|
||||
proc quit*(errorcode: int = QuitSuccess) {.inline, noreturn.} =
|
||||
when defined(posix): # posix uses low 8 bits
|
||||
type ExitCodeRange = int8
|
||||
else: # win32 uses low 32 bits
|
||||
type ExitCodeRange = int32
|
||||
|
||||
if errorcode < low(ExitCodeRange):
|
||||
rawQuit(low(ExitCodeRange).int)
|
||||
elif errorcode > high(ExitCodeRange):
|
||||
rawQuit(high(ExitCodeRange).int)
|
||||
else:
|
||||
rawQuit(errorcode)
|
||||
|
||||
proc quit*(errormsg: string, errorcode = QuitFailure) {.noreturn.} =
|
||||
## A shorthand for `echo(errormsg); quit(errorcode)`.
|
||||
when defined(nimscript) or defined(js) or (hostOS == "standalone"):
|
||||
@@ -2662,7 +2693,7 @@ when defined(genode):
|
||||
proc nim_component_construct(env: GenodeEnv) {.exportc.} =
|
||||
## Procedure called during `Component::construct` by the loader.
|
||||
if componentConstructHook.isNil:
|
||||
env.quit(programResult)
|
||||
env.rawQuit(programResult)
|
||||
# No native Genode application initialization,
|
||||
# exit as would POSIX.
|
||||
else:
|
||||
|
||||
@@ -154,7 +154,7 @@ proc nimRawDispose(p: pointer, alignment: int) {.compilerRtl.} =
|
||||
when defined(nimOwnedEnabled):
|
||||
if head(p).rc >= rcIncrement:
|
||||
cstderr.rawWrite "[FATAL] dangling references exist\n"
|
||||
quit 1
|
||||
rawQuit 1
|
||||
when defined(nimArcDebug):
|
||||
# we do NOT really free the memory here in order to reliably detect use-after-frees
|
||||
if freedCells.data == nil: init(freedCells)
|
||||
|
||||
@@ -47,14 +47,14 @@ proc nimLoadLibraryError(path: string) =
|
||||
copyMem(msg[msgIdx].addr, badExe.cstring, badExe.len)
|
||||
discard MessageBoxA(nil, msg[0].addr, nil, 0)
|
||||
cstderr.rawWrite("\n")
|
||||
quit(1)
|
||||
rawQuit(1)
|
||||
|
||||
proc procAddrError(name: cstring) {.compilerproc, nonReloadable, hcrInline.} =
|
||||
# carefully written to avoid memory allocation:
|
||||
cstderr.rawWrite("could not import: ")
|
||||
cstderr.rawWrite(name)
|
||||
cstderr.rawWrite("\n")
|
||||
quit(1)
|
||||
rawQuit(1)
|
||||
|
||||
# this code was inspired from Lua's source code:
|
||||
# Lua - An Extensible Extension Language
|
||||
@@ -180,19 +180,19 @@ elif defined(nintendoswitch) or defined(freertos) or defined(zephyr):
|
||||
proc nimUnloadLibrary(lib: LibHandle) =
|
||||
cstderr.rawWrite("nimUnLoadLibrary not implemented")
|
||||
cstderr.rawWrite("\n")
|
||||
quit(1)
|
||||
rawQuit(1)
|
||||
|
||||
proc nimLoadLibrary(path: string): LibHandle =
|
||||
cstderr.rawWrite("nimLoadLibrary not implemented")
|
||||
cstderr.rawWrite("\n")
|
||||
quit(1)
|
||||
rawQuit(1)
|
||||
|
||||
|
||||
proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr =
|
||||
cstderr.rawWrite("nimGetProAddr not implemented")
|
||||
cstderr.rawWrite(name)
|
||||
cstderr.rawWrite("\n")
|
||||
quit(1)
|
||||
rawQuit(1)
|
||||
|
||||
else:
|
||||
{.error: "no implementation for dyncalls".}
|
||||
|
||||
@@ -415,7 +415,7 @@ proc nimLeaveFinally() {.compilerRtl.} =
|
||||
c_longjmp(excHandler.context, 1)
|
||||
else:
|
||||
reportUnhandledError(currException)
|
||||
quit(1)
|
||||
rawQuit(1)
|
||||
|
||||
when gotoBasedExceptions:
|
||||
var nimInErrorMode {.threadvar.}: bool
|
||||
@@ -430,13 +430,13 @@ when gotoBasedExceptions:
|
||||
if nimInErrorMode and currException != nil:
|
||||
reportUnhandledError(currException)
|
||||
currException = nil
|
||||
quit(1)
|
||||
rawQuit(1)
|
||||
|
||||
proc raiseExceptionAux(e: sink(ref Exception)) {.nodestroy.} =
|
||||
when defined(nimPanics):
|
||||
if e of Defect:
|
||||
reportUnhandledError(e)
|
||||
quit(1)
|
||||
rawQuit(1)
|
||||
|
||||
if localRaiseHook != nil:
|
||||
if not localRaiseHook(e): return
|
||||
@@ -458,7 +458,7 @@ proc raiseExceptionAux(e: sink(ref Exception)) {.nodestroy.} =
|
||||
c_longjmp(excHandler.context, 1)
|
||||
else:
|
||||
reportUnhandledError(e)
|
||||
quit(1)
|
||||
rawQuit(1)
|
||||
|
||||
proc raiseExceptionEx(e: sink(ref Exception), ename, procname, filename: cstring,
|
||||
line: int) {.compilerRtl, nodestroy.} =
|
||||
@@ -501,7 +501,7 @@ proc threadTrouble() =
|
||||
if currException != nil: reportUnhandledError(currException)
|
||||
except:
|
||||
discard
|
||||
quit 1
|
||||
rawQuit 1
|
||||
|
||||
proc writeStackTrace() =
|
||||
when hasSomeStackTrace:
|
||||
@@ -544,7 +544,7 @@ proc callDepthLimitReached() {.noinline.} =
|
||||
"-d:nimCallDepthLimit=<int> but really try to avoid deep " &
|
||||
"recursions instead.\n"
|
||||
showErrorMessage2(msg)
|
||||
quit(1)
|
||||
rawQuit(1)
|
||||
|
||||
proc nimFrame(s: PFrame) {.compilerRtl, inl, raises: [].} =
|
||||
if framePtr == nil:
|
||||
@@ -597,7 +597,7 @@ when defined(cpp) and appType != "lib" and not gotoBasedExceptions and
|
||||
else:
|
||||
writeToStdErr msg & "\n"
|
||||
|
||||
quit 1
|
||||
rawQuit 1
|
||||
|
||||
when not defined(noSignalHandler) and not defined(useNimRtl):
|
||||
type Sighandler = proc (a: cint) {.noconv, benign.}
|
||||
@@ -651,7 +651,7 @@ when not defined(noSignalHandler) and not defined(useNimRtl):
|
||||
# also return the correct exit code to the shell.
|
||||
discard c_raise(sign)
|
||||
else:
|
||||
quit(1)
|
||||
rawQuit(1)
|
||||
|
||||
var SIG_IGN {.importc: "SIG_IGN", header: "<signal.h>".}: Sighandler
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ elif (defined(nimQuirky) or defined(nimPanics)) and not defined(nimscript):
|
||||
add(buf, name exceptn)
|
||||
add(buf, "]\n")
|
||||
cstderr.rawWrite buf
|
||||
quit 1
|
||||
rawQuit 1
|
||||
|
||||
func sysFatal(exceptn: typedesc, message: string) {.inline, noreturn.} =
|
||||
sysFatal(exceptn, message, "")
|
||||
|
||||
@@ -161,7 +161,7 @@ template gcAssert(cond: bool, msg: string) =
|
||||
writeStackTrace()
|
||||
#var x: ptr int
|
||||
#echo x[]
|
||||
quit 1
|
||||
rawQuit 1
|
||||
|
||||
proc addZCT(s: var CellSeq, c: PCell) {.noinline.} =
|
||||
if (c.refcount and ZctFlag) == 0:
|
||||
@@ -626,7 +626,7 @@ when logGC:
|
||||
if cycleCheckA[i] == c: return true
|
||||
if cycleCheckALen == len(cycleCheckA):
|
||||
gcAssert(false, "cycle detection overflow")
|
||||
quit 1
|
||||
rawQuit 1
|
||||
cycleCheckA[cycleCheckALen] = c
|
||||
inc cycleCheckALen
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ template gcAssert(cond: bool, msg: string) =
|
||||
echo "[GCASSERT] ", msg
|
||||
GC_disable()
|
||||
writeStackTrace()
|
||||
quit 1
|
||||
rawQuit 1
|
||||
|
||||
proc cellToUsr(cell: PCell): pointer {.inline.} =
|
||||
# convert object (=pointer to refcount) to pointer to userdata
|
||||
|
||||
@@ -472,7 +472,7 @@ proc nimRegisterGlobalMarker(markerProc: GlobalMarkerProc) {.compilerproc.} =
|
||||
inc globalMarkersLen
|
||||
else:
|
||||
cstderr.rawWrite("[GC] cannot register global variable; too many global variables")
|
||||
quit 1
|
||||
rawQuit 1
|
||||
|
||||
proc nimRegisterThreadLocalMarker(markerProc: GlobalMarkerProc) {.compilerproc.} =
|
||||
if threadLocalMarkersLen <= high(threadLocalMarkers):
|
||||
@@ -480,4 +480,4 @@ proc nimRegisterThreadLocalMarker(markerProc: GlobalMarkerProc) {.compilerproc.}
|
||||
inc threadLocalMarkersLen
|
||||
else:
|
||||
cstderr.rawWrite("[GC] cannot register thread local variable; too many thread local variables")
|
||||
quit 1
|
||||
rawQuit 1
|
||||
|
||||
@@ -24,7 +24,7 @@ proc nimRegisterGlobalMarker(markerProc: GlobalMarkerProc) {.compilerproc.} =
|
||||
inc globalMarkersLen
|
||||
else:
|
||||
cstderr.rawWrite("[GC] cannot register global variable; too many global variables")
|
||||
quit 1
|
||||
rawQuit 1
|
||||
|
||||
proc nimRegisterThreadLocalMarker(markerProc: GlobalMarkerProc) {.compilerproc.} =
|
||||
if threadLocalMarkersLen <= high(threadLocalMarkers):
|
||||
@@ -32,7 +32,7 @@ proc nimRegisterThreadLocalMarker(markerProc: GlobalMarkerProc) {.compilerproc.}
|
||||
inc threadLocalMarkersLen
|
||||
else:
|
||||
cstderr.rawWrite("[GC] cannot register thread local variable; too many thread local variables")
|
||||
quit 1
|
||||
rawQuit 1
|
||||
|
||||
proc traverseGlobals*() =
|
||||
for i in 0..globalMarkersLen-1:
|
||||
|
||||
@@ -90,7 +90,7 @@ template gcAssert(cond: bool, msg: string) =
|
||||
if not cond:
|
||||
cstderr.rawWrite "[GCASSERT] "
|
||||
cstderr.rawWrite msg
|
||||
quit 1
|
||||
rawQuit 1
|
||||
|
||||
proc cellToUsr(cell: PCell): pointer {.inline.} =
|
||||
# convert object (=pointer to refcount) to pointer to userdata
|
||||
|
||||
@@ -72,7 +72,7 @@ proc addEntry(entry: LogEntry) =
|
||||
cprintf("interesting %s:%ld %s\n", entry.file, entry.line, entry.op)
|
||||
let x = cast[proc() {.nimcall, tags: [], gcsafe, raises: [].}](writeStackTrace)
|
||||
x()
|
||||
quit 1
|
||||
rawQuit 1
|
||||
#if gLog.count > high(gLog.data):
|
||||
# gLogger(gLog)
|
||||
# gLog.count = 0
|
||||
|
||||
@@ -46,7 +46,7 @@ else:
|
||||
proc raiseOutOfMem() {.noinline.} =
|
||||
if outOfMemHook != nil: outOfMemHook()
|
||||
cstderr.rawWrite("out of memory\n")
|
||||
quit(1)
|
||||
rawQuit(1)
|
||||
|
||||
when defined(boehmgc):
|
||||
include system / mm / boehm
|
||||
|
||||
@@ -114,7 +114,7 @@ template orcAssert(cond, msg) =
|
||||
when logOrc:
|
||||
if not cond:
|
||||
cfprintf(cstderr, "[Bug!] %s\n", msg)
|
||||
quit 1
|
||||
rawQuit 1
|
||||
|
||||
when logOrc:
|
||||
proc strstr(s, sub: cstring): cstring {.header: "<string.h>", importc.}
|
||||
@@ -143,7 +143,7 @@ proc unregisterCycle(s: Cell) =
|
||||
when false:
|
||||
if idx >= roots.len or idx < 0:
|
||||
cprintf("[Bug!] %ld\n", idx)
|
||||
quit 1
|
||||
rawQuit 1
|
||||
roots.d[idx] = roots.d[roots.len-1]
|
||||
roots.d[idx][0].rootIdx = idx+1
|
||||
dec roots.len
|
||||
|
||||
@@ -189,7 +189,7 @@ elif defined(windows) and not defined(StandaloneHeapSize):
|
||||
when reallyOsDealloc:
|
||||
if virtualFree(p, 0, MEM_RELEASE) == 0:
|
||||
cprintf "virtualFree failing!"
|
||||
quit 1
|
||||
rawQuit 1
|
||||
#VirtualFree(p, size, MEM_DECOMMIT)
|
||||
|
||||
elif hostOS == "standalone" or defined(StandaloneHeapSize):
|
||||
|
||||
@@ -122,4 +122,4 @@ when not defined(useNimRtl):
|
||||
if nimThreadVarsSize() > sizeof(ThreadLocalStorage):
|
||||
c_fprintf(cstderr, """too large thread local storage size requested,
|
||||
use -d:\"nimTlsSize=X\" to setup even more or stop using unittest.nim""")
|
||||
quit 1
|
||||
rawQuit 1
|
||||
|
||||
Reference in New Issue
Block a user