summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2019-11-12 17:05:32 +0100
committerAndreas Rumpf <rumpf_a@web.de>2019-11-13 23:29:21 +0100
commit25c724d38b66aa52b017a63ad6ea59912d627f5a (patch)
treeb12dafdf01ffa676b4d962c42827c9ecb5895c8a
parenteea0cb07cfcebcb5be9e1a942834c7ed675579b9 (diff)
downloadNim-25c724d38b66aa52b017a63ad6ea59912d627f5a.tar.gz
gc:arc: support GC_ref/unref for ref T
-rw-r--r--lib/core/runtime_v2.nim15
-rw-r--r--lib/system.nim2
-rw-r--r--lib/system/excpt.nim4
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) =