fixes merge conflict
This commit is contained in:
commit
61d9292095
24 changed files with 360 additions and 105 deletions
|
|
@ -25,6 +25,8 @@ before_install:
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- set -e
|
- set -e
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then unset -f cd; fi
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then shell_session_update() { :; }; fi
|
||||||
- git clone --depth 1 https://github.com/nim-lang/csources.git
|
- git clone --depth 1 https://github.com/nim-lang/csources.git
|
||||||
- cd csources
|
- cd csources
|
||||||
- sh build.sh
|
- sh build.sh
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,12 @@
|
||||||
- ``math.`mod` `` for floats now behaves the same as ``mod`` for integers
|
- ``math.`mod` `` for floats now behaves the same as ``mod`` for integers
|
||||||
(previously it used floor division like Python). Use ``math.floorMod`` for the old behavior.
|
(previously it used floor division like Python). Use ``math.floorMod`` for the old behavior.
|
||||||
|
|
||||||
|
- For string inputs, ``unicode.isUpper`` and ``unicode.isLower`` now require a
|
||||||
|
second mandatory parameter ``skipNonAlpha``.
|
||||||
|
|
||||||
|
- For string inputs, ``strutils.isUpperAscii`` and ``strutils.isLowerAscii`` now
|
||||||
|
require a second mandatory parameter ``skipNonAlpha``.
|
||||||
|
|
||||||
#### Breaking changes in the compiler
|
#### Breaking changes in the compiler
|
||||||
|
|
||||||
- The undocumented ``#? braces`` parsing mode was removed.
|
- The undocumented ``#? braces`` parsing mode was removed.
|
||||||
|
|
@ -91,6 +97,7 @@
|
||||||
API". Using the Nim compiler and its VM as a scripting engine has never been
|
API". Using the Nim compiler and its VM as a scripting engine has never been
|
||||||
easier. See ``tests/compilerapi/tcompilerapi.nim`` for an example of how to
|
easier. See ``tests/compilerapi/tcompilerapi.nim`` for an example of how to
|
||||||
use the Nim VM in a native Nim application.
|
use the Nim VM in a native Nim application.
|
||||||
|
- Added the parameter ``val`` for the ``CritBitTree[T].incl`` proc.
|
||||||
- The proc ``tgamma`` was renamed to ``gamma``. ``tgamma`` is deprecated.
|
- The proc ``tgamma`` was renamed to ``gamma``. ``tgamma`` is deprecated.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -731,8 +731,6 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
|
||||||
else: addAbiCheck(m, t, result)
|
else: addAbiCheck(m, t, result)
|
||||||
of tyObject, tyTuple:
|
of tyObject, tyTuple:
|
||||||
if isImportedCppType(t) and origTyp.kind == tyGenericInst:
|
if isImportedCppType(t) and origTyp.kind == tyGenericInst:
|
||||||
# for instantiated templates we do not go through the type cache as the
|
|
||||||
# the type cache is not aware of 'tyGenericInst'.
|
|
||||||
let cppName = getTypeName(m, t, sig)
|
let cppName = getTypeName(m, t, sig)
|
||||||
var i = 0
|
var i = 0
|
||||||
var chunkStart = 0
|
var chunkStart = 0
|
||||||
|
|
|
||||||
|
|
@ -1036,14 +1036,19 @@ proc genMainProc(m: BModule) =
|
||||||
"}$N$N"
|
"}$N$N"
|
||||||
|
|
||||||
GenodeNimMain =
|
GenodeNimMain =
|
||||||
"Libc::Env *genodeEnv;$N" &
|
"extern Genode::Env *nim_runtime_env;$N" &
|
||||||
|
"extern void nim_component_construct(Genode::Env*);$N$N" &
|
||||||
NimMainBody
|
NimMainBody
|
||||||
|
|
||||||
ComponentConstruct =
|
ComponentConstruct =
|
||||||
"void Libc::Component::construct(Libc::Env &env) {$N" &
|
"void Libc::Component::construct(Libc::Env &env) {$N" &
|
||||||
"\tgenodeEnv = &env;$N" &
|
"\t// Set Env used during runtime initialization$N" &
|
||||||
|
"\tnim_runtime_env = &env;$N" &
|
||||||
"\tLibc::with_libc([&] () {$N\t" &
|
"\tLibc::with_libc([&] () {$N\t" &
|
||||||
|
"\t// Initialize runtime and globals$N" &
|
||||||
MainProcs &
|
MainProcs &
|
||||||
|
"\t// Call application construct$N" &
|
||||||
|
"\t\tnim_component_construct(&env);$N" &
|
||||||
"\t});$N" &
|
"\t});$N" &
|
||||||
"}$N$N"
|
"}$N$N"
|
||||||
|
|
||||||
|
|
@ -1060,6 +1065,7 @@ proc genMainProc(m: BModule) =
|
||||||
elif m.config.target.targetOS == osGenode:
|
elif m.config.target.targetOS == osGenode:
|
||||||
nimMain = GenodeNimMain
|
nimMain = GenodeNimMain
|
||||||
otherMain = ComponentConstruct
|
otherMain = ComponentConstruct
|
||||||
|
m.includeHeader("<libc/component.h>")
|
||||||
elif optGenDynLib in m.config.globalOptions:
|
elif optGenDynLib in m.config.globalOptions:
|
||||||
nimMain = PosixNimDllMain
|
nimMain = PosixNimDllMain
|
||||||
otherMain = PosixCDllMain
|
otherMain = PosixCDllMain
|
||||||
|
|
|
||||||
|
|
@ -496,7 +496,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||||
def = fitNode(c, typ, def, def.info)
|
def = fitNode(c, typ, def, def.info)
|
||||||
#changeType(def.skipConv, typ, check=true)
|
#changeType(def.skipConv, typ, check=true)
|
||||||
else:
|
else:
|
||||||
typ = skipIntLit(def.typ)
|
typ = def.typ.skipTypes({tyStatic}).skipIntLit
|
||||||
if typ.kind in tyUserTypeClasses and typ.isResolvedUserTypeClass:
|
if typ.kind in tyUserTypeClasses and typ.isResolvedUserTypeClass:
|
||||||
typ = typ.lastSon
|
typ = typ.lastSon
|
||||||
if hasEmpty(typ):
|
if hasEmpty(typ):
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
import ast, md5, tables, ropes
|
import ast, md5, tables, ropes
|
||||||
from hashes import Hash
|
from hashes import Hash
|
||||||
from astalgo import debug
|
from astalgo import debug
|
||||||
from types import typeToString, preferDesc
|
import types
|
||||||
from strutils import startsWith, contains
|
from strutils import startsWith, contains
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
|
|
@ -148,19 +148,23 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
|
||||||
of tyGenericInvocation:
|
of tyGenericInvocation:
|
||||||
for i in countup(0, sonsLen(t) - 1):
|
for i in countup(0, sonsLen(t) - 1):
|
||||||
c.hashType t.sons[i], flags
|
c.hashType t.sons[i], flags
|
||||||
return
|
|
||||||
of tyDistinct:
|
of tyDistinct:
|
||||||
if CoType in flags:
|
if CoType in flags:
|
||||||
c.hashType t.lastSon, flags
|
c.hashType t.lastSon, flags
|
||||||
else:
|
else:
|
||||||
c.hashSym(t.sym)
|
c.hashSym(t.sym)
|
||||||
return
|
of tyGenericInst:
|
||||||
of tyAlias, tySink, tyGenericInst, tyUserTypeClasses:
|
if sfInfixCall in t.base.sym.flags:
|
||||||
|
# This is an imported C++ generic type.
|
||||||
|
# We cannot trust the `lastSon` to hold a properly populated and unique
|
||||||
|
# value for each instantiation, so we hash the generic parameters here:
|
||||||
|
let normalizedType = t.skipGenericAlias
|
||||||
|
for i in 0 .. normalizedType.len - 2:
|
||||||
|
c.hashType t.sons[i], flags
|
||||||
|
else:
|
||||||
|
c.hashType t.lastSon, flags
|
||||||
|
of tyAlias, tySink, tyUserTypeClasses:
|
||||||
c.hashType t.lastSon, flags
|
c.hashType t.lastSon, flags
|
||||||
return
|
|
||||||
else:
|
|
||||||
discard
|
|
||||||
case t.kind
|
|
||||||
of tyBool, tyChar, tyInt..tyUInt64:
|
of tyBool, tyChar, tyInt..tyUInt64:
|
||||||
# no canonicalization for integral types, so that e.g. ``pid_t`` is
|
# no canonicalization for integral types, so that e.g. ``pid_t`` is
|
||||||
# produced instead of ``NI``:
|
# produced instead of ``NI``:
|
||||||
|
|
@ -168,11 +172,12 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
|
||||||
if t.sym != nil and {sfImportc, sfExportc} * t.sym.flags != {}:
|
if t.sym != nil and {sfImportc, sfExportc} * t.sym.flags != {}:
|
||||||
c.hashSym(t.sym)
|
c.hashSym(t.sym)
|
||||||
of tyObject, tyEnum:
|
of tyObject, tyEnum:
|
||||||
c &= char(t.kind)
|
|
||||||
if t.typeInst != nil:
|
if t.typeInst != nil:
|
||||||
assert t.typeInst.kind == tyGenericInst
|
assert t.typeInst.kind == tyGenericInst
|
||||||
for i in countup(1, sonsLen(t.typeInst) - 2):
|
for i in countup(0, sonsLen(t.typeInst) - 2):
|
||||||
c.hashType t.typeInst.sons[i], flags
|
c.hashType t.typeInst.sons[i], flags
|
||||||
|
return
|
||||||
|
c &= char(t.kind)
|
||||||
# Every cyclic type in Nim need to be constructed via some 't.sym', so this
|
# Every cyclic type in Nim need to be constructed via some 't.sym', so this
|
||||||
# is actually safe without an infinite recursion check:
|
# is actually safe without an infinite recursion check:
|
||||||
if t.sym != nil:
|
if t.sym != nil:
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,15 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
# Low level dataspace allocator for Genode.
|
# Low level dataspace allocator for Genode.
|
||||||
|
# For interacting with dataspaces outside of the
|
||||||
|
# standard library see the Genode Nimble package.
|
||||||
|
|
||||||
when not defined(genode):
|
when not defined(genode):
|
||||||
{.error: "Genode only module".}
|
{.error: "Genode only module".}
|
||||||
|
|
||||||
|
when not declared(GenodeEnv):
|
||||||
|
include genode/env
|
||||||
|
|
||||||
type DataspaceCapability {.
|
type DataspaceCapability {.
|
||||||
importcpp: "Genode::Dataspace_capability", pure.} = object
|
importcpp: "Genode::Dataspace_capability", pure.} = object
|
||||||
|
|
||||||
|
|
@ -31,35 +36,35 @@ type
|
||||||
|
|
||||||
const SlabBackendSize = 4096
|
const SlabBackendSize = 4096
|
||||||
|
|
||||||
proc ramAvail(): int {.
|
proc ramAvail(env: GenodeEnv): int {.
|
||||||
importcpp: "genodeEnv->pd().avail_ram().value".}
|
importcpp: "#->pd().avail_ram().value".}
|
||||||
## Return number of bytes available for allocation.
|
## Return number of bytes available for allocation.
|
||||||
|
|
||||||
proc capsAvail(): int {.
|
proc capsAvail(env: GenodeEnv): int {.
|
||||||
importcpp: "genodeEnv->pd().avail_caps().value".}
|
importcpp: "#->pd().avail_caps().value".}
|
||||||
## Return the number of available capabilities.
|
## Return the number of available capabilities.
|
||||||
## Each dataspace allocation consumes a capability.
|
## Each dataspace allocation consumes a capability.
|
||||||
|
|
||||||
proc allocDataspace(size: int): DataspaceCapability {.
|
proc allocDataspace(env: GenodeEnv; size: int): DataspaceCapability {.
|
||||||
importcpp: "genodeEnv->pd().alloc(@)".}
|
importcpp: "#->pd().alloc(@)".}
|
||||||
## Allocate a dataspace and its capability.
|
## Allocate a dataspace and its capability.
|
||||||
|
|
||||||
proc attachDataspace(ds: DataspaceCapability): pointer {.
|
proc attachDataspace(env: GenodeEnv; ds: DataspaceCapability): pointer {.
|
||||||
importcpp: "genodeEnv->rm().attach(@)".}
|
importcpp: "#->rm().attach(@)".}
|
||||||
## Attach a dataspace into the component address-space.
|
## Attach a dataspace into the component address-space.
|
||||||
|
|
||||||
proc detachAddress(p: pointer) {.
|
proc detachAddress(env: GenodeEnv; p: pointer) {.
|
||||||
importcpp: "genodeEnv->rm().detach(@)".}
|
importcpp: "#->rm().detach(@)".}
|
||||||
## Detach a dataspace from the component address-space.
|
## Detach a dataspace from the component address-space.
|
||||||
|
|
||||||
proc freeDataspace(ds: DataspaceCapability) {.
|
proc freeDataspace(env: GenodeEnv; ds: DataspaceCapability) {.
|
||||||
importcpp: "genodeEnv->pd().free(@)".}
|
importcpp: "#->pd().free(@)".}
|
||||||
## Free a dataspace.
|
## Free a dataspace.
|
||||||
|
|
||||||
proc newMapSlab(): ptr MapSlab =
|
proc newMapSlab(): ptr MapSlab =
|
||||||
let
|
let
|
||||||
ds = allocDataspace SlabBackendSize
|
ds = runtimeEnv.allocDataspace SlabBackendSize
|
||||||
p = attachDataspace ds
|
p = runtimeEnv.attachDataspace ds
|
||||||
result = cast[ptr MapSlab](p)
|
result = cast[ptr MapSlab](p)
|
||||||
result.meta.ds = ds
|
result.meta.ds = ds
|
||||||
|
|
||||||
|
|
@ -89,13 +94,13 @@ proc osAllocPages(size: int): pointer =
|
||||||
# tack a new slab on the tail
|
# tack a new slab on the tail
|
||||||
slab = slab.meta.next
|
slab = slab.meta.next
|
||||||
# move to next slab in linked list
|
# move to next slab in linked list
|
||||||
map.ds = allocDataspace size
|
map.ds = runtimeEnv.allocDataspace size
|
||||||
map.size = size
|
map.size = size
|
||||||
map.attachment = attachDataspace map.ds
|
map.attachment = runtimeEnv.attachDataspace map.ds
|
||||||
result = map.attachment
|
result = map.attachment
|
||||||
|
|
||||||
proc osTryAllocPages(size: int): pointer =
|
proc osTryAllocPages(size: int): pointer =
|
||||||
if ramAvail() >= size and capsAvail() > 1:
|
if runtimeEnv.ramAvail() >= size and runtimeEnv.capsAvail() > 4:
|
||||||
result = osAllocPages size
|
result = osAllocPages size
|
||||||
|
|
||||||
proc osDeallocPages(p: pointer; size: int) =
|
proc osDeallocPages(p: pointer; size: int) =
|
||||||
|
|
@ -107,8 +112,8 @@ proc osDeallocPages(p: pointer; size: int) =
|
||||||
if m.size != size:
|
if m.size != size:
|
||||||
echo "cannot partially detach dataspace"
|
echo "cannot partially detach dataspace"
|
||||||
quit -1
|
quit -1
|
||||||
detachAddress m.attachment
|
runtimeEnv.detachAddress m.attachment
|
||||||
freeDataspace m.ds
|
runtimeEnv.freeDataspace m.ds
|
||||||
m[] = Map()
|
m[] = Map()
|
||||||
return
|
return
|
||||||
slab = slab.meta.next
|
slab = slab.meta.next
|
||||||
29
lib/genode/env.nim
Normal file
29
lib/genode/env.nim
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Nim's Runtime Library
|
||||||
|
# (c) Copyright 2018 Emery Hemingway
|
||||||
|
#
|
||||||
|
# See the file "copying.txt", included in this
|
||||||
|
# distribution, for details about the copyright.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# This file contains the minimum required definitions
|
||||||
|
# for interacting with the initial Genode environment.
|
||||||
|
# It is reserved for use only within the standard
|
||||||
|
# library. See ``componentConstructHook`` in the system
|
||||||
|
# module for accessing the Genode environment after the
|
||||||
|
# standard library has finished initializating.
|
||||||
|
#
|
||||||
|
|
||||||
|
when not defined(genode):
|
||||||
|
{.error: "Genode only include".}
|
||||||
|
|
||||||
|
type
|
||||||
|
GenodeEnvObj {.importcpp: "Genode::Env", header: "<base/env.h>", pure.} = object
|
||||||
|
GenodeEnvPtr = ptr GenodeEnvObj
|
||||||
|
|
||||||
|
const runtimeEnvSym = "nim_runtime_env"
|
||||||
|
|
||||||
|
when not defined(nimscript):
|
||||||
|
var runtimeEnv {.importcpp: runtimeEnvSym.}: GenodeEnvPtr
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#define _GENODE_CPP__THREAD_H_
|
#define _GENODE_CPP__THREAD_H_
|
||||||
|
|
||||||
#include <base/thread.h>
|
#include <base/thread.h>
|
||||||
|
#include <base/env.h>
|
||||||
#include <util/reconstructible.h>
|
#include <util/reconstructible.h>
|
||||||
|
|
||||||
namespace Nim { struct SysThread; }
|
namespace Nim { struct SysThread; }
|
||||||
|
|
|
||||||
|
|
@ -502,11 +502,6 @@ typedef int Nim_and_C_compiler_disagree_on_target_architecture[sizeof(NI) == siz
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__GENODE__)
|
|
||||||
#include <libc/component.h>
|
|
||||||
extern Libc::Env *genodeEnv;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Compile with -d:checkAbi and a sufficiently C11:ish compiler to enable */
|
/* Compile with -d:checkAbi and a sufficiently C11:ish compiler to enable */
|
||||||
#define NIM_CHECK_SIZE(typ, sz) \
|
#define NIM_CHECK_SIZE(typ, sz) \
|
||||||
_Static_assert(sizeof(typ) == sz, "Nim & C disagree on type size")
|
_Static_assert(sizeof(typ) == sz, "Nim & C disagree on type size")
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,20 @@ proc parseProtocol(protocol: string): tuple[orig: string, major, minor: int] =
|
||||||
proc sendStatus(client: AsyncSocket, status: string): Future[void] =
|
proc sendStatus(client: AsyncSocket, status: string): Future[void] =
|
||||||
client.send("HTTP/1.1 " & status & "\c\L\c\L")
|
client.send("HTTP/1.1 " & status & "\c\L\c\L")
|
||||||
|
|
||||||
|
proc parseUppercaseMethod(name: string): HttpMethod =
|
||||||
|
result =
|
||||||
|
case name
|
||||||
|
of "GET": HttpGet
|
||||||
|
of "POST": HttpPost
|
||||||
|
of "HEAD": HttpHead
|
||||||
|
of "PUT": HttpPut
|
||||||
|
of "DELETE": HttpDelete
|
||||||
|
of "PATCH": HttpPatch
|
||||||
|
of "OPTIONS": HttpOptions
|
||||||
|
of "CONNECT": HttpConnect
|
||||||
|
of "TRACE": HttpTrace
|
||||||
|
else: raise newException(ValueError, "Invalid HTTP method " & name)
|
||||||
|
|
||||||
proc processRequest(server: AsyncHttpServer, req: FutureVar[Request],
|
proc processRequest(server: AsyncHttpServer, req: FutureVar[Request],
|
||||||
client: AsyncSocket,
|
client: AsyncSocket,
|
||||||
address: string, lineFut: FutureVar[string],
|
address: string, lineFut: FutureVar[string],
|
||||||
|
|
@ -172,8 +186,7 @@ proc processRequest(server: AsyncHttpServer, req: FutureVar[Request],
|
||||||
case i
|
case i
|
||||||
of 0:
|
of 0:
|
||||||
try:
|
try:
|
||||||
# TODO: this is likely slow.
|
request.reqMethod = parseUppercaseMethod(linePart)
|
||||||
request.reqMethod = parseEnum[HttpMethod]("http" & linePart)
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
asyncCheck request.respondError(Http400)
|
asyncCheck request.respondError(Http400)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -165,16 +165,18 @@ proc containsOrIncl*(c: var CritBitTree[void], key: string): bool =
|
||||||
|
|
||||||
proc inc*(c: var CritBitTree[int]; key: string, val: int = 1) =
|
proc inc*(c: var CritBitTree[int]; key: string, val: int = 1) =
|
||||||
## increments `c[key]` by `val`.
|
## increments `c[key]` by `val`.
|
||||||
let oldCount = c.count
|
|
||||||
var n = rawInsert(c, key)
|
var n = rawInsert(c, key)
|
||||||
if c.count >= oldCount or oldCount == 0:
|
inc n.val, val
|
||||||
# not a new key:
|
|
||||||
inc n.val, val
|
|
||||||
|
|
||||||
proc incl*(c: var CritBitTree[void], key: string) =
|
proc incl*(c: var CritBitTree[void], key: string) =
|
||||||
## includes `key` in `c`.
|
## includes `key` in `c`.
|
||||||
discard rawInsert(c, key)
|
discard rawInsert(c, key)
|
||||||
|
|
||||||
|
proc incl*[T](c: var CritBitTree[T], key: string, val: T) =
|
||||||
|
## inserts `key` with value `val` into `c`.
|
||||||
|
var n = rawInsert(c, key)
|
||||||
|
n.val = val
|
||||||
|
|
||||||
proc `[]=`*[T](c: var CritBitTree[T], key: string, val: T) =
|
proc `[]=`*[T](c: var CritBitTree[T], key: string, val: T) =
|
||||||
## puts a (key, value)-pair into `t`.
|
## puts a (key, value)-pair into `t`.
|
||||||
var n = rawInsert(c, key)
|
var n = rawInsert(c, key)
|
||||||
|
|
@ -375,3 +377,18 @@ when isMainModule:
|
||||||
|
|
||||||
c.inc("a", 1)
|
c.inc("a", 1)
|
||||||
assert c["a"] == 1
|
assert c["a"] == 1
|
||||||
|
|
||||||
|
var cf = CritBitTree[float]()
|
||||||
|
|
||||||
|
cf.incl("a", 1.0)
|
||||||
|
assert cf["a"] == 1.0
|
||||||
|
|
||||||
|
cf.incl("b", 2.0)
|
||||||
|
assert cf["b"] == 2.0
|
||||||
|
|
||||||
|
cf.incl("c", 3.0)
|
||||||
|
assert cf["c"] == 3.0
|
||||||
|
|
||||||
|
assert cf.len == 3
|
||||||
|
cf.excl("c")
|
||||||
|
assert cf.len == 2
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,10 @@ when defined(macosx) or defined(bsd):
|
||||||
importc: "sysctl", nodecl.}
|
importc: "sysctl", nodecl.}
|
||||||
|
|
||||||
when defined(genode):
|
when defined(genode):
|
||||||
proc affinitySpaceTotal(): cuint {.
|
include genode/env
|
||||||
importcpp: "genodeEnv->cpu().affinity_space().total()".}
|
|
||||||
|
proc affinitySpaceTotal(env: GenodeEnvPtr): cuint {.
|
||||||
|
importcpp: "@->cpu().affinity_space().total()".}
|
||||||
|
|
||||||
proc countProcessors*(): int {.rtl, extern: "ncpi$1".} =
|
proc countProcessors*(): int {.rtl, extern: "ncpi$1".} =
|
||||||
## returns the numer of the processors/cores the machine has.
|
## returns the numer of the processors/cores the machine has.
|
||||||
|
|
@ -83,7 +85,7 @@ proc countProcessors*(): int {.rtl, extern: "ncpi$1".} =
|
||||||
var SC_NPROC_ONLN {.importc: "_SC_NPROC_ONLN", header: "<unistd.h>".}: cint
|
var SC_NPROC_ONLN {.importc: "_SC_NPROC_ONLN", header: "<unistd.h>".}: cint
|
||||||
result = sysconf(SC_NPROC_ONLN)
|
result = sysconf(SC_NPROC_ONLN)
|
||||||
elif defined(genode):
|
elif defined(genode):
|
||||||
result = affinitySpaceTotal().int
|
result = runtimeEnv.affinitySpaceTotal().int
|
||||||
else:
|
else:
|
||||||
result = sysconf(SC_NPROCESSORS_ONLN)
|
result = sysconf(SC_NPROCESSORS_ONLN)
|
||||||
if result <= 0: result = 0
|
if result <= 0: result = 0
|
||||||
|
|
|
||||||
|
|
@ -447,7 +447,7 @@ proc fromSockAddr*(sa: Sockaddr_storage | SockAddr | Sockaddr_in | Sockaddr_in6,
|
||||||
sl: Socklen, address: var IpAddress, port: var Port) {.inline.} =
|
sl: Socklen, address: var IpAddress, port: var Port) {.inline.} =
|
||||||
## Converts `SockAddr` and `Socklen` to `IpAddress` and `Port`. Raises
|
## Converts `SockAddr` and `Socklen` to `IpAddress` and `Port`. Raises
|
||||||
## `ObjectConversionError` in case of invalid `sa` and `sl` arguments.
|
## `ObjectConversionError` in case of invalid `sa` and `sl` arguments.
|
||||||
fromSockAddrAux(unsafeAddr sa, sl, address, port)
|
fromSockAddrAux(cast[ptr Sockaddr_storage](unsafeAddr sa), sl, address, port)
|
||||||
|
|
||||||
when defineSsl:
|
when defineSsl:
|
||||||
CRYPTO_malloc_init()
|
CRYPTO_malloc_init()
|
||||||
|
|
|
||||||
|
|
@ -1440,7 +1440,7 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect].} =
|
||||||
elif defined(solaris):
|
elif defined(solaris):
|
||||||
result = getApplAux("/proc/" & $getpid() & "/path/a.out")
|
result = getApplAux("/proc/" & $getpid() & "/path/a.out")
|
||||||
elif defined(genode):
|
elif defined(genode):
|
||||||
raiseOSError("POSIX command line not supported")
|
raiseOSError(OSErrorCode(-1), "POSIX command line not supported")
|
||||||
elif defined(freebsd) or defined(dragonfly):
|
elif defined(freebsd) or defined(dragonfly):
|
||||||
result = getApplFreebsd()
|
result = getApplFreebsd()
|
||||||
# little heuristic that may work on other POSIX-like systems:
|
# little heuristic that may work on other POSIX-like systems:
|
||||||
|
|
|
||||||
|
|
@ -150,23 +150,52 @@ proc isSpaceAscii*(s: string): bool {.noSideEffect, procvar,
|
||||||
## characters and there is at least one character in `s`.
|
## characters and there is at least one character in `s`.
|
||||||
isImpl isSpaceAscii
|
isImpl isSpaceAscii
|
||||||
|
|
||||||
proc isLowerAscii*(s: string): bool {.noSideEffect, procvar,
|
template isCaseImpl(s, charProc, skipNonAlpha) =
|
||||||
rtl, extern: "nsuIsLowerAsciiStr".} =
|
var hasAtleastOneAlphaChar = false
|
||||||
## Checks whether or not `s` contains all lower case characters.
|
if s.len == 0: return false
|
||||||
##
|
for c in s:
|
||||||
## This checks ASCII characters only.
|
if skipNonAlpha:
|
||||||
## Returns true if all characters in `s` are lower case
|
var charIsAlpha = c.isAlphaAscii()
|
||||||
## and there is at least one character in `s`.
|
if not hasAtleastOneAlphaChar:
|
||||||
isImpl isLowerAscii
|
hasAtleastOneAlphaChar = charIsAlpha
|
||||||
|
if charIsAlpha and (not charProc(c)):
|
||||||
|
return false
|
||||||
|
else:
|
||||||
|
if not charProc(c):
|
||||||
|
return false
|
||||||
|
return if skipNonAlpha: hasAtleastOneAlphaChar else: true
|
||||||
|
|
||||||
proc isUpperAscii*(s: string): bool {.noSideEffect, procvar,
|
proc isLowerAscii*(s: string, skipNonAlpha: bool): bool =
|
||||||
rtl, extern: "nsuIsUpperAsciiStr".} =
|
## Checks whether ``s`` is lower case.
|
||||||
## Checks whether or not `s` contains all upper case characters.
|
|
||||||
##
|
##
|
||||||
## This checks ASCII characters only.
|
## This checks ASCII characters only.
|
||||||
## Returns true if all characters in `s` are upper case
|
##
|
||||||
## and there is at least one character in `s`.
|
## If ``skipNonAlpha`` is true, returns true if all alphabetical
|
||||||
isImpl isUpperAscii
|
## characters in ``s`` are lower case. Returns false if none of the
|
||||||
|
## characters in ``s`` are alphabetical.
|
||||||
|
##
|
||||||
|
## If ``skipNonAlpha`` is false, returns true only if all characters
|
||||||
|
## in ``s`` are alphabetical and lower case.
|
||||||
|
##
|
||||||
|
## For either value of ``skipNonAlpha``, returns false if ``s`` is
|
||||||
|
## an empty string.
|
||||||
|
isCaseImpl(s, isLowerAscii, skipNonAlpha)
|
||||||
|
|
||||||
|
proc isUpperAscii*(s: string, skipNonAlpha: bool): bool =
|
||||||
|
## Checks whether ``s`` is upper case.
|
||||||
|
##
|
||||||
|
## This checks ASCII characters only.
|
||||||
|
##
|
||||||
|
## If ``skipNonAlpha`` is true, returns true if all alphabetical
|
||||||
|
## characters in ``s`` are upper case. Returns false if none of the
|
||||||
|
## characters in ``s`` are alphabetical.
|
||||||
|
##
|
||||||
|
## If ``skipNonAlpha`` is false, returns true only if all characters
|
||||||
|
## in ``s`` are alphabetical and upper case.
|
||||||
|
##
|
||||||
|
## For either value of ``skipNonAlpha``, returns false if ``s`` is
|
||||||
|
## an empty string.
|
||||||
|
isCaseImpl(s, isUpperAscii, skipNonAlpha)
|
||||||
|
|
||||||
proc toLowerAscii*(c: char): char {.noSideEffect, procvar,
|
proc toLowerAscii*(c: char): char {.noSideEffect, procvar,
|
||||||
rtl, extern: "nsuToLowerAsciiChar".} =
|
rtl, extern: "nsuToLowerAsciiChar".} =
|
||||||
|
|
@ -2516,19 +2545,34 @@ when isMainModule:
|
||||||
doAssert(not isLowerAscii('A'))
|
doAssert(not isLowerAscii('A'))
|
||||||
doAssert(not isLowerAscii('5'))
|
doAssert(not isLowerAscii('5'))
|
||||||
doAssert(not isLowerAscii('&'))
|
doAssert(not isLowerAscii('&'))
|
||||||
|
doAssert(not isLowerAscii(' '))
|
||||||
|
|
||||||
doAssert isLowerAscii("abcd")
|
doAssert isLowerAscii("abcd", false)
|
||||||
doAssert(not isLowerAscii("abCD"))
|
doAssert(not isLowerAscii("33aa", false))
|
||||||
doAssert(not isLowerAscii("33aa"))
|
doAssert(not isLowerAscii("a b", false))
|
||||||
|
|
||||||
|
doAssert(not isLowerAscii("abCD", true))
|
||||||
|
doAssert isLowerAscii("33aa", true)
|
||||||
|
doAssert isLowerAscii("a b", true)
|
||||||
|
doAssert isLowerAscii("1, 2, 3 go!", true)
|
||||||
|
doAssert(not isLowerAscii(" ", true))
|
||||||
|
doAssert(not isLowerAscii("(*&#@(^#$ ", true)) # None of the string chars are alphabets
|
||||||
|
|
||||||
doAssert isUpperAscii('A')
|
doAssert isUpperAscii('A')
|
||||||
doAssert(not isUpperAscii('b'))
|
doAssert(not isUpperAscii('b'))
|
||||||
doAssert(not isUpperAscii('5'))
|
doAssert(not isUpperAscii('5'))
|
||||||
doAssert(not isUpperAscii('%'))
|
doAssert(not isUpperAscii('%'))
|
||||||
|
|
||||||
doAssert isUpperAscii("ABC")
|
doAssert isUpperAscii("ABC", false)
|
||||||
doAssert(not isUpperAscii("AAcc"))
|
doAssert(not isUpperAscii("A#$", false))
|
||||||
doAssert(not isUpperAscii("A#$"))
|
doAssert(not isUpperAscii("A B", false))
|
||||||
|
|
||||||
|
doAssert(not isUpperAscii("AAcc", true))
|
||||||
|
doAssert isUpperAscii("A#$", true)
|
||||||
|
doAssert isUpperAscii("A B", true)
|
||||||
|
doAssert isUpperAscii("1, 2, 3 GO!", true)
|
||||||
|
doAssert(not isUpperAscii(" ", true))
|
||||||
|
doAssert(not isUpperAscii("(*&#@(^#$ ", true)) # None of the string chars are alphabets
|
||||||
|
|
||||||
doAssert rsplit("foo bar", seps=Whitespace) == @["foo", "bar"]
|
doAssert rsplit("foo bar", seps=Whitespace) == @["foo", "bar"]
|
||||||
doAssert rsplit(" foo bar", seps=Whitespace, maxsplit=1) == @[" foo", "bar"]
|
doAssert rsplit(" foo bar", seps=Whitespace, maxsplit=1) == @[" foo", "bar"]
|
||||||
|
|
@ -2601,4 +2645,3 @@ bar
|
||||||
nonStaticTests()
|
nonStaticTests()
|
||||||
staticTests()
|
staticTests()
|
||||||
static: staticTests()
|
static: staticTests()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1392,7 +1392,7 @@ proc isCombining*(c: Rune): bool {.rtl, extern: "nuc$1", procvar.} =
|
||||||
(c >= 0xfe20 and c <= 0xfe2f))
|
(c >= 0xfe20 and c <= 0xfe2f))
|
||||||
|
|
||||||
template runeCheck(s, runeProc) =
|
template runeCheck(s, runeProc) =
|
||||||
## Common code for rune.isLower, rune.isUpper, etc
|
## Common code for isAlpha and isSpace.
|
||||||
result = if len(s) == 0: false else: true
|
result = if len(s) == 0: false else: true
|
||||||
|
|
||||||
var
|
var
|
||||||
|
|
@ -1403,16 +1403,6 @@ template runeCheck(s, runeProc) =
|
||||||
fastRuneAt(s, i, rune, doInc=true)
|
fastRuneAt(s, i, rune, doInc=true)
|
||||||
result = runeProc(rune) and result
|
result = runeProc(rune) and result
|
||||||
|
|
||||||
proc isUpper*(s: string): bool {.noSideEffect, procvar,
|
|
||||||
rtl, extern: "nuc$1Str".} =
|
|
||||||
## Returns true iff `s` contains all upper case unicode characters.
|
|
||||||
runeCheck(s, isUpper)
|
|
||||||
|
|
||||||
proc isLower*(s: string): bool {.noSideEffect, procvar,
|
|
||||||
rtl, extern: "nuc$1Str".} =
|
|
||||||
## Returns true iff `s` contains all lower case unicode characters.
|
|
||||||
runeCheck(s, isLower)
|
|
||||||
|
|
||||||
proc isAlpha*(s: string): bool {.noSideEffect, procvar,
|
proc isAlpha*(s: string): bool {.noSideEffect, procvar,
|
||||||
rtl, extern: "nuc$1Str".} =
|
rtl, extern: "nuc$1Str".} =
|
||||||
## Returns true iff `s` contains all alphabetic unicode characters.
|
## Returns true iff `s` contains all alphabetic unicode characters.
|
||||||
|
|
@ -1423,6 +1413,56 @@ proc isSpace*(s: string): bool {.noSideEffect, procvar,
|
||||||
## Returns true iff `s` contains all whitespace unicode characters.
|
## Returns true iff `s` contains all whitespace unicode characters.
|
||||||
runeCheck(s, isWhiteSpace)
|
runeCheck(s, isWhiteSpace)
|
||||||
|
|
||||||
|
template runeCaseCheck(s, runeProc, skipNonAlpha) =
|
||||||
|
## Common code for rune.isLower and rune.isUpper.
|
||||||
|
if len(s) == 0: return false
|
||||||
|
|
||||||
|
var
|
||||||
|
i = 0
|
||||||
|
rune: Rune
|
||||||
|
hasAtleastOneAlphaRune = false
|
||||||
|
|
||||||
|
while i < len(s):
|
||||||
|
fastRuneAt(s, i, rune, doInc=true)
|
||||||
|
if skipNonAlpha:
|
||||||
|
var runeIsAlpha = isAlpha(rune)
|
||||||
|
if not hasAtleastOneAlphaRune:
|
||||||
|
hasAtleastOneAlphaRune = runeIsAlpha
|
||||||
|
if runeIsAlpha and (not runeProc(rune)):
|
||||||
|
return false
|
||||||
|
else:
|
||||||
|
if not runeProc(rune):
|
||||||
|
return false
|
||||||
|
return if skipNonAlpha: hasAtleastOneAlphaRune else: true
|
||||||
|
|
||||||
|
proc isLower*(s: string, skipNonAlpha: bool): bool =
|
||||||
|
## Checks whether ``s`` is lower case.
|
||||||
|
##
|
||||||
|
## If ``skipNonAlpha`` is true, returns true if all alphabetical
|
||||||
|
## runes in ``s`` are lower case. Returns false if none of the
|
||||||
|
## runes in ``s`` are alphabetical.
|
||||||
|
##
|
||||||
|
## If ``skipNonAlpha`` is false, returns true only if all runes in
|
||||||
|
## ``s`` are alphabetical and lower case.
|
||||||
|
##
|
||||||
|
## For either value of ``skipNonAlpha``, returns false if ``s`` is
|
||||||
|
## an empty string.
|
||||||
|
runeCaseCheck(s, isLower, skipNonAlpha)
|
||||||
|
|
||||||
|
proc isUpper*(s: string, skipNonAlpha: bool): bool =
|
||||||
|
## Checks whether ``s`` is upper case.
|
||||||
|
##
|
||||||
|
## If ``skipNonAlpha`` is true, returns true if all alphabetical
|
||||||
|
## runes in ``s`` are upper case. Returns false if none of the
|
||||||
|
## runes in ``s`` are alphabetical.
|
||||||
|
##
|
||||||
|
## If ``skipNonAlpha`` is false, returns true only if all runes in
|
||||||
|
## ``s`` are alphabetical and upper case.
|
||||||
|
##
|
||||||
|
## For either value of ``skipNonAlpha``, returns false if ``s`` is
|
||||||
|
## an empty string.
|
||||||
|
runeCaseCheck(s, isUpper, skipNonAlpha)
|
||||||
|
|
||||||
template convertRune(s, runeProc) =
|
template convertRune(s, runeProc) =
|
||||||
## Convert runes in `s` using `runeProc` as the converter.
|
## Convert runes in `s` using `runeProc` as the converter.
|
||||||
result = newString(len(s))
|
result = newString(len(s))
|
||||||
|
|
@ -1755,25 +1795,39 @@ when isMainModule:
|
||||||
doAssert(not isSpace(""))
|
doAssert(not isSpace(""))
|
||||||
doAssert(not isSpace("ΑΓc \td"))
|
doAssert(not isSpace("ΑΓc \td"))
|
||||||
|
|
||||||
doAssert isLower("a")
|
doAssert(not isLower(' '.Rune))
|
||||||
doAssert isLower("γ")
|
|
||||||
doAssert(not isLower("Γ"))
|
|
||||||
doAssert(not isLower("4"))
|
|
||||||
doAssert(not isLower(""))
|
|
||||||
|
|
||||||
doAssert isLower("abcdγ")
|
doAssert isLower("a", false)
|
||||||
doAssert(not isLower("abCDΓ"))
|
doAssert isLower("γ", true)
|
||||||
doAssert(not isLower("33aaΓ"))
|
doAssert(not isLower("Γ", false))
|
||||||
|
doAssert(not isLower("4", true))
|
||||||
|
doAssert(not isLower("", false))
|
||||||
|
doAssert isLower("abcdγ", false)
|
||||||
|
doAssert(not isLower("33aaΓ", false))
|
||||||
|
doAssert(not isLower("a b", false))
|
||||||
|
|
||||||
doAssert isUpper("Γ")
|
doAssert(not isLower("abCDΓ", true))
|
||||||
doAssert(not isUpper("b"))
|
doAssert isLower("a b", true)
|
||||||
doAssert(not isUpper("α"))
|
doAssert isLower("1, 2, 3 go!", true)
|
||||||
doAssert(not isUpper("✓"))
|
doAssert(not isLower(" ", true))
|
||||||
doAssert(not isUpper(""))
|
doAssert(not isLower("(*&#@(^#$✓ ", true)) # None of the string runes are alphabets
|
||||||
|
|
||||||
doAssert isUpper("ΑΒΓ")
|
doAssert(not isUpper(' '.Rune))
|
||||||
doAssert(not isUpper("AAccβ"))
|
|
||||||
doAssert(not isUpper("A#$β"))
|
doAssert isUpper("Γ", false)
|
||||||
|
doAssert(not isUpper("α", false))
|
||||||
|
doAssert(not isUpper("", false))
|
||||||
|
doAssert isUpper("ΑΒΓ", false)
|
||||||
|
doAssert(not isUpper("A#$β", false))
|
||||||
|
doAssert(not isUpper("A B", false))
|
||||||
|
|
||||||
|
doAssert(not isUpper("b", true))
|
||||||
|
doAssert(not isUpper("✓", true))
|
||||||
|
doAssert(not isUpper("AAccβ", true))
|
||||||
|
doAssert isUpper("A B", true)
|
||||||
|
doAssert isUpper("1, 2, 3 GO!", true)
|
||||||
|
doAssert(not isUpper(" ", true))
|
||||||
|
doAssert(not isUpper("(*&#@(^#$✓ ", true)) # None of the string runes are alphabets
|
||||||
|
|
||||||
doAssert toUpper("Γ") == "Γ"
|
doAssert toUpper("Γ") == "Γ"
|
||||||
doAssert toUpper("b") == "B"
|
doAssert toUpper("b") == "B"
|
||||||
|
|
|
||||||
|
|
@ -1498,11 +1498,21 @@ when defined(nimdoc):
|
||||||
## macro, use the `error <manual.html#error-pragma>`_ or `fatal
|
## macro, use the `error <manual.html#error-pragma>`_ or `fatal
|
||||||
## <manual.html#fatal-pragma>`_ pragmas.
|
## <manual.html#fatal-pragma>`_ pragmas.
|
||||||
|
|
||||||
|
|
||||||
elif defined(genode):
|
elif defined(genode):
|
||||||
proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit", noreturn,
|
include genode/env
|
||||||
importcpp: "genodeEnv->parent().exit(@); Genode::sleep_forever()",
|
|
||||||
header: "<base/sleep.h>".}
|
var systemEnv {.exportc: runtimeEnvSym.}: GenodeEnvPtr
|
||||||
|
|
||||||
|
type GenodeEnv* = GenodeEnvPtr
|
||||||
|
## Opaque type representing Genode environment.
|
||||||
|
|
||||||
|
proc quit*(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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
elif defined(nodejs):
|
elif defined(nodejs):
|
||||||
proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit",
|
proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit",
|
||||||
|
|
@ -4215,3 +4225,22 @@ when not defined(js):
|
||||||
type
|
type
|
||||||
ForLoopStmt* {.compilerProc.} = object ## special type that marks a macro
|
ForLoopStmt* {.compilerProc.} = object ## special type that marks a macro
|
||||||
## as a `for-loop macro`:idx:
|
## as a `for-loop macro`:idx:
|
||||||
|
|
||||||
|
when defined(genode):
|
||||||
|
var componentConstructHook*: proc (env: GenodeEnv) {.nimcall.}
|
||||||
|
## Hook into the Genode component bootstrap process.
|
||||||
|
## This hook is called after all globals are initialized.
|
||||||
|
## When this hook is set the component will not automatically exit,
|
||||||
|
## call ``quit`` explicitly to do so. This is the only available method
|
||||||
|
## of accessing the initial Genode environment.
|
||||||
|
|
||||||
|
proc nim_component_construct(env: GenodeEnv) {.exportc.} =
|
||||||
|
## Procedure called during ``Component::construct`` by the loader.
|
||||||
|
if componentConstructHook.isNil:
|
||||||
|
env.quit(programResult)
|
||||||
|
# No native Genode application initialization,
|
||||||
|
# exit as would POSIX.
|
||||||
|
else:
|
||||||
|
componentConstructHook(env)
|
||||||
|
# Perform application initialization
|
||||||
|
# and return to thread entrypoint.
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ when defined(emscripten):
|
||||||
munmap(mmapDescr.realPointer, mmapDescr.realSize)
|
munmap(mmapDescr.realPointer, mmapDescr.realSize)
|
||||||
|
|
||||||
elif defined(genode):
|
elif defined(genode):
|
||||||
include genodealloc # osAllocPages, osTryAllocPages, osDeallocPages
|
include genode/alloc # osAllocPages, osTryAllocPages, osDeallocPages
|
||||||
|
|
||||||
elif defined(posix):
|
elif defined(posix):
|
||||||
const
|
const
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,7 @@ when defined(windows):
|
||||||
importc: "SetThreadAffinityMask", stdcall, header: "<windows.h>".}
|
importc: "SetThreadAffinityMask", stdcall, header: "<windows.h>".}
|
||||||
|
|
||||||
elif defined(genode):
|
elif defined(genode):
|
||||||
|
import genode/env
|
||||||
const
|
const
|
||||||
GenodeHeader = "genode_cpp/threads.h"
|
GenodeHeader = "genode_cpp/threads.h"
|
||||||
type
|
type
|
||||||
|
|
@ -125,11 +126,12 @@ elif defined(genode):
|
||||||
ThreadVarSlot = int
|
ThreadVarSlot = int
|
||||||
|
|
||||||
proc initThread(s: var SysThread,
|
proc initThread(s: var SysThread,
|
||||||
|
env: GenodeEnv,
|
||||||
stackSize: culonglong,
|
stackSize: culonglong,
|
||||||
entry: GenodeThreadProc,
|
entry: GenodeThreadProc,
|
||||||
arg: pointer,
|
arg: pointer,
|
||||||
affinity: cuint) {.
|
affinity: cuint) {.
|
||||||
importcpp: "#.initThread(genodeEnv, @)".}
|
importcpp: "#.initThread(@)".}
|
||||||
|
|
||||||
proc threadVarAlloc(): ThreadVarSlot = 0
|
proc threadVarAlloc(): ThreadVarSlot = 0
|
||||||
|
|
||||||
|
|
@ -569,7 +571,7 @@ when hostOS == "windows":
|
||||||
|
|
||||||
elif defined(genode):
|
elif defined(genode):
|
||||||
var affinityOffset: cuint = 1
|
var affinityOffset: cuint = 1
|
||||||
# CPU affinity offset for next thread, safe to roll-over
|
## CPU affinity offset for next thread, safe to roll-over
|
||||||
|
|
||||||
proc createThread*[TArg](t: var Thread[TArg],
|
proc createThread*[TArg](t: var Thread[TArg],
|
||||||
tp: proc (arg: TArg) {.thread, nimcall.},
|
tp: proc (arg: TArg) {.thread, nimcall.},
|
||||||
|
|
@ -580,6 +582,7 @@ elif defined(genode):
|
||||||
t.dataFn = tp
|
t.dataFn = tp
|
||||||
when hasSharedHeap: t.stackSize = ThreadStackSize
|
when hasSharedHeap: t.stackSize = ThreadStackSize
|
||||||
t.sys.initThread(
|
t.sys.initThread(
|
||||||
|
runtimeEnv,
|
||||||
ThreadStackSize.culonglong,
|
ThreadStackSize.culonglong,
|
||||||
threadProcWrapper[TArg], addr(t), affinityOffset)
|
threadProcWrapper[TArg], addr(t), affinityOffset)
|
||||||
inc affinityOffset
|
inc affinityOffset
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,10 @@ else:
|
||||||
const
|
const
|
||||||
DLLSSLName* = "libssl" & versions & ".dylib"
|
DLLSSLName* = "libssl" & versions & ".dylib"
|
||||||
DLLUtilName* = "libcrypto" & versions & ".dylib"
|
DLLUtilName* = "libcrypto" & versions & ".dylib"
|
||||||
|
elif defined(genode):
|
||||||
|
const
|
||||||
|
DLLSSLName* = "libssl.lib.so"
|
||||||
|
DLLUtilName* = "libcrypto.lib.so"
|
||||||
else:
|
else:
|
||||||
const
|
const
|
||||||
DLLSSLName* = "libssl.so" & versions
|
DLLSSLName* = "libssl.so" & versions
|
||||||
|
|
|
||||||
|
|
@ -20,3 +20,19 @@ v.doSomething()
|
||||||
|
|
||||||
var vf = initVector[float]()
|
var vf = initVector[float]()
|
||||||
vf.doSomething() # Nim uses doSomething[int] here in C++
|
vf.doSomething() # Nim uses doSomething[int] here in C++
|
||||||
|
|
||||||
|
# Alternative definition:
|
||||||
|
# https://github.com/nim-lang/Nim/issues/7653
|
||||||
|
|
||||||
|
type VectorAlt* {.importcpp: "std::vector", header: "<vector>", nodecl.} [T] = object
|
||||||
|
proc mkVector*[T]: VectorAlt[T] {.importcpp: "std::vector<'*0>()", header: "<vector>", constructor, nodecl.}
|
||||||
|
|
||||||
|
proc foo(): VectorAlt[cint] =
|
||||||
|
mkVector[cint]()
|
||||||
|
|
||||||
|
proc bar(): VectorAlt[cstring] =
|
||||||
|
mkVector[cstring]()
|
||||||
|
|
||||||
|
var x = foo()
|
||||||
|
var y = bar()
|
||||||
|
|
||||||
|
|
|
||||||
14
tests/generics/t3977.nim
Normal file
14
tests/generics/t3977.nim
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
discard """
|
||||||
|
output: "42\n42"
|
||||||
|
"""
|
||||||
|
|
||||||
|
type
|
||||||
|
Foo[N: static[int]] = object
|
||||||
|
|
||||||
|
proc foo[N](x: Foo[N]) =
|
||||||
|
let n = N
|
||||||
|
echo N
|
||||||
|
echo n
|
||||||
|
|
||||||
|
var f1: Foo[42]
|
||||||
|
f1.foo
|
||||||
|
|
@ -66,6 +66,18 @@ block: # "IpAddress/Sockaddr conversion"
|
||||||
doAssert(ipaddr_1 == ipaddr_2)
|
doAssert(ipaddr_1 == ipaddr_2)
|
||||||
doAssert($ipaddr_1 == $ipaddr_2)
|
doAssert($ipaddr_1 == $ipaddr_2)
|
||||||
|
|
||||||
|
if sockaddr.ss_family == AF_INET.toInt:
|
||||||
|
var sockaddr4: Sockaddr_in
|
||||||
|
copyMem(addr sockaddr4, addr sockaddr, sizeof(sockaddr4))
|
||||||
|
fromSockAddr(sockaddr4, socklen, ipaddr_2, port_2)
|
||||||
|
elif sockaddr.ss_family == AF_INET6.toInt:
|
||||||
|
var sockaddr6: Sockaddr_in6
|
||||||
|
copyMem(addr sockaddr6, addr sockaddr, sizeof(sockaddr6))
|
||||||
|
fromSockAddr(sockaddr6, socklen, ipaddr_2, port_2)
|
||||||
|
|
||||||
|
doAssert(ipaddr_1 == ipaddr_2)
|
||||||
|
doAssert($ipaddr_1 == $ipaddr_2)
|
||||||
|
|
||||||
|
|
||||||
# ipv6 address of example.com
|
# ipv6 address of example.com
|
||||||
test("2606:2800:220:1:248:1893:25c8:1946")
|
test("2606:2800:220:1:248:1893:25c8:1946")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue