threading code deactivated; tiny C bugfix: don't report warnings to error callback
This commit is contained in:
parent
c065694598
commit
93b3c03dbd
15 changed files with 208 additions and 135 deletions
|
|
@ -1,14 +1,13 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
## Declaration of the Document Object Model for the ECMAScript backend.
|
||||
## (c) 2008 Andreas Rumpf
|
||||
|
||||
when not defined(ecmascript):
|
||||
{.error: "This module only works on the ECMAScript platform".}
|
||||
|
|
|
|||
|
|
@ -1605,10 +1605,8 @@ when not defined(EcmaScript) and not defined(NimrodVM):
|
|||
## can be used to mark a condition to be unlikely. This is a hint for the
|
||||
## optimizer.
|
||||
|
||||
elif defined(ecmaScript):
|
||||
include "system/ecmasys"
|
||||
elif defined(NimrodVM):
|
||||
# Stubs for the GC interface:
|
||||
elif defined(ecmaScript) or defined(NimrodVM):
|
||||
# Stubs:
|
||||
proc GC_disable() = nil
|
||||
proc GC_enable() = nil
|
||||
proc GC_fullCollect() = nil
|
||||
|
|
@ -1620,16 +1618,19 @@ elif defined(NimrodVM):
|
|||
proc getOccupiedMem(): int = return -1
|
||||
proc getFreeMem(): int = return -1
|
||||
proc getTotalMem(): int = return -1
|
||||
|
||||
proc cmp(x, y: string): int =
|
||||
if x == y: return 0
|
||||
if x < y: return -1
|
||||
return 1
|
||||
|
||||
|
||||
proc dealloc(p: pointer) = nil
|
||||
proc alloc(size: int): pointer = nil
|
||||
proc alloc0(size: int): pointer = nil
|
||||
proc realloc(p: Pointer, newsize: int): pointer = nil
|
||||
|
||||
when defined(ecmaScript):
|
||||
include "system/ecmasys"
|
||||
elif defined(NimrodVM):
|
||||
proc cmp(x, y: string): int =
|
||||
if x == y: return 0
|
||||
if x < y: return -1
|
||||
return 1
|
||||
|
||||
{.pop.} # checks
|
||||
{.pop.} # hints
|
||||
|
|
|
|||
|
|
@ -1,26 +1,12 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2008 Andreas Rumpf
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
## Stubs for the GC interface:
|
||||
|
||||
proc GC_disable() = nil
|
||||
proc GC_enable() = nil
|
||||
proc GC_fullCollect() = nil
|
||||
proc GC_setStrategy(strategy: TGC_Strategy) = nil
|
||||
proc GC_enableMarkAndSweep() = nil
|
||||
proc GC_disableMarkAndSweep() = nil
|
||||
proc GC_getStatistics(): string = return ""
|
||||
|
||||
proc getOccupiedMem(): int = return -1
|
||||
proc getFreeMem(): int = return -1
|
||||
proc getTotalMem(): int = return -1
|
||||
|
||||
proc alert(s: cstring) {.importc, nodecl.}
|
||||
|
||||
type
|
||||
|
|
@ -130,8 +116,6 @@ proc raiseIndexError() {.compilerproc, noreturn.} =
|
|||
proc raiseFieldError(f: string) {.compilerproc, noreturn.} =
|
||||
raise newException(EInvalidField, f & " is not accessible")
|
||||
|
||||
|
||||
|
||||
proc SetConstr() {.varargs, pure, compilerproc.} =
|
||||
asm """
|
||||
var result = {};
|
||||
|
|
@ -317,61 +301,58 @@ proc ewriteln(x: cstring) =
|
|||
else:
|
||||
raise newException(EInvalidValue, "<body> element does not exist yet!")
|
||||
|
||||
proc echo*(x: int) = ewriteln($x)
|
||||
proc echo*(x: float) = ewriteln($x)
|
||||
proc echo*(x: bool) = ewriteln(if x: cstring("true") else: cstring("false"))
|
||||
proc echo*(x: string) = ewriteln(x)
|
||||
proc echo*(x: cstring) = ewriteln(x)
|
||||
|
||||
proc echo[Ty](x: Ty) =
|
||||
echo(x)
|
||||
|
||||
proc echo[Ty](x: openArray[Ty]) =
|
||||
for a in items(x): echo(a)
|
||||
proc rawEcho {.compilerproc.} =
|
||||
var node = document.getElementsByTagName("body")[0]
|
||||
if node == nil: raise newException(EIO, "<body> element does not exist yet!")
|
||||
asm """
|
||||
for (var i = 0; i < arguments.length; ++i) {
|
||||
var x = `toEcmaStr`(arguments[i]);
|
||||
`node`.appendChild(document.createTextNode(x))
|
||||
}
|
||||
"""
|
||||
node.appendChild(document.createElement("br"))
|
||||
|
||||
# Arithmetic:
|
||||
proc addInt(a, b: int): int {.pure, compilerproc.} =
|
||||
asm """
|
||||
var result = `a` + `b`;
|
||||
if (result > 2147483647 || result < -2147483648) raiseOverflow();
|
||||
if (result > 2147483647 || result < -2147483648) `raiseOverflow`();
|
||||
return result;
|
||||
"""
|
||||
|
||||
proc subInt(a, b: int): int {.pure, compilerproc.} =
|
||||
asm """
|
||||
var result = `a` - `b`;
|
||||
if (result > 2147483647 || result < -2147483648) raiseOverflow();
|
||||
if (result > 2147483647 || result < -2147483648) `raiseOverflow`();
|
||||
return result;
|
||||
"""
|
||||
|
||||
proc mulInt(a, b: int): int {.pure, compilerproc.} =
|
||||
asm """
|
||||
var result = `a` * `b`;
|
||||
if (result > 2147483647 || result < -2147483648) raiseOverflow();
|
||||
if (result > 2147483647 || result < -2147483648) `raiseOverflow`();
|
||||
return result;
|
||||
"""
|
||||
|
||||
proc divInt(a, b: int): int {.pure, compilerproc.} =
|
||||
asm """
|
||||
if (`b` == 0) raiseDivByZero();
|
||||
if (`b` == -1 && `a` == 2147483647) raiseOverflow();
|
||||
if (`b` == 0) `raiseDivByZero`();
|
||||
if (`b` == -1 && `a` == 2147483647) `raiseOverflow`();
|
||||
return Math.floor(`a` / `b`);
|
||||
"""
|
||||
|
||||
proc modInt(a, b: int): int {.pure, compilerproc.} =
|
||||
asm """
|
||||
if (`b` == 0) raiseDivByZero();
|
||||
if (`b` == -1 && `a` == 2147483647) raiseOverflow();
|
||||
if (`b` == 0) `raiseDivByZero`();
|
||||
if (`b` == -1 && `a` == 2147483647) `raiseOverflow`();
|
||||
return Math.floor(`a` % `b`);
|
||||
"""
|
||||
|
||||
|
||||
|
||||
proc addInt64(a, b: int): int {.pure, compilerproc.} =
|
||||
asm """
|
||||
var result = `a` + `b`;
|
||||
if (result > 9223372036854775807
|
||||
|| result < -9223372036854775808) raiseOverflow();
|
||||
|| result < -9223372036854775808) `raiseOverflow`();
|
||||
return result;
|
||||
"""
|
||||
|
||||
|
|
@ -379,7 +360,7 @@ proc subInt64(a, b: int): int {.pure, compilerproc.} =
|
|||
asm """
|
||||
var result = `a` - `b`;
|
||||
if (result > 9223372036854775807
|
||||
|| result < -9223372036854775808) raiseOverflow();
|
||||
|| result < -9223372036854775808) `raiseOverflow`();
|
||||
return result;
|
||||
"""
|
||||
|
||||
|
|
@ -387,21 +368,21 @@ proc mulInt64(a, b: int): int {.pure, compilerproc.} =
|
|||
asm """
|
||||
var result = `a` * `b`;
|
||||
if (result > 9223372036854775807
|
||||
|| result < -9223372036854775808) raiseOverflow();
|
||||
|| result < -9223372036854775808) `raiseOverflow`();
|
||||
return result;
|
||||
"""
|
||||
|
||||
proc divInt64(a, b: int): int {.pure, compilerproc.} =
|
||||
asm """
|
||||
if (`b` == 0) raiseDivByZero();
|
||||
if (`b` == -1 && `a` == 9223372036854775807) raiseOverflow();
|
||||
if (`b` == 0) `raiseDivByZero`();
|
||||
if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`();
|
||||
return Math.floor(`a` / `b`);
|
||||
"""
|
||||
|
||||
proc modInt64(a, b: int): int {.pure, compilerproc.} =
|
||||
asm """
|
||||
if (`b` == 0) raiseDivByZero();
|
||||
if (`b` == -1 && `a` == 9223372036854775807) raiseOverflow();
|
||||
if (`b` == 0) `raiseDivByZero`();
|
||||
if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`();
|
||||
return Math.floor(`a` % `b`);
|
||||
"""
|
||||
|
||||
|
|
@ -415,13 +396,13 @@ proc internalAssert(file: cstring, line: int) {.pure, compilerproc.} =
|
|||
asm """`e`.message = "[Assertion failure] file: "+`file`+", line: "+`line`"""
|
||||
raise e
|
||||
|
||||
include hti
|
||||
include "system/hti"
|
||||
|
||||
proc isFatPointer(ti: PNimType): bool =
|
||||
# This has to be consistent with the code generator!
|
||||
return ti.base.kind notin {tyRecord, tyRecordConstr, tyObject,
|
||||
return ti.base.kind notin {tyObject,
|
||||
tyArray, tyArrayConstr, tyPureObject, tyTuple,
|
||||
tyEmptySet, tyOpenArray, tySet, tyVar, tyRef, tyPtr}
|
||||
tyOpenArray, tySet, tyVar, tyRef, tyPtr}
|
||||
|
||||
proc NimCopy(x: pointer, ti: PNimType): pointer {.compilerproc.}
|
||||
|
||||
|
|
@ -452,7 +433,7 @@ proc NimCopy(x: pointer, ti: PNimType): pointer =
|
|||
`result`[0] = `x`[0];
|
||||
`result`[1] = `x`[1];
|
||||
"""
|
||||
of tyEmptySet, tySet:
|
||||
of tySet:
|
||||
asm """
|
||||
`result` = {};
|
||||
for (var key in `x`) { `result`[key] = `x`[key]; }
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@
|
|||
# Exception handling code. This is difficult because it has
|
||||
# to work if there is no more memory (but it doesn't yet!).
|
||||
|
||||
var
|
||||
stackTraceNewLine* = "\n" ## undocumented feature; it is replaced by ``<br>``
|
||||
## for CGI applications
|
||||
|
||||
when not defined(windows) or not defined(guiapp):
|
||||
proc writeToStdErr(msg: CString) = write(stdout, msg)
|
||||
|
||||
|
|
@ -32,7 +36,7 @@ type
|
|||
TSafePoint {.compilerproc, final.} = object
|
||||
prev: PSafePoint # points to next safe point ON THE STACK
|
||||
status: int
|
||||
exc: ref E_Base # XXX only needed for bootstrapping
|
||||
exc: ref E_Base # XXX only needed for bootstrapping; unused
|
||||
context: C_JmpBuf
|
||||
|
||||
var
|
||||
|
|
@ -55,6 +59,58 @@ proc pushCurrentException(e: ref E_Base) {.compilerRtl, inl.} =
|
|||
proc popCurrentException {.compilerRtl, inl.} =
|
||||
currException = currException.parent
|
||||
|
||||
# some platforms have native support for stack traces:
|
||||
const
|
||||
nimrodStackTrace = compileOption("stacktrace")
|
||||
nativeStackTrace = (defined(macosx) or defined(linux)) and
|
||||
not nimrodStackTrace and false
|
||||
|
||||
# `nativeStackTrace` does not work for me --> deactivated for now. Maybe for
|
||||
# the next release version.
|
||||
|
||||
when nativeStacktrace:
|
||||
type
|
||||
TDl_info {.importc: "Dl_info", header: "<dlfcn.h>",
|
||||
final, pure.} = object
|
||||
dli_fname: CString
|
||||
dli_fbase: pointer
|
||||
dli_sname: CString
|
||||
dli_saddr: pointer
|
||||
|
||||
proc backtrace(symbols: ptr pointer, size: int): int {.
|
||||
importc: "backtrace", header: "<execinfo.h>".}
|
||||
proc dladdr(addr1: pointer, info: ptr TDl_info): int {.
|
||||
importc: "dladdr", header: "<dlfcn.h>".}
|
||||
|
||||
var
|
||||
tempAddresses: array [0..127, pointer] # cannot be allocated on the stack!
|
||||
tempDlInfo: TDl_info
|
||||
|
||||
proc auxWriteStackTraceWithBacktrace(s: var string) =
|
||||
# This is allowed to be expensive since it only happens during crashes
|
||||
# (but this way you don't need manual stack tracing)
|
||||
var size = backtrace(cast[ptr pointer](addr(tempAddresses)),
|
||||
len(tempAddresses))
|
||||
var enabled = false
|
||||
for i in 0..size-1:
|
||||
var dlresult = dladdr(tempAddresses[i], addr(tempDlInfo))
|
||||
if enabled:
|
||||
if dlresult != 0:
|
||||
var oldLen = s.len
|
||||
add(s, tempDlInfo.dli_fname)
|
||||
if tempDlInfo.dli_sname != nil:
|
||||
for k in 1..max(1, 25-(s.len-oldLen)): add(s, ' ')
|
||||
add(s, tempDlInfo.dli_sname)
|
||||
else:
|
||||
add(s, '?')
|
||||
add(s, stackTraceNewLine)
|
||||
else:
|
||||
if dlresult != 0 and tempDlInfo.dli_sname != nil and
|
||||
c_strcmp(tempDlInfo.dli_sname, "signalHandler") == 0'i32:
|
||||
# Once we're past signalHandler, we're at what the user is
|
||||
# interested in
|
||||
enabled = true
|
||||
|
||||
type
|
||||
PFrame = ptr TFrame
|
||||
TFrame {.importc, nodecl, final.} = object
|
||||
|
|
@ -74,9 +130,6 @@ var
|
|||
|
||||
tempFrames: array [0..127, PFrame] # cannot be allocated on the stack!
|
||||
|
||||
stackTraceNewLine* = "\n" ## undocumented feature; it is replaced by ``<br>``
|
||||
## for CGI applications
|
||||
|
||||
proc auxWriteStackTrace(f: PFrame, s: var string) =
|
||||
const
|
||||
firstCalls = 32
|
||||
|
|
@ -120,7 +173,7 @@ proc auxWriteStackTrace(f: PFrame, s: var string) =
|
|||
add(s, stackTraceNewLine)
|
||||
|
||||
proc rawWriteStackTrace(s: var string) =
|
||||
when compileOption("stacktrace") or compileOption("linetrace"):
|
||||
when nimrodStackTrace:
|
||||
if framePtr == nil:
|
||||
add(s, "No stack traceback available")
|
||||
add(s, stackTraceNewLine)
|
||||
|
|
@ -128,6 +181,10 @@ proc rawWriteStackTrace(s: var string) =
|
|||
add(s, "Traceback (most recent call last)")
|
||||
add(s, stackTraceNewLine)
|
||||
auxWriteStackTrace(framePtr, s)
|
||||
elif nativeStackTrace:
|
||||
add(s, "Traceback from system (most recent call last)")
|
||||
add(s, stackTraceNewLine)
|
||||
auxWriteStackTraceWithBacktrace(s)
|
||||
else:
|
||||
add(s, "No stack traceback available")
|
||||
add(s, stackTraceNewLine)
|
||||
|
|
@ -197,11 +254,6 @@ proc WriteStackTrace() =
|
|||
rawWriteStackTrace(s)
|
||||
writeToStdErr(s)
|
||||
|
||||
#proc stackTraceWrapper {.noconv.} =
|
||||
# writeStackTrace()
|
||||
|
||||
#addQuitProc(stackTraceWrapper)
|
||||
|
||||
var
|
||||
dbgAborting: bool # whether the debugger wants to abort
|
||||
|
||||
|
|
|
|||
|
|
@ -77,14 +77,16 @@ var
|
|||
# collection, not a lock for threads!
|
||||
|
||||
proc lock(gch: var TGcHeap) {.inline.} =
|
||||
if isMultiThreaded:
|
||||
Lock(gch.zctLock)
|
||||
lock(gch.cycleRootsLock)
|
||||
when hasThreadSupport:
|
||||
if isMultiThreaded:
|
||||
Lock(gch.zctLock)
|
||||
lock(gch.cycleRootsLock)
|
||||
|
||||
proc unlock(gch: var TGcHeap) {.inline.} =
|
||||
if isMultiThreaded:
|
||||
unlock(gch.zctLock)
|
||||
unlock(gch.cycleRootsLock)
|
||||
when hasThreadSupport:
|
||||
if isMultiThreaded:
|
||||
unlock(gch.zctLock)
|
||||
unlock(gch.cycleRootsLock)
|
||||
|
||||
proc addZCT(s: var TCellSeq, c: PCell) {.noinline.} =
|
||||
if (c.refcount and rcZct) == 0:
|
||||
|
|
@ -202,15 +204,19 @@ proc prepareDealloc(cell: PCell) =
|
|||
|
||||
proc rtlAddCycleRoot(c: PCell) {.rtl, inl.} =
|
||||
# we MUST access gch as a global here, because this crosses DLL boundaries!
|
||||
if isMultiThreaded: Lock(gch.cycleRootsLock)
|
||||
when hasThreadSupport:
|
||||
if isMultiThreaded: Lock(gch.cycleRootsLock)
|
||||
incl(gch.cycleRoots, c)
|
||||
if isMultiThreaded: Unlock(gch.cycleRootsLock)
|
||||
when hasThreadSupport:
|
||||
if isMultiThreaded: Unlock(gch.cycleRootsLock)
|
||||
|
||||
proc rtlAddZCT(c: PCell) {.rtl, inl.} =
|
||||
# we MUST access gch as a global here, because this crosses DLL boundaries!
|
||||
if isMultiThreaded: Lock(gch.zctLock)
|
||||
when hasThreadSupport:
|
||||
if isMultiThreaded: Lock(gch.zctLock)
|
||||
addZCT(gch.zct, c)
|
||||
if isMultiThreaded: Unlock(gch.zctLock)
|
||||
when hasThreadSupport:
|
||||
if isMultiThreaded: Unlock(gch.zctLock)
|
||||
|
||||
proc decRef(c: PCell) {.inline.} =
|
||||
when stressGC:
|
||||
|
|
@ -480,7 +486,7 @@ proc gcMark(p: pointer) {.inline.} =
|
|||
add(gch.decStack, cell)
|
||||
|
||||
proc markThreadStacks(gch: var TGcHeap) =
|
||||
when isMultiThreaded:
|
||||
when hasThreadSupport:
|
||||
nil
|
||||
|
||||
# ----------------- stack management --------------------------------------
|
||||
|
|
|
|||
|
|
@ -7,12 +7,17 @@
|
|||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
when defined(gcc) or defined(llvm_gcc):
|
||||
const
|
||||
hasThreadSupport = false # deactivate for now: thread stack walking
|
||||
# is missing!
|
||||
maxThreads = 256
|
||||
|
||||
when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
|
||||
proc sync_add_and_fetch(p: var int, val: int): int {.
|
||||
importc: "__sync_add_and_fetch", nodecl.}
|
||||
proc sync_sub_and_fetch(p: var int, val: int): int {.
|
||||
importc: "__sync_sub_and_fetch", nodecl.}
|
||||
elif defined(vcc):
|
||||
elif defined(vcc) and hasThreadSupport:
|
||||
proc sync_add_and_fetch(p: var int, val: int): int {.
|
||||
importc: "NimXadd", nodecl.}
|
||||
else:
|
||||
|
|
@ -20,19 +25,18 @@ else:
|
|||
inc(p, val)
|
||||
result = p
|
||||
|
||||
const
|
||||
isMultiThreaded* = true
|
||||
maxThreads = 256
|
||||
var
|
||||
isMultiThreaded: bool # true when prog created at least 1 thread
|
||||
|
||||
proc atomicInc(memLoc: var int, x: int): int =
|
||||
when isMultiThreaded:
|
||||
when hasThreadSupport:
|
||||
result = sync_add_and_fetch(memLoc, x)
|
||||
else:
|
||||
inc(memLoc, x)
|
||||
result = memLoc
|
||||
|
||||
proc atomicDec(memLoc: var int, x: int): int =
|
||||
when isMultiThreaded:
|
||||
when hasThreadSupport:
|
||||
when defined(sync_sub_and_fetch):
|
||||
result = sync_sub_and_fetch(memLoc, x)
|
||||
else:
|
||||
|
|
@ -85,11 +89,8 @@ type
|
|||
TThreadFunc* = proc (closure: pointer) {.cdecl.}
|
||||
|
||||
proc createThread*(t: var TThread, fn: TThreadFunc) =
|
||||
|
||||
nil
|
||||
|
||||
proc destroyThread*(t: var TThread) =
|
||||
nil
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue