Updated Destructors (rest)

This commit is contained in:
Andreas Rumpf 2018-01-04 14:06:50 +01:00
parent 5ddd47c46b
commit f1609baebe
1 changed files with 57 additions and 0 deletions

View File

@ -167,3 +167,60 @@ Rule Pattern Transformed into
# object construction counts as proc call:
c.add T() # calls version B
Interactions with the GC
========================
The implementation of ``ref`` is likely to stay as it is today, a GC'ed pointer. But if the ``seq`` is not
baked by the GC how can ``ref seq[ref T]`` continue to work? The answer is yet another type bound operator
called ``=trace``. With ``=trace`` a container can tell the GC how to access its contents for a GC's
sweeping/tracing step:
.. code-block:: nim
proc `=trace`[T](s: seq[T]; a: Allocator) =
for i in 0 ..< s.len: `=trace`(s.data[i], a)
``=trace`` always takes a second parameter, an ``allocator``. The new ``seq`` and ``string`` implementations
are also based on allocators.
Allocators
==========
The current design for an allocator looks like this:
.. code-block:: nim
type
Allocator* {.inheritable.} = ptr object
alloc*: proc (a: Allocator; size: int; alignment = 8): pointer {.nimcall.}
dealloc*: proc (a: Allocator; p: pointer; size: int) {.nimcall.}
realloc*: proc (a: Allocator; p: pointer; oldSize, newSize: int): pointer {.nimcall.}
var
currentAllocator {.threadvar.}: Allocator
proc getCurrentAllocator*(): Allocator =
result = currentAllocator
proc setCurrentAllocator*(a: Allocator) =
currentAllocator = a
proc alloc*(size: int): pointer =
let a = getCurrentAllocator()
result = a.alloc(a, size)
proc dealloc*(p: pointer; size: int) =
let a = getCurrentAllocator()
a.dealloc(a, size)
proc realloc*(p: pointer; oldSize, newSize: int): pointer =
let a = getCurrentAllocator()
result = a.realloc(a, oldSize, newSize)
Pluggable GC
============
To be written.