Skip to content

Commit 79a3267

Browse files
zevvAraq
authored andcommitted
Added 'ansic' os support for minimal (embedded) targets (#13088)
* os:any implementation * os:asny: omit flock/funlock calls in echoBinSafe * Disabled default "unhandled expection" reporting for `--os:any` to reduce code size. Added unhandledExceptionHook instead which can be used to get a notification from Nim and handle it from the application.
1 parent d31e327 commit 79a3267

File tree

6 files changed

+85
-71
lines changed

6 files changed

+85
-71
lines changed

compiler/platform.nim

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type
2222
osNone, osDos, osWindows, osOs2, osLinux, osMorphos, osSkyos, osSolaris,
2323
osIrix, osNetbsd, osFreebsd, osOpenbsd, osDragonfly, osAix, osPalmos, osQnx,
2424
osAmiga, osAtari, osNetware, osMacos, osMacosx, osIos, osHaiku, osAndroid, osVxWorks
25-
osGenode, osJS, osNimVM, osStandalone, osNintendoSwitch
25+
osGenode, osJS, osNimVM, osStandalone, osNintendoSwitch, osAny
2626

2727
type
2828
TInfoOSProp* = enum
@@ -177,6 +177,10 @@ const
177177
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
178178
scriptExt: ".sh", curDir: ".", exeExt: ".elf", extSep: ".",
179179
props: {ospNeedsPIC, ospPosix}),
180+
(name: "Any", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
181+
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
182+
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
183+
props: {}),
180184
]
181185

182186
type

lib/system.nim

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2096,7 +2096,7 @@ template sysAssert(cond: bool, msg: string) =
20962096

20972097
const hasAlloc = (hostOS != "standalone" or not defined(nogc)) and not defined(nimscript)
20982098

2099-
when notJSnotNims and hostOS != "standalone":
2099+
when notJSnotNims and hostOS != "standalone" and hostOS != "any":
21002100
include "system/cgprocs"
21012101
when notJSnotNims and hasAlloc and not defined(nimSeqsV2):
21022102
proc addChar(s: NimString, c: char): NimString {.compilerproc, benign.}
@@ -3395,6 +3395,11 @@ var
33953395
##
33963396
## If the handler does not raise an exception, ordinary control flow
33973397
## continues and the program is terminated.
3398+
unhandledExceptionHook*: proc (e: ref Exception) {.nimcall, tags: [], benign, raises: [].}
3399+
## Set this variable to provide a procedure that should be called
3400+
## in case of an `unhandle exception` event. The standard handler
3401+
## writes an error message and terminates the program, except when
3402+
## using `--os:any`
33983403
33993404
type
34003405
PFrame* = ptr TFrame ## Represents a runtime frame of the call stack;
@@ -3745,7 +3750,7 @@ when not defined(JS):
37453750

37463751

37473752
when notJSnotNims:
3748-
when hostOS != "standalone":
3753+
when hostOS != "standalone" and hostOS != "any":
37493754
include "system/dyncalls"
37503755

37513756
include "system/sets"

lib/system/excpt.nim

Lines changed: 54 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ when defined(nativeStacktrace) and nativeStackTraceSupported:
210210
# interested in
211211
enabled = true
212212

213-
when not hasThreadSupport:
213+
when hasSomeStackTrace and not hasThreadSupport:
214214
var
215215
tempFrames: array[0..127, PFrame] # should not be alloc'd on stack
216216

@@ -261,52 +261,53 @@ proc `$`(s: seq[StackTraceEntry]): string =
261261
elif s[i].line == reraisedFromEnd: result.add "]]\n"
262262
else: addFrameEntry(result, s[i])
263263

