From 559a7615ad8e2e169aa9684f034c156881d88d4d Mon Sep 17 00:00:00 2001 From: Joey Date: Wed, 27 Jun 2018 19:35:09 +0900 Subject: Nintendo switch support (#8069) * Add config section for Nintendo Switch * Add compiler configuration for Nintendo Switch and it's CPU * Add specific lib code for Nintendo Switch * Add GC support for Nintendo Switch * Update changelog for Nintendo Switch * Update changelog with more info about fixed paths * Cleaned up GC memory management a bit * Relocate docs for Switch * Rename aarch64NoneElfGcc to nintendoSwitchGCC * Remove armv8a57 * Fix installer.ini * Reuse code in linux and amd64 * Add posix defs for nintendo switch * Add more defined sections for nintendo switch * Remove old comment * Add what's not supported for Nintendo Switch docs * Make nintendoswitch == posix * Remove DEVKITPRO references from nim.cfg * Make PR extccomp changes * Remove Result type alias * Add separate switch consts file * Update docs for nintendo switch * Fix travis errors with undefined consts and add correct wait.h procs --- lib/system/ansi_c.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/system/ansi_c.nim') diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim index 0bac979e7..52cb15e39 100644 --- a/lib/system/ansi_c.nim +++ b/lib/system/ansi_c.nim @@ -45,7 +45,7 @@ when defined(windows): SIGTERM = cint(15) elif defined(macosx) or defined(linux) or defined(freebsd) or defined(openbsd) or defined(netbsd) or defined(solaris) or - defined(dragonfly): + defined(dragonfly) or defined(nintendoswitch): const SIGABRT = cint(6) SIGFPE = cint(8) -- cgit 1.4.1-2-gfad0 From dfe3f160227dadd5d93bd6c697106e71899eccce Mon Sep 17 00:00:00 2001 From: Yuriy Glukhov Date: Fri, 13 Jul 2018 18:41:59 +0300 Subject: Don't depend on string.h in codegen (#8299) --- compiler/ccgexprs.nim | 34 +++++++++++++--------------------- compiler/cgen.nim | 13 +++---------- lib/pure/memfiles.nim | 3 +-- lib/system.nim | 34 +++++++++++++++++----------------- lib/system/alloc.nim | 4 ++-- lib/system/ansi_c.nim | 2 ++ lib/system/memory.nim | 47 +++++++++++++++++++++++++++++++++++++++++++++++ lib/system/sysio.nim | 2 +- lib/system/sysstr.nim | 2 +- 9 files changed, 87 insertions(+), 54 deletions(-) create mode 100644 lib/system/memory.nim (limited to 'lib/system/ansi_c.nim') diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 9b31167e3..2e9fb2cc2 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -257,9 +257,8 @@ proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = if needToCopy notin flags or tfShallow in skipTypes(dest.t, abstractVarRange).flags: if dest.storage == OnStack or not usesNativeGC(p.config): - useStringh(p.module) linefmt(p, cpsStmts, - "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n", + "#nimCopyMem((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n", addrLoc(p.config, dest), addrLoc(p.config, src), rdLoc(dest)) else: linefmt(p, cpsStmts, "#genericShallowAssign((void*)$1, (void*)$2, $3);$n", @@ -336,9 +335,8 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = if needsComplexAssignment(dest.t): genGenericAsgn(p, dest, src, flags) else: - useStringh(p.module) linefmt(p, cpsStmts, - "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n", + "#nimCopyMem((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n", rdLoc(dest), rdLoc(src), getTypeDesc(p.module, dest.t)) of tyOpenArray, tyVarargs: # open arrays are always on the stack - really? What if a sequence is @@ -349,16 +347,14 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = addrLoc(p.config, dest), addrLoc(p.config, src), genTypeInfo(p.module, dest.t, dest.lode.info)) else: - useStringh(p.module) linefmt(p, cpsStmts, - # bug #4799, keep the memcpy for a while - #"memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1[0])*$1Len_0);$n", + # bug #4799, keep the nimCopyMem for a while + #"#nimCopyMem((void*)$1, (NIM_CONST void*)$2, sizeof($1[0])*$1Len_0);$n", "$1 = $2;$n", rdLoc(dest), rdLoc(src)) of tySet: if mapType(p.config, ty) == ctArray: - useStringh(p.module) - linefmt(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, $3);$n", + linefmt(p, cpsStmts, "#nimCopyMem((void*)$1, (NIM_CONST void*)$2, $3);$n", rdLoc(dest), rdLoc(src), rope(getSize(p.config, dest.t))) else: linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) @@ -403,8 +399,7 @@ proc genDeepCopy(p: BProc; dest, src: TLoc) = genTypeInfo(p.module, dest.t, dest.lode.info)) of tySet: if mapType(p.config, ty) == ctArray: - useStringh(p.module) - linefmt(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, $3);$n", + linefmt(p, cpsStmts, "#nimCopyMem((void*)$1, (NIM_CONST void*)$2, $3);$n", rdLoc(dest), rdLoc(src), rope(getSize(p.config, dest.t))) else: linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) @@ -1481,9 +1476,8 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) = if op == mHigh: unaryExpr(p, e, d, "($1Len_0-1)") else: unaryExpr(p, e, d, "$1Len_0") of tyCString: - useStringh(p.module) - if op == mHigh: unaryExpr(p, e, d, "($1 ? (strlen($1)-1) : -1)") - else: unaryExpr(p, e, d, "($1 ? strlen($1) : 0)") + if op == mHigh: unaryExpr(p, e, d, "($1 ? (#nimCStrLen($1)-1) : -1)") + else: unaryExpr(p, e, d, "($1 ? #nimCStrLen($1) : 0)") of tyString: if not p.module.compileToCpp: if op == mHigh: unaryExpr(p, e, d, "($1 ? ($1->Sup.len-1) : -1)") @@ -1632,7 +1626,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) = " $3 = (($4[$1] & ~ $5[$1]) == 0);$n" & " if (!$3) break;}$n", "for ($1 = 0; $1 < $2; $1++) { $n" & " $3 = (($4[$1] & ~ $5[$1]) == 0);$n" & " if (!$3) break;}$n" & - "if ($3) $3 = (memcmp($4, $5, $2) != 0);$n", + "if ($3) $3 = (#nimCmpMem($4, $5, $2) != 0);$n", "&", "|", "& ~", "^"] var a, b, i: TLoc var setType = skipTypes(e.sons[1].typ, abstractVar) @@ -1671,11 +1665,10 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) = initLocExpr(p, e.sons[1], a) initLocExpr(p, e.sons[2], b) if d.k == locNone: getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyBool), d) - lineF(p, cpsStmts, lookupOpr[op], + linefmt(p, cpsStmts, lookupOpr[op], [rdLoc(i), rope(size), rdLoc(d), rdLoc(a), rdLoc(b)]) of mEqSet: - useStringh(p.module) - binaryExprChar(p, e, d, "(memcmp($1, $2, " & $(size) & ")==0)") + binaryExprChar(p, e, d, "(#nimCmpMem($1, $2, " & $(size) & ")==0)") of mMulSet, mPlusSet, mMinusSet, mSymDiffSet: # we inline the simple for loop for better code generation: getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyInt), i) # our counter @@ -1934,7 +1927,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = proc genSetConstr(p: BProc, e: PNode, d: var TLoc) = # example: { a..b, c, d, e, f..g } # we have to emit an expression of the form: - # memset(tmp, 0, sizeof(tmp)); inclRange(tmp, a, b); incl(tmp, c); + # nimZeroMem(tmp, sizeof(tmp)); inclRange(tmp, a, b); incl(tmp, c); # incl(tmp, d); incl(tmp, e); inclRange(tmp, f, g); var a, b, idx: TLoc @@ -1944,8 +1937,7 @@ proc genSetConstr(p: BProc, e: PNode, d: var TLoc) = if d.k == locNone: getTemp(p, e.typ, d) if getSize(p.config, e.typ) > 8: # big set: - useStringh(p.module) - lineF(p, cpsStmts, "memset($1, 0, sizeof($2));$n", + linefmt(p, cpsStmts, "#nimZeroMem($1, sizeof($2));$n", [rdLoc(d), getTypeDesc(p.module, e.typ)]) for it in e.sons: if it.kind == nkRange: diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 32891c62c..ea82c496f 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -80,11 +80,6 @@ proc isSimpleConst(typ: PType): bool = {tyTuple, tyObject, tyArray, tySet, tySequence} and not (t.kind == tyProc and t.callConv == ccClosure) -proc useStringh(m: BModule) = - if includesStringh notin m.flags: - incl m.flags, includesStringh - m.includeHeader("") - proc useHeader(m: BModule, sym: PSym) = if lfHeader in sym.loc.flags: assert(sym.annex != nil) @@ -320,10 +315,9 @@ proc resetLoc(p: BProc, loc: var TLoc) = # field, so disabling this should be safe: genObjectInit(p, cpsStmts, loc.t, loc, true) else: - useStringh(p.module) # array passed as argument decayed into pointer, bug #7332 # so we use getTypeDesc here rather than rdLoc(loc) - linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n", + linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));$n", addrLoc(p.config, loc), getTypeDesc(p.module, loc.t)) # XXX: We can be extra clever here and call memset only # on the bytes following the m_type field? @@ -336,11 +330,10 @@ proc constructLoc(p: BProc, loc: TLoc, isTemp = false) = getTypeDesc(p.module, typ)) else: if not isTemp or containsGarbageCollectedRef(loc.t): - # don't use memset for temporary values for performance if we can + # don't use nimZeroMem for temporary values for performance if we can # avoid it: if not isImportedCppType(typ): - useStringh(p.module) - linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n", + linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));$n", addrLoc(p.config, loc), getTypeDesc(p.module, typ)) genObjectInit(p, cpsStmts, loc.t, loc, true) diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index bda0ecb77..0249b7413 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -322,8 +322,7 @@ type MemSlice* = object ## represent slice of a MemFile for iteration over deli proc `==`*(x, y: MemSlice): bool = ## Compare a pair of MemSlice for strict equality. - proc memcmp(a, b: pointer, n:int):int {.importc: "memcmp",header: "string.h".} - result = (x.size == y.size and memcmp(x.data, y.data, x.size) == 0) + result = (x.size == y.size and equalMem(x.data, y.data, x.size)) proc `$`*(ms: MemSlice): string {.inline.} = ## Return a Nim string built from a MemSlice. diff --git a/lib/system.nim b/lib/system.nim index 10f1df150..fed02f6d0 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2903,6 +2903,22 @@ when not defined(JS): #and not defined(nimscript): ## useful for low-level file access include "system/ansi_c" + include "system/memory" + + proc zeroMem(p: pointer, size: Natural) = + nimZeroMem(p, size) + when declared(memTrackerOp): + memTrackerOp("zeroMem", p, size) + proc copyMem(dest, source: pointer, size: Natural) = + nimCopyMem(dest, source, size) + when declared(memTrackerOp): + memTrackerOp("copyMem", dest, size) + proc moveMem(dest, source: pointer, size: Natural) = + c_memmove(dest, source, size) + when declared(memTrackerOp): + memTrackerOp("moveMem", dest, size) + proc equalMem(a, b: pointer, size: Natural): bool = + nimCmpMem(a, b, size) == 0 proc cmp(x, y: string): int = when nimvm: @@ -2911,7 +2927,7 @@ when not defined(JS): #and not defined(nimscript): else: result = 0 else: let minlen = min(x.len, y.len) - result = int(c_memcmp(x.cstring, y.cstring, minlen.csize)) + result = int(nimCmpMem(x.cstring, y.cstring, minlen.csize)) if result == 0: result = x.len - y.len @@ -3200,22 +3216,6 @@ when not defined(JS): #and not defined(nimscript): when defined(memtracker): include "system/memtracker" - when not defined(nimscript): - proc zeroMem(p: pointer, size: Natural) = - c_memset(p, 0, size) - when declared(memTrackerOp): - memTrackerOp("zeroMem", p, size) - proc copyMem(dest, source: pointer, size: Natural) = - c_memcpy(dest, source, size) - when declared(memTrackerOp): - memTrackerOp("copyMem", dest, size) - proc moveMem(dest, source: pointer, size: Natural) = - c_memmove(dest, source, size) - when declared(memTrackerOp): - memTrackerOp("moveMem", dest, size) - proc equalMem(a, b: pointer, size: Natural): bool = - c_memcmp(a, b, size) == 0 - when hostOS == "standalone": include "system/embedded" else: diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index 6aef4f411..95becde22 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -830,7 +830,7 @@ proc rawDealloc(a: var MemRegion, p: pointer) = c.freeList = f when overwriteFree: # set to 0xff to check for usage after free bugs: - c_memset(cast[pointer](cast[int](p) +% sizeof(FreeCell)), -1'i32, + nimSetMem(cast[pointer](cast[int](p) +% sizeof(FreeCell)), -1'i32, s -% sizeof(FreeCell)) # check if it is not in the freeSmallChunks[s] list: if c.free < s: @@ -847,7 +847,7 @@ proc rawDealloc(a: var MemRegion, p: pointer) = s == 0, "rawDealloc 2") else: # set to 0xff to check for usage after free bugs: - when overwriteFree: c_memset(p, -1'i32, c.size -% bigChunkOverhead()) + when overwriteFree: nimSetMem(p, -1'i32, c.size -% bigChunkOverhead()) # free big chunk var c = cast[PBigChunk](c) dec a.occ, c.size diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim index 52cb15e39..4d21f8747 100644 --- a/lib/system/ansi_c.nim +++ b/lib/system/ansi_c.nim @@ -25,6 +25,8 @@ proc c_memset(p: pointer, value: cint, size: csize): pointer {. importc: "memset", header: "", discardable.} proc c_strcmp(a, b: cstring): cint {. importc: "strcmp", header: "", noSideEffect.} +proc c_strlen(a: cstring): csize {. + importc: "strlen", header: "", noSideEffect.} when defined(linux) and defined(amd64): type diff --git a/lib/system/memory.nim b/lib/system/memory.nim new file mode 100644 index 000000000..f86fd4696 --- /dev/null +++ b/lib/system/memory.nim @@ -0,0 +1,47 @@ +const useLibC = not defined(nimNoLibc) + +proc nimCopyMem(dest, source: pointer, size: Natural) {.compilerproc, inline.} = + when useLibC: + c_memcpy(dest, source, size) + else: + let d = cast[ptr UncheckedArray[byte]](dest) + let s = cast[ptr UncheckedArray[byte]](source) + var i = 0 + while i < size: + d[i] = s[i] + inc i + +proc nimSetMem(a: pointer, v: cint, size: Natural) {.inline.} = + when useLibC: + c_memset(a, v, size) + else: + let a = cast[ptr UncheckedArray[byte]](a) + var i = 0 + let v = cast[byte](v) + while i < size: + a[i] = v + inc i + +proc nimZeroMem(p: pointer, size: Natural) {.compilerproc, inline.} = + nimSetMem(p, 0, size) + +proc nimCmpMem(a, b: pointer, size: Natural): cint {.compilerproc, inline.} = + when useLibC: + c_memcmp(a, b, size) + else: + let a = cast[ptr UncheckedArray[byte]](a) + let b = cast[ptr UncheckedArray[byte]](b) + var i = 0 + while i < size: + let d = a[i].cint - b[i].cint + if d != 0: return d + inc i + +proc nimCStrLen(a: cstring): csize {.compilerproc, inline.} = + when useLibC: + c_strlen(a) + else: + var a = cast[ptr byte](a) + while a[] != 0: + a = cast[ptr byte](cast[uint](a) + 1) + inc result diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim index f3a576be0..2ece56916 100644 --- a/lib/system/sysio.nim +++ b/lib/system/sysio.nim @@ -154,7 +154,7 @@ proc readLine(f: File, line: var TaintedString): bool = while true: # memset to \L so that we can tell how far fgets wrote, even on EOF, where # fgets doesn't append an \L - c_memset(addr line.string[pos], '\L'.ord, sp) + nimSetMem(addr line.string[pos], '\L'.ord, sp) var fgetsSuccess = c_fgets(addr line.string[pos], sp, f) != nil if not fgetsSuccess: checkErr(f) let m = c_memchr(addr line.string[pos], '\L'.ord, sp) diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim index 90ae91cf5..8e9e18b05 100644 --- a/lib/system/sysstr.nim +++ b/lib/system/sysstr.nim @@ -32,7 +32,7 @@ proc cmpStrings(a, b: NimString): int {.inline, compilerProc.} = let blen = b.len let minlen = min(alen, blen) if minlen > 0: - result = c_memcmp(addr a.data, addr b.data, minlen.csize) + result = nimCmpMem(addr a.data, addr b.data, minlen.csize) if result == 0: result = alen - blen else: -- cgit 1.4.1-2-gfad0 From 6b40114f21e681b0110a74add7a61b16df4d2fb8 Mon Sep 17 00:00:00 2001 From: Yuriy Glukhov Date: Mon, 30 Jul 2018 12:10:51 +0300 Subject: Added c_abort to ansi_c (#8449) --- lib/system/ansi_c.nim | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/system/ansi_c.nim') diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim index 4d21f8747..f593d4c99 100644 --- a/lib/system/ansi_c.nim +++ b/lib/system/ansi_c.nim @@ -27,6 +27,9 @@ proc c_strcmp(a, b: cstring): cint {. importc: "strcmp", header: "", noSideEffect.} proc c_strlen(a: cstring): csize {. importc: "strlen", header: "", noSideEffect.} +proc c_abort() {. + importc: "abort", header: "", noSideEffect.} + when defined(linux) and defined(amd64): type -- cgit 1.4.1-2-gfad0 From 7ef268274f387530b85f5a9f704e0eda5a7aa022 Mon Sep 17 00:00:00 2001 From: alaviss Date: Tue, 14 Aug 2018 14:35:07 +0700 Subject: Haiku support for Nim (#8542) * posix_other: Haiku now has spawn.h This is added per https://dev.haiku-os.org/ticket/13446 * posix_other: Add Haiku specific Dirent members * cpuinfo: Add an implementation for Haiku * distros: Add basic Haiku support * encodings: update Haiku support * fenv, math: Haiku now provides libm * times: Add Haiku struct members * ansi_c, osalloc: Add Haiku constants * threads: Add Haiku support * testament: Haiku uses LIBRARY_PATH * nim.cfg: Update Haiku support libnetwork should only be linked if network functions are used * threads: Haiku does not support -pthread switch * tworkingdir: Haiku's env is in /bin * posix_other: add SIGKILLTHR for Haiku * sockets: link with libnetwork on Haiku * coro: correct ucontext.h location http://pubs.opengroup.org/onlinepubs/009696699/basedefs/ucontext.h.html * coro: ucontext backend is not available on Haiku Haiku doesn't provide the header, as it was removed from POSIX * coro: fix setjmp backend The compiler does not allow statements after a noreturn function * nativesockets: Haiku doesn't support AI_V4MAPPED * system: hostOS can contains "haiku" * os: add support for Haiku's packagefs packagefs is read-only, but there are writable holes to the underlying file system as well * os: update constant for Haiku --- config/nim.cfg | 16 +++++++++------- lib/deprecated/pure/sockets.nim | 2 ++ lib/posix/posix_other.nim | 12 +++++++++++- lib/pure/concurrency/cpuinfo.nim | 12 ++++++++++++ lib/pure/coro.nim | 18 +++++++++++------- lib/pure/distros.nim | 6 ++++++ lib/pure/encodings.nim | 4 +++- lib/pure/fenv.nim | 2 +- lib/pure/math.nim | 2 +- lib/pure/nativesockets.nim | 5 +++-- lib/pure/os.nim | 13 ++++++++++++- lib/pure/times.nim | 2 +- lib/system.nim | 2 +- lib/system/ansi_c.nim | 11 +++++++++++ lib/system/osalloc.nim | 3 +++ lib/system/threads.nim | 16 ++++++++++++++-- tests/osproc/texitsignal.nim | 5 ++++- tests/osproc/tworkingdir.nim | 2 ++ tests/testament/categories.nim | 10 +++++++--- 19 files changed, 114 insertions(+), 29 deletions(-) (limited to 'lib/system/ansi_c.nim') diff --git a/config/nim.cfg b/config/nim.cfg index c30190a18..af9df9c55 100644 --- a/config/nim.cfg +++ b/config/nim.cfg @@ -82,19 +82,21 @@ path="$lib/pure" clang.cpp.options.linker = "-ldl" tcc.options.linker = "-ldl" @end - @if bsd or haiku: + @if bsd: # BSD got posix_spawn only recently, so we deactivate it for osproc: define:useFork # at least NetBSD has problems with thread local storage: tlsEmulation:on @end @if haiku: - # -fopenmp - gcc.options.linker = "-lroot -lnetwork" - gcc.cpp.options.linker = "-lroot -lnetwork" - clang.options.linker = "-lroot -lnetwork" - clang.cpp.options.linker = "-lroot -lnetwork" - tcc.options.linker = "-lroot -lnetwork" + # Haiku currently have problems with TLS + # https://dev.haiku-os.org/ticket/14342 + tlsEmulation:on + gcc.options.linker = "-Wl,--as-needed -lnetwork" + gcc.cpp.options.linker = "-Wl,--as-needed -lnetwork" + clang.options.linker = "-Wl,--as-needed -lnetwork" + clang.cpp.options.linker = "-Wl,--as-needed -lnetwork" + tcc.options.linker = "-Wl,--as-needed -lnetwork" @end @end diff --git a/lib/deprecated/pure/sockets.nim b/lib/deprecated/pure/sockets.nim index 05aebef76..76a9044d8 100644 --- a/lib/deprecated/pure/sockets.nim +++ b/lib/deprecated/pure/sockets.nim @@ -36,6 +36,8 @@ include "system/inclrtl" when hostOS == "solaris": {.passl: "-lsocket -lnsl".} +elif hostOS == "haiku": + {.passl: "-lnetwork".} import os, parseutils from times import epochTime diff --git a/lib/posix/posix_other.nim b/lib/posix/posix_other.nim index b7570bd15..99d67824e 100644 --- a/lib/posix/posix_other.nim +++ b/lib/posix/posix_other.nim @@ -10,7 +10,7 @@ {.deadCodeElim: on.} # dce option deprecated const - hasSpawnH = not defined(haiku) # should exist for every Posix system nowadays + hasSpawnH = true # should exist for every Posix system nowadays hasAioH = defined(linux) when defined(linux) and not defined(android): @@ -43,6 +43,9 @@ type Dirent* {.importc: "struct dirent", header: "", final, pure.} = object ## dirent_t struct + when defined(haiku): + d_dev*: Dev ## Device (not POSIX) + d_pdev*: Dev ## Parent device (only for queries) (not POSIX) d_ino*: Ino ## File serial number. when defined(dragonfly): # DragonflyBSD doesn't have `d_reclen` field. @@ -54,6 +57,9 @@ type ## (not POSIX) when defined(linux) or defined(openbsd): d_off*: Off ## Not an offset. Value that ``telldir()`` would return. + elif defined(haiku): + d_pino*: Ino ## Parent inode (only for queries) (not POSIX) + d_reclen*: cushort ## Length of this record. (not POSIX) d_name*: array[0..255, char] ## Name of entry. @@ -599,6 +605,10 @@ else: MSG_NOSIGNAL* {.importc, header: "".}: cint ## No SIGPIPE generated when an attempt to send is made on a stream-oriented socket that is no longer connected. +when defined(haiku): + const + SIGKILLTHR* = 21 ## BeOS specific: Kill just the thread, not team + when hasSpawnH: when defined(linux): # better be safe than sorry; Linux has this flag, macosx doesn't, don't diff --git a/lib/pure/concurrency/cpuinfo.nim b/lib/pure/concurrency/cpuinfo.nim index 6d41aa1b2..541265da9 100644 --- a/lib/pure/concurrency/cpuinfo.nim +++ b/lib/pure/concurrency/cpuinfo.nim @@ -43,6 +43,14 @@ when defined(genode): proc affinitySpaceTotal(env: GenodeEnvPtr): cuint {. importcpp: "@->cpu().affinity_space().total()".} +when defined(haiku): + {.emit: "#include ".} + type + SystemInfo {.importc: "system_info", bycopy.} = object + cpuCount {.importc: "cpu_count".}: uint32 + + proc getSystemInfo(info: ptr SystemInfo): int32 {.importc: "get_system_info".} + proc countProcessors*(): int {.rtl, extern: "ncpi$1".} = ## returns the numer of the processors/cores the machine has. ## Returns 0 if it cannot be detected. @@ -86,6 +94,10 @@ proc countProcessors*(): int {.rtl, extern: "ncpi$1".} = result = sysconf(SC_NPROC_ONLN) elif defined(genode): result = runtimeEnv.affinitySpaceTotal().int + elif defined(haiku): + var sysinfo: SystemInfo + if getSystemInfo(addr sysinfo) == 0: + result = sysinfo.cpuCount.int else: result = sysconf(SC_NPROCESSORS_ONLN) if result <= 0: result = 0 diff --git a/lib/pure/coro.nim b/lib/pure/coro.nim index b6ef30e7c..6d7dcf078 100644 --- a/lib/pure/coro.nim +++ b/lib/pure/coro.nim @@ -43,6 +43,10 @@ when defined(windows): {.warning: "ucontext coroutine backend is not available on windows, defaulting to fibers.".} when defined(nimCoroutinesSetjmp): {.warning: "setjmp coroutine backend is not available on windows, defaulting to fibers.".} +elif defined(haiku): + const coroBackend = CORO_BACKEND_SETJMP + when defined(nimCoroutinesUcontext): + {.warning: "ucontext coroutine backend is not available on haiku, defaulting to setjmp".} elif defined(nimCoroutinesSetjmp) or defined(nimCoroutinesSetjmpBundled): const coroBackend = CORO_BACKEND_SETJMP else: @@ -55,21 +59,21 @@ when coroBackend == CORO_BACKEND_FIBERS: elif coroBackend == CORO_BACKEND_UCONTEXT: type - stack_t {.importc, header: "".} = object + stack_t {.importc, header: "".} = object ss_sp: pointer ss_flags: int ss_size: int - ucontext_t {.importc, header: "".} = object + ucontext_t {.importc, header: "".} = object uc_link: ptr ucontext_t uc_stack: stack_t Context = ucontext_t - proc getcontext(context: var ucontext_t): int32 {.importc, header: "".} - proc setcontext(context: var ucontext_t): int32 {.importc, header: "".} - proc swapcontext(fromCtx, toCtx: var ucontext_t): int32 {.importc, header: "".} - proc makecontext(context: var ucontext_t, fn: pointer, argc: int32) {.importc, header: "", varargs.} + proc getcontext(context: var ucontext_t): int32 {.importc, header: "".} + proc setcontext(context: var ucontext_t): int32 {.importc, header: "".} + proc swapcontext(fromCtx, toCtx: var ucontext_t): int32 {.importc, header: "".} + proc makecontext(context: var ucontext_t, fn: pointer, argc: int32) {.importc, header: "", varargs.} elif coroBackend == CORO_BACKEND_SETJMP: proc coroExecWithStack*(fn: pointer, stack: pointer) {.noreturn, importc: "narch_$1", fastcall.} @@ -190,7 +194,7 @@ proc switchTo(current, to: CoroutinePtr) = elif to.state == CORO_CREATED: # Coroutine is started. coroExecWithStack(runCurrentTask, to.stack.bottom) - doAssert false + #doAssert false else: {.error: "Invalid coroutine backend set.".} # Execution was just resumed. Restore frame information and set active stack. diff --git a/lib/pure/distros.nim b/lib/pure/distros.nim index 0adba5b1e..5847cfadb 100644 --- a/lib/pure/distros.nim +++ b/lib/pure/distros.nim @@ -126,6 +126,8 @@ type OpenBSD DragonFlyBSD + Haiku + const LacksDevPackages* = {Distribution.Gentoo, Distribution.Slackware, @@ -166,6 +168,8 @@ proc detectOsImpl(d: Distribution): bool = of Distribution.Solaris: let uname = toLowerAscii(uname()) result = ("sun" in uname) or ("solaris" in uname) + of Distribution.Haiku: + result = defined(haiku) else: let dd = toLowerAscii($d) result = dd in toLowerAscii(uname()) or dd in toLowerAscii(release()) @@ -224,6 +228,8 @@ proc foreignDepInstallCmd*(foreignPackageName: string): (string, bool) = result = ("pacman -S " & p, true) else: result = (" install " & p, true) + elif defined(haiku): + result = ("pkgman install " & p, true) else: result = ("brew install " & p, false) diff --git a/lib/pure/encodings.nim b/lib/pure/encodings.nim index 3c1cf73f4..2039a31be 100644 --- a/lib/pure/encodings.nim +++ b/lib/pure/encodings.nim @@ -255,7 +255,7 @@ when defined(windows): else: when defined(haiku): - const iconvDll = "(libc.so.6|libiconv.so|libtextencoding.so)" + const iconvDll = "libiconv.so" elif defined(macosx): const iconvDll = "libiconv.dylib" else: @@ -272,6 +272,8 @@ else: const EILSEQ = 86.cint elif defined(solaris): const EILSEQ = 88.cint + elif defined(haiku): + const EILSEQ = -2147454938.cint var errno {.importc, header: "".}: cint diff --git a/lib/pure/fenv.nim b/lib/pure/fenv.nim index c946c4261..0725973ca 100644 --- a/lib/pure/fenv.nim +++ b/lib/pure/fenv.nim @@ -12,7 +12,7 @@ {.deadCodeElim: on.} # dce option deprecated -when defined(Posix) and not defined(haiku): +when defined(Posix): {.passl: "-lm".} var diff --git a/lib/pure/math.nim b/lib/pure/math.nim index eb09bf4a7..785d4c183 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -49,7 +49,7 @@ proc fac*(n: int): int = {.push checks:off, line_dir:off, stack_trace:off.} -when defined(Posix) and not defined(haiku): +when defined(Posix): {.passl: "-lm".} const diff --git a/lib/pure/nativesockets.nim b/lib/pure/nativesockets.nim index 5545ca2d1..d5fb0f89b 100644 --- a/lib/pure/nativesockets.nim +++ b/lib/pure/nativesockets.nim @@ -248,9 +248,10 @@ proc getAddrInfo*(address: string, port: Port, domain: Domain = AF_INET, hints.ai_socktype = toInt(sockType) hints.ai_protocol = toInt(protocol) # OpenBSD doesn't support AI_V4MAPPED and doesn't define the macro AI_V4MAPPED. - # FreeBSD doesn't support AI_V4MAPPED but defines the macro. + # FreeBSD, Haiku don't support AI_V4MAPPED but defines the macro. # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=198092 - when not defined(freebsd) and not defined(openbsd) and not defined(netbsd) and not defined(android): + # https://dev.haiku-os.org/ticket/14323 + when not defined(freebsd) and not defined(openbsd) and not defined(netbsd) and not defined(android) and not defined(haiku): if domain == AF_INET6: hints.ai_flags = AI_V4MAPPED var gaiResult = getaddrinfo(address, $port, addr(hints), result) diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 9cc83c372..c05e33e31 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -615,7 +615,10 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", when not declared(ENOENT) and not defined(Windows): when NoFakeVars: - const ENOENT = cint(2) # 2 on most systems including Solaris + when not defined(haiku): + const ENOENT = cint(2) # 2 on most systems including Solaris + else: + const ENOENT = cint(-2147459069) else: var ENOENT {.importc, header: "".}: cint @@ -972,6 +975,14 @@ proc rawCreateDir(dir: string): bool = result = false else: raiseOSError(osLastError(), dir) + elif defined(haiku): + let res = mkdir(dir, 0o777) + if res == 0'i32: + result = true + elif errno == EEXIST or errno == EROFS: + result = false + else: + raiseOSError(osLastError(), dir) elif defined(posix): let res = mkdir(dir, 0o777) if res == 0'i32: diff --git a/lib/pure/times.nim b/lib/pure/times.nim index cdb7a4466..073216e22 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -892,7 +892,7 @@ else: weekday {.importc: "tm_wday".}, yearday {.importc: "tm_yday".}, isdst {.importc: "tm_isdst".}: cint - when defined(linux) and defined(amd64): + when defined(linux) and defined(amd64) or defined(haiku): gmtoff {.importc: "tm_gmtoff".}: clong zone {.importc: "tm_zone".}: cstring type diff --git a/lib/system.nim b/lib/system.nim index 53605f9fd..de6e96611 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1365,7 +1365,7 @@ const hostOS* {.magic: "HostOS".}: string = "" ## a string that describes the host operating system. Possible values: ## "windows", "macosx", "linux", "netbsd", "freebsd", "openbsd", "solaris", - ## "aix", "standalone". + ## "aix", "haiku", "standalone". hostCPU* {.magic: "HostCPU".}: string = "" ## a string that describes the host CPU. Possible values: diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim index f593d4c99..c6b89afe1 100644 --- a/lib/system/ansi_c.nim +++ b/lib/system/ansi_c.nim @@ -59,6 +59,15 @@ elif defined(macosx) or defined(linux) or defined(freebsd) or SIGSEGV = cint(11) SIGTERM = cint(15) SIGPIPE = cint(13) +elif defined(haiku): + const + SIGABRT = cint(6) + SIGFPE = cint(8) + SIGILL = cint(4) + SIGINT = cint(2) + SIGSEGV = cint(11) + SIGTERM = cint(15) + SIGPIPE = cint(7) else: when NoFakeVars: {.error: "SIGABRT not ported to your platform".} @@ -74,6 +83,8 @@ else: when defined(macosx): const SIGBUS = cint(10) +elif defined(haiku): + const SIGBUS = cint(30) else: template SIGBUS: untyped = SIGSEGV diff --git a/lib/system/osalloc.nim b/lib/system/osalloc.nim index 85c796ba0..06e89f130 100644 --- a/lib/system/osalloc.nim +++ b/lib/system/osalloc.nim @@ -207,6 +207,9 @@ elif defined(posix): # some arches like mips and alpha use different values const MAP_ANONYMOUS = 0x20 const MAP_PRIVATE = 0x02 # Changes are private + elif defined(haiku): + const MAP_ANONYMOUS = 0x08 + const MAP_PRIVATE = 0x02 else: var MAP_ANONYMOUS {.importc: "MAP_ANONYMOUS", header: "".}: cint diff --git a/lib/system/threads.nim b/lib/system/threads.nim index 3bfaa1dc2..2434ea21e 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -162,10 +162,12 @@ elif defined(genode): mainTls else: - when not defined(macosx): + when not (defined(macosx) or defined(haiku)): {.passL: "-pthread".} - {.passC: "-pthread".} + when not defined(haiku): + {.passC: "-pthread".} + const schedh = "#define _GNU_SOURCE\n#include " pthreadh = "#define _GNU_SOURCE\n#include " @@ -714,3 +716,13 @@ elif defined(solaris): if threadId == 0: threadId = int(thr_self()) result = threadId + +elif defined(haiku): + type thr_id {.importc: "thread_id", header: "".} = distinct int32 + proc find_thread(name: cstring): thr_id {.importc, header: "".} + + proc getThreadId*(): int = + ## get the ID of the currently running thread. + if threadId == 0: + threadId = int(find_thread(nil)) + result = threadId diff --git a/tests/osproc/texitsignal.nim b/tests/osproc/texitsignal.nim index c0bed70ee..fbf5068ea 100644 --- a/tests/osproc/texitsignal.nim +++ b/tests/osproc/texitsignal.nim @@ -28,9 +28,12 @@ if paramCount() == 0: # windows kill happens using TerminateProcess(h, 0), so we should get a # 0 here echo p.waitForExit() == 0 + elif defined(haiku): + # on Haiku, the program main thread receive SIGKILLTHR + echo p.waitForExit() == 128 + SIGKILLTHR else: # on posix (non-windows), kill sends SIGKILL echo p.waitForExit() == 128 + SIGKILL else: - sleep(5000) # should get killed before this \ No newline at end of file + sleep(5000) # should get killed before this diff --git a/tests/osproc/tworkingdir.nim b/tests/osproc/tworkingdir.nim index eeed9240d..7d58d5ae6 100644 --- a/tests/osproc/tworkingdir.nim +++ b/tests/osproc/tworkingdir.nim @@ -12,6 +12,8 @@ else: var process: Process when defined(android): process = startProcess("/system/bin/env", "/system/bin", ["true"]) + elif defined(haiku): + process = startProcess("/bin/env", "/bin", ["true"]) else: process = startProcess("/usr/bin/env", "/usr/bin", ["true"]) let dir2 = getCurrentDir() diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim index 95521449a..fca6927d4 100644 --- a/tests/testament/categories.nim +++ b/tests/testament/categories.nim @@ -109,10 +109,14 @@ proc runBasicDLLTest(c, r: var TResults, cat: Category, options: string) = safeCopyFile("lib" / nimrtlDll, "tests/dll" / nimrtlDll) else: # posix relies on crappy LD_LIBRARY_PATH (ugh!): - var libpath = getEnv"LD_LIBRARY_PATH".string + const libpathenv = when defined(haiku): + "LIBRARY_PATH" + else: + "LD_LIBRARY_PATH" + var libpath = getEnv(libpathenv).string # Temporarily add the lib directory to LD_LIBRARY_PATH: - putEnv("LD_LIBRARY_PATH", "tests/dll" & (if libpath.len > 0: ":" & libpath else: "")) - defer: putEnv("LD_LIBRARY_PATH", libpath) + putEnv(libpathenv, "tests/dll" & (if libpath.len > 0: ":" & libpath else: "")) + defer: putEnv(libpathenv, libpath) var nimrtlDll = DynlibFormat % "nimrtl" safeCopyFile("lib" / nimrtlDll, "tests/dll" / nimrtlDll) -- cgit 1.4.1-2-gfad0 From 2da0341b4d6828479c5dc75a233b47732f53cf6c Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Thu, 16 Aug 2018 18:12:37 +0200 Subject: Genode fixes (#8501) * Genode fixes - wrap strings in "Genode::Cstring" when logging - define SIGABRT for Genode - disable GCC -fstack-protector - use log RPC for fatal messages - add --os:genode build to appveyor - define paramStr and paramCount * Select fixups for Genode POSIX --- appveyor.yml | 1 + compiler/ccgexprs.nim | 5 +++-- config/nim.cfg | 17 +++++++++++------ lib/nimbase.h | 4 ++-- lib/pure/ioselects/ioselectors_select.nim | 6 ++++-- lib/pure/os.nim | 10 ++++++++-- lib/system.nim | 9 +++++++-- lib/system/ansi_c.nim | 2 +- lib/system/excpt.nim | 6 +++++- 9 files changed, 42 insertions(+), 18 deletions(-) (limited to 'lib/system/ansi_c.nim') diff --git a/appveyor.yml b/appveyor.yml index 5aa3798b1..cb4ac9e00 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -55,6 +55,7 @@ build_script: - nimble install jester@#head -y - nimble install niminst - nim c --taintMode:on -d:nimCoroutines tests/testament/tester + - nim c --taintMode:on -d:nimCoroutines --os:genode -d:posix --compileOnly tests/testament/tester test_script: - tests\testament\tester --pedantic all -d:nimCoroutines diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index dd1c72ab6..9ec034f67 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -982,7 +982,7 @@ proc genEcho(p: BProc, n: PNode) = # is threadsafe. internalAssert p.config, n.kind == nkBracket if p.config.target.targetOS == osGenode: - # bypass libc and print directly to the Genode LOG session + # echo directly to the Genode LOG session var args: Rope = nil var a: TLoc for it in n.sons: @@ -990,8 +990,9 @@ proc genEcho(p: BProc, n: PNode) = add(args, ", \"\"") else: initLocExpr(p, it, a) - add(args, ropecg(p.module, ", #nimToCStringConv($1)", [rdLoc(a)])) + add(args, ropecg(p.module, ", Genode::Cstring($1->data, $1->len)", [rdLoc(a)])) p.module.includeHeader("") + p.module.includeHeader("") linefmt(p, cpsStmts, """Genode::log(""$1);$n""", args) else: if n.len == 0: diff --git a/config/nim.cfg b/config/nim.cfg index af9df9c55..9626a3197 100644 --- a/config/nim.cfg +++ b/config/nim.cfg @@ -255,9 +255,14 @@ vcc.cpp.options.size = "/O1" tcc.options.always = "-w" # Configuration for the Genode toolchain -amd64.genode.gcc.cpp.exe = "genode-x86-g++" -amd64.genode.gcc.exe = "genode-x86-gcc" -amd64.genode.gcc.path = "/usr/local/genode-gcc/bin" -arm.genode.gcc.cpp.exe = "genode-arm-g++" -arm.genode.gcc.exe = "genode-arm-gcc" -arm.genode.gcc.path = "/usr/local/genode-gcc/bin" +@if genode: + gcc.path = "/usr/local/genode-gcc/bin" + gcc.cpp.options.always = "-D__GENODE__ -fno-stack-protector" + @if i386 or amd64: + gcc.exe = "genode-x86-gcc" + gcc.cpp.exe = "genode-x86-g++" + @elif arm: + gcc.exe = "genode-arm-gcc" + gcc.cpp.exe = "genode-arm-g++" + @end +@end diff --git a/lib/nimbase.h b/lib/nimbase.h index 6dc742910..84972fcb0 100644 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -129,13 +129,13 @@ __clang__ defined __DMC__ || \ defined __BORLANDC__ ) # define NIM_THREADVAR __declspec(thread) +#elif defined(__TINYC__) || defined(__GENODE__) +# define NIM_THREADVAR /* note that ICC (linux) and Clang are covered by __GNUC__ */ #elif defined __GNUC__ || \ defined __SUNPRO_C || \ defined __xlC__ # define NIM_THREADVAR __thread -#elif defined __TINYC__ -# define NIM_THREADVAR #else # error "Cannot define NIM_THREADVAR" #endif diff --git a/lib/pure/ioselects/ioselectors_select.nim b/lib/pure/ioselects/ioselectors_select.nim index cd6a72b44..521b31a64 100644 --- a/lib/pure/ioselects/ioselectors_select.nim +++ b/lib/pure/ioselects/ioselectors_select.nim @@ -310,7 +310,10 @@ proc selectInto*[T](s: Selector[T], timeout: int, var rset, wset, eset: FdSet if timeout != -1: - tv.tv_sec = timeout.int32 div 1_000 + when defined(genode): + tv.tv_sec = Time(timeout div 1_000) + else: + tv.tv_sec = timeout.int32 div 1_000 tv.tv_usec = (timeout.int32 %% 1_000) * 1_000 else: ptv = nil @@ -391,7 +394,6 @@ proc contains*[T](s: Selector[T], fd: SocketHandle|int): bool {.inline.} = for i in 0..