diff options
author | Araq <rumpf_a@web.de> | 2019-11-12 17:05:32 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2019-11-13 23:29:21 +0100 |
commit | 25c724d38b66aa52b017a63ad6ea59912d627f5a (patch) | |
tree | b12dafdf01ffa676b4d962c42827c9ecb5895c8a | |
parent | eea0cb07cfcebcb5be9e1a942834c7ed675579b9 (diff) | |
download | Nim-25c724d38b66aa52b017a63ad6ea59912d627f5a.tar.gz |
gc:arc: support GC_ref/unref for ref T
-rw-r--r-- | lib/core/runtime_v2.nim | 15 | ||||
-rw-r--r-- | lib/system.nim | 2 | ||||
-rw-r--r-- | lib/system/excpt.nim | 4 |
3 files changed, 16 insertions, 5 deletions
diff --git a/lib/core/runtime_v2.nim b/lib/core/runtime_v2.nim index d18f91f6f..0d55ff4ac 100644 --- a/lib/core/runtime_v2.nim +++ b/lib/core/runtime_v2.nim @@ -28,8 +28,8 @@ hash of ``package & "." & module & "." & name`` to save space. type RefHeader = object rc: int # the object header is now a single RC field. - # we could remove it in non-debug builds but this seems - # unwise. + # we could remove it in non-debug builds for the 'owned ref' + # design but this seems unwise. template `+!`(p: pointer, s: int): pointer = cast[pointer](cast[int](p) +% s) @@ -121,6 +121,17 @@ proc nimDecRefIsLast(p: pointer): bool {.compilerRtl, inl.} = else: dec head(p).rc +proc GC_unref*[T](x: ref T) = + ## New runtime only supports this operation for 'ref T'. + if nimDecRefIsLast(cast[pointer](x)): + # XXX this does NOT work for virtual destructors! + `=destroy`(x[]) + nimRawDispose(cast[pointer](x)) + +proc GC_ref*[T](x: ref T) = + ## New runtime only supports this operation for 'ref T'. + if x != nil: nimIncRef(cast[pointer](x)) + proc isObj(obj: PNimType, subclass: cstring): bool {.compilerRtl, inl.} = proc strstr(s, sub: cstring): cstring {.header: "<string.h>", importc.} diff --git a/lib/system.nim b/lib/system.nim index 7818b8d26..19b96d4a1 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -3269,7 +3269,7 @@ when not defined(nimscript) and hasAlloc: ## Expands operating GC stack range to `theStackBottom`. Does nothing ## if current stack bottom is already lower than `theStackBottom`. - else: + elif defined(JS): template GC_disable* = {.warning: "GC_disable is a no-op in JavaScript".} diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index 4074002fe..2595a045b 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -531,12 +531,12 @@ when not defined(noSignalHandler) and not defined(useNimRtl): when defined(memtracker): logPendingOps() when hasSomeStackTrace: - GC_disable() + when not defined(gcDestructors): GC_disable() var buf = newStringOfCap(2000) rawWriteStackTrace(buf) processSignal(sign, buf.add) # nice hu? currying a la Nim :-) showErrorMessage(buf) - GC_enable() + when not defined(gcDestructors): GC_enable() else: var msg: cstring template asgn(y) = |