264-
proc auxWriteStackTrace(f: PFrame, s: var string) =
265-
when hasThreadSupport:
264+
when hasSomeStackTrace:
265+
266+
proc auxWriteStackTrace(f: PFrame, s: var string) =
267+
when hasThreadSupport:
268+
var
269+
tempFrames: array[0..127, PFrame] # but better than a threadvar
270+
const
271+
firstCalls = 32
266272
var
267-
tempFrames: array[0..127, PFrame] # but better than a threadvar
268-
const
269-
firstCalls = 32
270-
var
271-
it = f
272-
i = 0
273-
total = 0
274-
# setup long head:
275-
while it != nil and i <= high(tempFrames)-firstCalls:
276-
tempFrames[i] = it
277-
inc(i)
278-
inc(total)
279-
it = it.prev
280-
# go up the stack to count 'total':
281-
var b = it
282-
while it != nil:
283-
inc(total)
284-
it = it.prev
285-
var skipped = 0
286-
if total > len(tempFrames):
287-
# skip N
288-
skipped = total-i-firstCalls+1
289-
for j in 1..skipped:
290-
if b != nil: b = b.prev
291-
# create '...' entry:
292-
tempFrames[i] = nil
293-
inc(i)
294-
# setup short tail:
295-
while b != nil and i <= high(tempFrames):
296-
tempFrames[i] = b
297-
inc(i)
298-
b = b.prev
299-
for j in countdown(i-1, 0):
300-
if tempFrames[j] == nil:
301-
add(s, "(")
302-
add(s, $skipped)
303-
add(s, " calls omitted) ...\n")
304-
else:
305-
addFrameEntry(s, tempFrames[j])
273+
it = f
274+
i = 0
275+
total = 0
276+
# setup long head:
277+
while it != nil and i <= high(tempFrames)-firstCalls:
278+
tempFrames[i] = it
279+
inc(i)
280+
inc(total)
281+
it = it.prev
282+
# go up the stack to count 'total':
283+
var b = it
284+
while it != nil:
285+
inc(total)
286+
it = it.prev
287+
var skipped = 0
288+
if total > len(tempFrames):
289+
# skip N
290+
skipped = total-i-firstCalls+1
291+
for j in 1..skipped:
292+
if b != nil: b = b.prev
293+
# create '...' entry:
294+
tempFrames[i] = nil
295+
inc(i)
296+
# setup short tail:
297+
while b != nil and i <= high(tempFrames):
298+
tempFrames[i] = b
299+
inc(i)
300+
b = b.prev
301+
for j in countdown(i-1, 0):
302+
if tempFrames[j] == nil:
303+
add(s, "(")
304+
add(s, $skipped)
305+
add(s, " calls omitted) ...\n")
306+
else:
307+
addFrameEntry(s, tempFrames[j])
306308

307-
proc stackTraceAvailable*(): bool
309+
proc stackTraceAvailable*(): bool
308310

309-
when hasSomeStackTrace:
310311
proc rawWriteStackTrace(s: var string) =
311312
when defined(nimStackTraceOverride):
312313
add(s, "Traceback (most recent call last, using override)\n")
@@ -351,7 +352,7 @@ var onUnhandledException*: (proc (errorMsg: string) {.
351352
## The default is to write a stacktrace to ``stderr`` and then call ``quit(1)``.
352353
## Unstable API.
353354

354-
proc reportUnhandledError(e: ref Exception) {.nodestroy.} =
355+
proc reportUnhandledErrorAux(e: ref Exception) {.nodestroy.} =
355356
when hasSomeStackTrace:
356357
var buf = newStringOfCap(2000)
357358
if e.trace.len == 0:
@@ -400,6 +401,14 @@ proc reportUnhandledError(e: ref Exception) {.nodestroy.} =
400401
else:
401402
showErrorMessage(tbuf())
402403

404+
proc reportUnhandledError(e: ref Exception) {.nodestroy.} =
405+
if unhandledExceptionHook != nil:
406+
unhandledExceptionHook(e)
407+
when hostOS != "any":
408+
reportUnhandledErrorAux(e)
409+
else:
410+
discard()
411+
403412
proc nimLeaveFinally() {.compilerRtl.} =
404413
when defined(cpp) and not defined(noCppExceptions):
405414
{.emit: "throw;".}
@@ -425,14 +434,6 @@ when gotoBasedExceptions:
425434
currException = nil
426435
quit(1)
427436

428-
addQuitProc(proc () {.noconv.} =
429-
if currException != nil:
430-
reportUnhandledError(currException)
431-
# emulate: ``programResult = 1`` via abort() and a nop signal handler.
432-
c_signal(SIGABRT, (proc (sign: cint) {.noconv, benign.} = discard))
433-
c_abort()
434-
)
435-
436437
proc raiseExceptionAux(e: sink(ref Exception)) {.nodestroy.} =
437438
if localRaiseHook != nil:
438439
if not localRaiseHook(e): return

lib/system/io.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ when declared(stdout):
615615
android_log_print(ANDROID_LOG_VERBOSE, "nim", s)
616616
else:
617617
# flockfile deadlocks some versions of Android 5.x.x
618-
when not defined(windows) and not defined(android) and not defined(nintendoswitch):
618+
when not defined(windows) and not defined(android) and not defined(nintendoswitch) and hostOS != "any":
619619
proc flockfile(f: File) {.importc, nodecl.}
620620
proc funlockfile(f: File) {.importc, nodecl.}
621621
flockfile(stdout)
@@ -629,7 +629,7 @@ when declared(stdout):
629629
const linefeed = "\n"
630630
discard c_fwrite(linefeed.cstring, linefeed.len, 1, stdout)
631631
discard c_fflush(stdout)
632-
when not defined(windows) and not defined(android) and not defined(nintendoswitch):
632+
when not defined(windows) and not defined(android) and not defined(nintendoswitch) and hostOS != "any":
633633
funlockfile(stdout)
634634
when defined(windows) and compileOption("threads"):
635635
releaseSys echoLock

lib/system/mmdisp.nim

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -354,11 +354,11 @@ elif defined(gogc):
354354
proc deallocOsPages(r: var MemRegion) {.inline.} = discard
355355
proc deallocOsPages() {.inline.} = discard
356356
357-
elif defined(nogc) and defined(useMalloc):
357+
elif (defined(nogc) or defined(gcDestructors)) and defined(useMalloc):
358358
359359
when not defined(useNimRtl):
360360
proc alloc(size: Natural): pointer =
361-
var x = c_malloc(size + sizeof(size))
361+
var x = c_malloc (size + sizeof(size)).csize_t
362362
if x == nil: raiseOutOfMem()
363363
364364
cast[ptr int](x)[] = size
@@ -371,7 +371,7 @@ elif defined(nogc) and defined(useMalloc):
371371
var x = cast[pointer](cast[int](p) - sizeof(newsize))
372372
let oldsize = cast[ptr int](x)[]
373373
374-
x = c_realloc(x, newsize + sizeof(newsize))
374+
x = c_realloc(x, (newsize + sizeof(newsize)).csize_t)
375375
376376
if x == nil: raiseOutOfMem()
377377
@@ -384,13 +384,13 @@ elif defined(nogc) and defined(useMalloc):
384384
proc dealloc(p: pointer) = c_free(cast[pointer](cast[int](p) - sizeof(int)))
385385
386386
proc allocShared(size: Natural): pointer =
387-
result = c_malloc(size)
387+
result = c_malloc(size.csize_t)
388388
if result == nil: raiseOutOfMem()
389389
proc allocShared0(size: Natural): pointer =
390390
result = alloc(size)
391391
zeroMem(result, size)
392392
proc reallocShared(p: pointer, newsize: Natural): pointer =
393-
result = c_realloc(p, newsize)
393+
result = c_realloc(p, newsize.csize_t)
394394
if result == nil: raiseOutOfMem()
395395
proc deallocShared(p: pointer) = c_free(p)
396396
@@ -400,7 +400,7 @@ elif defined(nogc) and defined(useMalloc):
400400
proc GC_setStrategy(strategy: GC_Strategy) = discard
401401
proc GC_enableMarkAndSweep() = discard
402402
proc GC_disableMarkAndSweep() = discard
403-
proc GC_getStatistics(): string = return ""
403+
#proc GC_getStatistics(): string = return ""
404404
405405
proc getOccupiedMem(): int = discard
406406
proc getFreeMem(): int = discard
@@ -410,13 +410,6 @@ elif defined(nogc) and defined(useMalloc):
410410
411411
proc initGC() = discard
412412
413-
proc newObj(typ: PNimType, size: int): pointer {.compilerproc.} =
414-
result = alloc0(size)
415-
proc newSeq(typ: PNimType, len: int): pointer {.compilerproc.} =
416-
result = newObj(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize))
417-
cast[PGenericSeq](result).len = len
418-
cast[PGenericSeq](result).reserved = len
419-
420413
proc newObjNoInit(typ: PNimType, size: int): pointer =
421414
result = alloc(size)
422415

lib/system/osalloc.nim

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,5 +295,16 @@ elif hostOS == "standalone" or defined(StandaloneHeapSize):
295295
proc osDeallocPages(p: pointer, size: int) {.inline.} =
296296
if bumpPointer-size == cast[int](p):
297297
dec bumpPointer, size
298+
299+
elif hostOS == "any":
300+
proc osAllocPages(size: int): pointer {.inline.} =
301+
result = c_malloc(size.csize_t)
302+
303+
proc osTryAllocPages(size: int): pointer {.inline.} =
304+
result = c_malloc(size.csize_t)
305+
306+
proc osDeallocPages(p: pointer, size: int) {.inline.} =
307+
c_free(p)
308+
298309
else:
299310
{.error: "Port memory manager to your platform".}

0 commit comments

Comments
 (0)