Patch Nim compiler and standard library

This commit is contained in:
Emery Hemingway 2021-02-18 19:42:23 +01:00
parent 1740628e41
commit 4a613364df
6 changed files with 753 additions and 6 deletions

View File

@ -2,16 +2,18 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1612545171, "lastModified": 1613672748,
"narHash": "sha256-AZkSuO7H055eDD4KWBEDCX/R5fvw0vUMCErvQvYSEhA=", "narHash": "sha256-8f/GGmO8zWSQj2lVjoDyQDURk6Nx9lY0VC7MwkE/Y8U=",
"owner": "NixOS", "owner": "ehmry",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "536fe36e23ab0fc8b7f35c24603422eee9fc17a2", "rev": "5a18ecda0f9f79e7d1de49512ae74c01ddbb4909",
"type": "github" "type": "github"
}, },
"original": { "original": {
"id": "nixpkgs", "owner": "ehmry",
"type": "indirect" "ref": "genodepkgs",
"repo": "nixpkgs",
"type": "github"
} }
}, },
"root": { "root": {

View File

@ -1,6 +1,8 @@
{ {
description = "Genode packages"; description = "Genode packages";
inputs.nixpkgs.url = "github:ehmry/nixpkgs/genodepkgs";
outputs = { self, nixpkgs }: outputs = { self, nixpkgs }:
let let
systems = { systems = {

View File

@ -142,6 +142,16 @@ in nullPkgs // {
ncurses = addPatchesHost [ ./ncurses/genode.patch ] ncurses; ncurses = addPatchesHost [ ./ncurses/genode.patch ] ncurses;
nim = overrideAttrsTarget (attrs: {
postInstall = ''
sed \
-e '/cc = gcc/d' \
-i $out/etc/nim/nim.cfg
'';
}) prev.nim;
nim-unwrapped = addPatchesTarget [ ./nim/genode.patch ] prev.nim-unwrapped;
openssl = openssl =
overrideHost { static = true; } # shared library comes out stupid big overrideHost { static = true; } # shared library comes out stupid big
(overrideAttrsHost (attrs: { (overrideAttrsHost (attrs: {

676
overlay/nim/genode.patch Normal file
View File

@ -0,0 +1,676 @@
From 30a1dc84498b6de491aecb1ee1bada16d0731564 Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Sat, 15 Feb 2020 12:47:47 +0100
Subject: [PATCH 1/7] Replace 'cstderr.rawWrite' with 'writeToStdErr'
Use a procedure that is easy to replace on platforms without UNIX file
descriptors.
---
lib/system.nim | 10 +++++-----
lib/system/arc.nim | 10 +++++-----
lib/system/dyncalls.nim | 34 +++++++++++++++++-----------------
lib/system/excpt.nim | 7 ++++++-
lib/system/fatal.nim | 4 ++--
lib/system/gc.nim | 8 ++++----
lib/system/gc_common.nim | 4 ++--
lib/system/gc_hooks.nim | 4 ++--
lib/system/gc_ms.nim | 4 ++--
lib/system/mmdisp.nim | 2 +-
lib/system/orc.nim | 12 ++++++------
11 files changed, 52 insertions(+), 47 deletions(-)
diff --git a/lib/system.nim b/lib/system.nim
index 2b66d637f..9fb5e5ac5 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1194,9 +1194,9 @@ else:
template sysAssert(cond: bool, msg: string) =
when defined(useSysAssert):
if not cond:
- cstderr.rawWrite "[SYSASSERT] "
- cstderr.rawWrite msg
- cstderr.rawWrite "\n"
+ writeToStdErr "[SYSASSERT] "
+ writeToStdErr msg
+ writeToStdErr "\n"
quit 1
const hasAlloc = (hostOS != "standalone" or not defined(nogc)) and not defined(nimscript)
@@ -2414,8 +2414,8 @@ proc quit*(errormsg: string, errorcode = QuitFailure) {.noreturn.} =
when nimvm:
echo errormsg
else:
- cstderr.rawWrite(errormsg)
- cstderr.rawWrite("\n")
+ writeToStdErr(errormsg)
+ writeToStdErr("\n")
quit(errorcode)
{.pop.} # checks: off
diff --git a/lib/system/arc.nim b/lib/system/arc.nim
index 4c97f1aa0..0087d286c 100644
--- a/lib/system/arc.nim
+++ b/lib/system/arc.nim
@@ -150,7 +150,7 @@ proc nimRawDispose(p: pointer, alignment: int) {.compilerRtl.} =
cprintf("[Freed] %p\n", p -! sizeof(RefHeader))
when defined(nimOwnedEnabled):
if head(p).rc >= rcIncrement:
- cstderr.rawWrite "[FATAL] dangling references exist\n"
+ writeToStdErr "[FATAL] dangling references exist\n"
quit 1
when defined(nimArcDebug):
# we do NOT really free the memory here in order to reliably detect use-after-frees
@@ -168,12 +168,12 @@ proc nimDestroyAndDispose(p: pointer) {.compilerRtl, raises: [].} =
if rti.destructor != nil:
cast[DestructorProc](rti.destructor)(p)
when false:
- cstderr.rawWrite cast[ptr PNimTypeV2](p)[].name
- cstderr.rawWrite "\n"
+ writeToStdErr cast[ptr PNimTypeV2](p)[].name
+ writeToStdErr "\n"
if d == nil:
- cstderr.rawWrite "bah, nil\n"
+ writeToStdErr "bah, nil\n"
else:
- cstderr.rawWrite "has destructor!\n"
+ writeToStdErr "has destructor!\n"
nimRawDispose(p, rti.align)
when defined(gcOrc):
diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim
index 1b0a3e64c..9a0cb3347 100644
--- a/lib/system/dyncalls.nim
+++ b/lib/system/dyncalls.nim
@@ -20,15 +20,15 @@ const
proc nimLoadLibraryError(path: string) =
# carefully written to avoid memory allocation:
const prefix = "could not load: "
- cstderr.rawWrite(prefix)
- cstderr.rawWrite(path)
+ writeToStdErr(prefix)
+ writeToStdErr(path)
when not defined(nimDebugDlOpen) and not defined(windows):
- cstderr.rawWrite("\n(compile with -d:nimDebugDlOpen for more information)")
+ writeToStdErr("\n(compile with -d:nimDebugDlOpen for more information)")
when defined(windows):
const badExe = "\n(bad format; library may be wrong architecture)"
let loadError = GetLastError()
if loadError == ERROR_BAD_EXE_FORMAT:
- cstderr.rawWrite(badExe)
+ writeToStdErr(badExe)
when defined(guiapp):
# Because console output is not shown in GUI apps, display the error as a
# message box instead:
@@ -46,14 +46,14 @@ proc nimLoadLibraryError(path: string) =
if loadError == ERROR_BAD_EXE_FORMAT and msgLeft >= badExe.len:
copyMem(msg[msgIdx].addr, badExe.cstring, badExe.len)
discard MessageBoxA(nil, msg[0].addr, nil, 0)
- cstderr.rawWrite("\n")
+ writeToStdErr("\n")
quit(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")
+ writeToStdErr("could not import: ")
+ writeToStdErr(name)
+ writeToStdErr("\n")
quit(1)
# this code was inspired from Lua's source code:
@@ -98,8 +98,8 @@ when defined(posix):
when defined(nimDebugDlOpen):
let error = dlerror()
if error != nil:
- cstderr.rawWrite(error)
- cstderr.rawWrite("\n")
+ writeToStdErr(error)
+ writeToStdErr("\n")
proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr =
result = dlsym(lib, name)
@@ -181,20 +181,20 @@ elif defined(genode):
elif defined(nintendoswitch) or defined(freertos):
proc nimUnloadLibrary(lib: LibHandle) =
- cstderr.rawWrite("nimUnLoadLibrary not implemented")
- cstderr.rawWrite("\n")
+ writeToStdErr("nimUnLoadLibrary not implemented")
+ writeToStdErr("\n")
quit(1)
proc nimLoadLibrary(path: string): LibHandle =
- cstderr.rawWrite("nimLoadLibrary not implemented")
- cstderr.rawWrite("\n")
+ writeToStdErr("nimLoadLibrary not implemented")
+ writeToStdErr("\n")
quit(1)
proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr =
- cstderr.rawWrite("nimGetProAddr not implemented")
- cstderr.rawWrite(name)
- cstderr.rawWrite("\n")
+ writeToStdErr("nimGetProAddr not implemented")
+ writeToStdErr(name)
+ writeToStdErr("\n")
quit(1)
else:
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index 1a7473a76..8ac4dcb9f 100644
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -24,8 +24,13 @@ when defined(windows):
proc GetLastError(): int32 {.header: "<windows.h>", nodecl.}
const ERROR_BAD_EXE_FORMAT = 193
-when not defined(windows) or not defined(guiapp):
+elif defined(genode):
+ proc writeToStdErr(msg: cstring) =
+ {.emit: "Genode::error(Genode::Cstring(`msg`));".}
+
+elif not defined(guiapp):
proc writeToStdErr(msg: cstring) = rawWrite(cstderr, msg)
+
else:
proc MessageBoxA(hWnd: pointer, lpText, lpCaption: cstring, uType: int): int32 {.
header: "<windows.h>", nodecl.}
diff --git a/lib/system/fatal.nim b/lib/system/fatal.nim
index 761e0dd69..791361380 100644
--- a/lib/system/fatal.nim
+++ b/lib/system/fatal.nim
@@ -37,8 +37,8 @@ elif (defined(nimQuirky) or defined(nimPanics)) and not defined(nimscript):
add(buf, arg)
add(buf, " [")
add(buf, name exceptn)
- add(buf, "]\n")
- cstderr.rawWrite buf
+ add(buf, "]")
+ writeToStdErr buf
quit 1
proc sysFatal(exceptn: typedesc, message: string) {.inline, noreturn.} =
diff --git a/lib/system/gc.nim b/lib/system/gc.nim
index 1f7164266..c81ce1b12 100644
--- a/lib/system/gc.nim
+++ b/lib/system/gc.nim
@@ -105,11 +105,11 @@ when not defined(useNimRtl):
template gcAssert(cond: bool, msg: string) =
when defined(useGcAssert):
if not cond:
- cstderr.rawWrite "[GCASSERT] "
- cstderr.rawWrite msg
+ writeToStdErr "[GCASSERT] "
+ writeToStdErr msg
when defined(logGC):
- cstderr.rawWrite "[GCASSERT] statistics:\L"
- cstderr.rawWrite GC_getStatistics()
+ writeToStdErr "[GCASSERT] statistics:\L"
+ writeToStdErr GC_getStatistics()
GC_disable()
writeStackTrace()
#var x: ptr int
diff --git a/lib/system/gc_common.nim b/lib/system/gc_common.nim
index 658c5d025..60d4f785e 100644
--- a/lib/system/gc_common.nim
+++ b/lib/system/gc_common.nim
@@ -471,7 +471,7 @@ proc nimRegisterGlobalMarker(markerProc: GlobalMarkerProc) {.compilerproc.} =
globalMarkers[globalMarkersLen] = markerProc
inc globalMarkersLen
else:
- cstderr.rawWrite("[GC] cannot register global variable; too many global variables")
+ writeToStdErr("[GC] cannot register global variable; too many global variables")
quit 1
proc nimRegisterThreadLocalMarker(markerProc: GlobalMarkerProc) {.compilerproc.} =
@@ -479,5 +479,5 @@ proc nimRegisterThreadLocalMarker(markerProc: GlobalMarkerProc) {.compilerproc.}
threadLocalMarkers[threadLocalMarkersLen] = markerProc
inc threadLocalMarkersLen
else:
- cstderr.rawWrite("[GC] cannot register thread local variable; too many thread local variables")
+ writeToStdErr("[GC] cannot register thread local variable; too many thread local variables")
quit 1
diff --git a/lib/system/gc_hooks.nim b/lib/system/gc_hooks.nim
index 70f02e657..a55359b61 100644
--- a/lib/system/gc_hooks.nim
+++ b/lib/system/gc_hooks.nim
@@ -23,7 +23,7 @@ proc nimRegisterGlobalMarker(markerProc: GlobalMarkerProc) {.compilerproc.} =
globalMarkers[globalMarkersLen] = markerProc
inc globalMarkersLen
else:
- cstderr.rawWrite("[GC] cannot register global variable; too many global variables")
+ writeToStdErr("[GC] cannot register global variable; too many global variables")
quit 1
proc nimRegisterThreadLocalMarker(markerProc: GlobalMarkerProc) {.compilerproc.} =
@@ -31,7 +31,7 @@ proc nimRegisterThreadLocalMarker(markerProc: GlobalMarkerProc) {.compilerproc.}
threadLocalMarkers[threadLocalMarkersLen] = markerProc
inc threadLocalMarkersLen
else:
- cstderr.rawWrite("[GC] cannot register thread local variable; too many thread local variables")
+ writeToStdErr("[GC] cannot register thread local variable; too many thread local variables")
quit 1
proc traverseGlobals*() =
diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim
index 852f5d7aa..c25ab499f 100644
--- a/lib/system/gc_ms.nim
+++ b/lib/system/gc_ms.nim
@@ -88,8 +88,8 @@ when not defined(useNimRtl):
template gcAssert(cond: bool, msg: string) =
when defined(useGcAssert):
if not cond:
- cstderr.rawWrite "[GCASSERT] "
- cstderr.rawWrite msg
+ writeToStdErr "[GCASSERT] "
+ writeToStdErr msg
quit 1
proc cellToUsr(cell: PCell): pointer {.inline.} =
diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim
index 5fe1960d1..beca06472 100644
--- a/lib/system/mmdisp.nim
+++ b/lib/system/mmdisp.nim
@@ -45,7 +45,7 @@ else:
proc raiseOutOfMem() {.noinline.} =
if outOfMemHook != nil: outOfMemHook()
- cstderr.rawWrite("out of memory\n")
+ writeToStdErr("out of memory")
quit(1)
when defined(boehmgc):
diff --git a/lib/system/orc.nim b/lib/system/orc.nim
index 28f8e5808..49fc43ad4 100644
--- a/lib/system/orc.nim
+++ b/lib/system/orc.nim
@@ -77,16 +77,16 @@ proc free(s: Cell; desc: PNimTypeV2) {.inline.} =
cast[DisposeProc](desc.disposeImpl)(p)
when false:
- cstderr.rawWrite desc.name
- cstderr.rawWrite " "
+ writeToStdErr desc.name
+ writeToStdErr " "
if desc.disposeImpl == nil:
- cstderr.rawWrite "lacks dispose"
+ writeToStdErr "lacks dispose"
if desc.traceImpl != nil:
- cstderr.rawWrite ", but has trace\n"
+ writeToStdErr ", but has trace\n"
else:
- cstderr.rawWrite ", and lacks trace\n"
+ writeToStdErr ", and lacks trace\n"
else:
- cstderr.rawWrite "has dispose!\n"
+ writeToStdErr "has dispose!\n"
nimRawDispose(p, desc.align)
--
2.29.2
From 5e768437f34cc8965246f9ec996a285a0466c525 Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Sat, 8 Feb 2020 14:32:18 +0100
Subject: [PATCH 2/7] Genode: move dyncall failures to runtime
Do not use the "error" pragma to warn that dynamic library loading is
not implemented, print a message at runtime and exit.
---
lib/pure/dynlib.nim | 26 ++++++++++++++++++++++++++
lib/system/dyncalls.nim | 15 +++++++++------
2 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/lib/pure/dynlib.nim b/lib/pure/dynlib.nim
index 42d13535f..d8934b0f0 100644
--- a/lib/pure/dynlib.nim
+++ b/lib/pure/dynlib.nim
@@ -150,6 +150,32 @@ elif defined(nintendoswitch):
proc symAddr(lib: LibHandle, name: cstring): pointer =
raise newException(OSError, "symAddr not implemented on Nintendo Switch!")
+elif defined(genode):
+ #
+ # =========================================================================
+ # Not implemented for Genode without POSIX. Raise an error if called.
+ # =========================================================================
+ #
+
+ template raiseErr(prc: string) =
+ raise newException(OSError, prc & " not implemented, compile with POSIX suport")
+
+ proc dlclose(lib: LibHandle) =
+ raiseErr(OSError, "dlclose")
+ proc dlopen(path: cstring, mode: int): LibHandle =
+ raiseErr(OSError, "dlopen")
+ proc dlsym(lib: LibHandle, name: cstring): pointer =
+ raiseErr(OSError, "dlsym")
+ proc loadLib(path: string, global_symbols = false): LibHandle =
+ raiseErr(OSError, "loadLib")
+ proc loadLib(): LibHandle =
+ raiseErr(OSError, "loadLib")
+ proc unloadLib(lib: LibHandle) =
+ raiseErr(OSError, "unloadLib")
+ proc symAddr(lib: LibHandle, name: cstring): pointer =
+ raiseErr(OSError, "symAddr")
+
+
elif defined(windows) or defined(dos):
#
# =======================================================================
diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim
index 9a0cb3347..3df0e3af0 100644
--- a/lib/system/dyncalls.nim
+++ b/lib/system/dyncalls.nim
@@ -170,14 +170,17 @@ elif defined(windows) or defined(dos):
elif defined(genode):
- proc nimUnloadLibrary(lib: LibHandle) {.
- error: "nimUnloadLibrary not implemented".}
+ proc nimUnloadLibrary(lib: LibHandle) =
+ writeToStdErr("nimUnloadLibrary not implemented")
+ quit(1)
- proc nimLoadLibrary(path: string): LibHandle {.
- error: "nimLoadLibrary not implemented".}
+ proc nimLoadLibrary(path: string): LibHandle =
+ writeToStdErr("nimLoadLibrary not implemented")
+ quit(1)
- proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr {.
- error: "nimGetProcAddr not implemented".}
+ proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr =
+ writeToStdErr("nimGetProcAddr not implemented")
+ quit(1)
elif defined(nintendoswitch) or defined(freertos):
proc nimUnloadLibrary(lib: LibHandle) =
--
2.29.2
From a5abcb5a4ebf704642ada062da5c5a2a98668356 Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Tue, 15 Oct 2019 10:19:27 +0200
Subject: [PATCH 3/7] Genode: use stricter dataspace type in page allocator
---
lib/genode/alloc.nim | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/lib/genode/alloc.nim b/lib/genode/alloc.nim
index a21a3ad7b..3ddd3074b 100644
--- a/lib/genode/alloc.nim
+++ b/lib/genode/alloc.nim
@@ -17,18 +17,18 @@ when not defined(genode):
when not declared(GenodeEnv):
include genode/env
-type DataspaceCapability {.
- importcpp: "Genode::Dataspace_capability", pure.} = object
+type RamDataspaceCapability {.
+ importcpp: "Genode::Ram_dataspace_capability", pure.} = object
type
Map = object
attachment: pointer
size: int
- ds: DataspaceCapability
+ ds: RamDataspaceCapability
SlabMeta = object
next: ptr MapSlab
- ds: DataspaceCapability
+ ds: RamDataspaceCapability
MapSlab = object
meta: SlabMeta
@@ -45,11 +45,11 @@ proc capsAvail(env: GenodeEnv): int {.
## Return the number of available capabilities.
## Each dataspace allocation consumes a capability.
-proc allocDataspace(env: GenodeEnv; size: int): DataspaceCapability {.
+proc allocDataspace(env: GenodeEnv; size: int): RamDataspaceCapability {.
importcpp: "#->pd().alloc(@)".}
## Allocate a dataspace and its capability.
-proc attachDataspace(env: GenodeEnv; ds: DataspaceCapability): pointer {.
+proc attachDataspace(env: GenodeEnv; ds: RamDataspaceCapability): pointer {.
importcpp: "#->rm().attach(@)".}
## Attach a dataspace into the component address-space.
@@ -57,7 +57,7 @@ proc detachAddress(env: GenodeEnv; p: pointer) {.
importcpp: "#->rm().detach(@)".}
## Detach a dataspace from the component address-space.
-proc freeDataspace(env: GenodeEnv; ds: DataspaceCapability) {.
+proc freeDataspace(env: GenodeEnv; ds: RamDataspaceCapability) {.
importcpp: "#->pd().free(@)".}
## Free a dataspace.
--
2.29.2
From 88ec46acdb8cd9296389d7a783cab8b3973526e0 Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Tue, 7 Apr 2020 10:03:13 +0530
Subject: [PATCH 4/7] Genode: remove compiler configuratin from nim.cfg
Self-hosting Nim is not supported on Genode and defining the
cross-compilation evironment is out-of-scope.
---
config/nim.cfg | 17 -----------------
1 file changed, 17 deletions(-)
diff --git a/config/nim.cfg b/config/nim.cfg
index a33a2f0a9..aab7941c7 100644
--- a/config/nim.cfg
+++ b/config/nim.cfg
@@ -299,23 +299,6 @@ tcc.options.always = "-w"
@if genode:
noCppExceptions # avoid std C++
tlsEmulation:on # no TLS segment register magic
- @if i386 or amd64:
- gcc.exe = "genode-x86-gcc"
- gcc.cpp.exe = "genode-x86-g++"
- gcc.cpp.linkerexe = "genode-x86-ld"
- @elif arm:
- gcc.exe = "genode-arm-gcc"
- gcc.cpp.exe = "genode-arm-g++"
- gcc.cpp.linkerexe = "genode-arm-ld"
- @elif arm64:
- gcc.exe = "genode-aarch64-gcc"
- gcc.cpp.exe = "genode-aarch64-g++"
- gcc.cpp.linkerexe = "genode-aarch64-ld"
- @elif riscv64:
- gcc.exe = "genode-riscv-gcc"
- gcc.cpp.exe = "genode-riscv-g++"
- gcc.cpp.linkerexe = "genode-riscv-ld"
- @end
@end
@if arm or arm64:
--
2.29.2
From 117287e4f757d1136b7163a2fa64f1aa05f5841c Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Tue, 7 Apr 2020 10:49:20 +0530
Subject: [PATCH 5/7] Genode: select POSIX or native NimMain
---
compiler/cgen.nim | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index ac977b32b..4daaec79b 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -14,7 +14,7 @@ import
nversion, nimsets, msgs, bitsets, idents, types,
ccgutils, os, ropes, math, passes, wordrecg, treetab, cgmeth,
rodutils, renderer, cgendata, ccgmerge, aliases,
- lowerings, tables, sets, ndi, lineinfos, pathutils, transf, enumtostr,
+ lowerings, strtabs, tables, sets, ndi, lineinfos, pathutils, transf, enumtostr,
injectdestructors
when not defined(leanCompiler):
@@ -1443,10 +1443,20 @@ proc genMainProc(m: BModule) =
GenodeNimMain =
"extern Genode::Env *nim_runtime_env;$N" &
- "extern void nim_component_construct(Genode::Env*);$N$N" &
+ "extern \"C\" void nim_component_construct(Genode::Env*);$N$N" &
NimMainBody
- ComponentConstruct =
+ GenodeComponentConstruct =
+ "void Component::construct(Genode::Env &env) {$N" &
+ "\t// Set Env used during runtime initialization$N" &
+ "\tnim_runtime_env = &env;$N" &
+ "\t// Initialize runtime and globals$N" &
+ MainProcs &
+ "\t// Call application construct$N" &
+ "\tnim_component_construct(&env);$N" &
+ "}$N$N"
+
+ GenodePosixComponentConstruct =
"void Libc::Component::construct(Libc::Env &env) {$N" &
"\t// Set Env used during runtime initialization$N" &
"\tnim_runtime_env = &env;$N" &
@@ -1462,7 +1472,10 @@ proc genMainProc(m: BModule) =
m.config.globalOptions * {optGenGuiApp, optGenDynLib} != {}:
m.includeHeader("<windows.h>")
elif m.config.target.targetOS == osGenode:
- m.includeHeader("<libc/component.h>")
+ if m.config.symbols.hasKey "posix":
+ m.includeHeader("<libc/component.h>")
+ else:
+ m.includeHeader("<base/component.h>")
let initStackBottomCall =
if m.config.target.targetOS == osStandalone or m.config.selectedGC == gcNone: "".rope
@@ -1511,8 +1524,10 @@ proc genMainProc(m: BModule) =
const otherMain = WinCDllMain
appcg(m, m.s[cfsProcs], otherMain, [])
elif m.config.target.targetOS == osGenode:
- const otherMain = ComponentConstruct
- appcg(m, m.s[cfsProcs], otherMain, [])
+ if m.config.symbols.hasKey "posix":
+ appcg(m, m.s[cfsProcs], GenodePosixComponentConstruct, [])
+ else:
+ appcg(m, m.s[cfsProcs], GenodeComponentConstruct, [])
elif optGenDynLib in m.config.globalOptions:
const otherMain = PosixCDllMain
appcg(m, m.s[cfsProcs], otherMain, [])
--
2.29.2
From 28dadde5a935a0fd3df917f4266247e635306361 Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Fri, 4 Dec 2020 12:53:51 +0100
Subject: [PATCH 6/7] Genode: use new mutex API
---
lib/genode_cpp/syslocks.h | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/lib/genode_cpp/syslocks.h b/lib/genode_cpp/syslocks.h
index 8ba39abc2..c50180903 100644
--- a/lib/genode_cpp/syslocks.h
+++ b/lib/genode_cpp/syslocks.h
@@ -13,7 +13,7 @@
/* Genode includes */
#include <base/semaphore.h>
-#include <base/lock.h>
+#include <base/mutex.h>
namespace Nim {
struct SysLock;
@@ -22,15 +22,14 @@ namespace Nim {
struct Nim::SysLock
{
- Genode::Lock _lock_a, _lock_b;
+ Genode::Mutex _mutex_a, _mutex_b;
bool _locked;
void acquireSys()
{
- _lock_a.lock();
+ Genode::Mutex::Guard guard(_mutex_a);
_locked = true;
- _lock_a.unlock();
- _lock_b.lock();
+ _mutex_b.acquire();
}
bool tryAcquireSys()
@@ -38,23 +37,22 @@ struct Nim::SysLock
if (_locked)
return false;
- _lock_a.lock();
+ Genode::Mutex::Guard guard(_mutex_a);
+
if (_locked) {
- _lock_a.unlock();
return false;
} else {
_locked = true;
- _lock_b.lock();
- _lock_a.unlock();
+ _mutex_b.acquire();
return true;
}
}
void releaseSys()
{
+ Genode::Mutex::Guard guard(_mutex_a);
_locked = false;
- _lock_a.unlock();
- _lock_b.unlock();
+ _mutex_b.release();
}
};
--
2.29.2
From 6f0ac2fb946c804e2624bb7d17ae76fc0074f85e Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Thu, 18 Feb 2021 18:45:29 +0100
Subject: [PATCH 7/7] Genode: do not pass -ldl to linker
---
config/nim.cfg | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/nim.cfg b/config/nim.cfg
index aab7941c7..53bf8e8bb 100644
--- a/config/nim.cfg
+++ b/config/nim.cfg
@@ -111,7 +111,7 @@ path="$lib/pure"
@end
@if unix:
- @if not bsd or haiku:
+ @if not bsd or haiku or genode:
# -fopenmp
gcc.options.linker = "-ldl"
gcc.cpp.options.linker = "-ldl"
--
2.29.2

View File

@ -14,6 +14,7 @@ let
./bash.nix ./bash.nix
./hello.nix ./hello.nix
./log.nix ./log.nix
./nim.nix
./vmm_x86.nix ./vmm_x86.nix
]; ];

56
tests/nim.nix Normal file
View File

@ -0,0 +1,56 @@
{
name = "nim";
machine = { pkgs, lib, ... }: {
genode.init.children.test_nim = let
testNim = with pkgs;
stdenv.mkDerivation {
pname = "test-nim";
inherit (nim-unwrapped) version;
nativeBuildInputs = [ nim ];
dontUnpack = true;
dontConfigure = true;
buildPhase = ''
export HOME=$NIX_BUILD_TOP
cat << EOF > test_nim.nim
echo "Hello Nim world!"
EOF
nim cpp -d:posix -d:release test_nim
'';
installPhase = ''
install -Dt $out/bin test_nim
'';
};
in {
binary = "${testNim}/bin/test_nim";
extraInputs = with pkgs.genodePackages; [ libc stdcxx ];
configFile = builtins.toFile "nim.dhall" ''
let Genode = env:DHALL_GENODE
let Init = Genode.Init
let Child = Init.Child
let Libc = Genode.Libc
in λ(binary : Text)
Child.flat
Child.Attributes::{
, binary
, exitPropagate = True
, resources = Genode.Init.Resources::{
, caps = 500
, ram = Genode.units.MiB 10
}
, config = Libc.toConfig Libc.default
}
'';
};
};
testScript = ''
start_all()
machine.wait_until_serial_output("Hello Nim world!")
'';
}