mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-03 18:34:43 +00:00
refined and documented regionized pointers
This commit is contained in:
@@ -738,27 +738,17 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
|
||||
result = typeRel(c, f.sons[0], a.sons[0])
|
||||
if result <= isConvertible:
|
||||
result = isNone # BUGFIX!
|
||||
of tyPtr:
|
||||
case a.kind
|
||||
of tyPtr:
|
||||
for i in 0..min(f.len, a.len)-2:
|
||||
of tyPtr, tyRef:
|
||||
if a.kind == f.kind:
|
||||
# ptr[R, T] can be passed to ptr[T], but not the other way round:
|
||||
if a.len < f.len: return isNone
|
||||
for i in 0..f.len-2:
|
||||
if typeRel(c, f.sons[i], a.sons[i]) == isNone: return isNone
|
||||
result = typeRel(c, f.lastSon, a.lastSon)
|
||||
if result <= isConvertible: result = isNone
|
||||
elif tfNotNil in f.flags and tfNotNil notin a.flags:
|
||||
result = isNilConversion
|
||||
of tyNil: result = f.allowsNil
|
||||
else: discard
|
||||
of tyRef:
|
||||
case a.kind
|
||||
of tyRef:
|
||||
for i in 0..min(f.len, a.len)-2:
|
||||
if typeRel(c, f.sons[i], a.sons[i]) == isNone: return isNone
|
||||
result = typeRel(c, base(f), base(a))
|
||||
if result <= isConvertible: result = isNone
|
||||
elif tfNotNil in f.flags and tfNotNil notin a.flags:
|
||||
result = isNilConversion
|
||||
of tyNil: result = f.allowsNil
|
||||
elif a.kind == tyNil: result = f.allowsNil
|
||||
else: discard
|
||||
of tyProc:
|
||||
result = procTypeRel(c, f, a)
|
||||
@@ -774,7 +764,11 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
|
||||
of tyNil: result = f.allowsNil
|
||||
of tyProc:
|
||||
if a.callConv != ccClosure: result = isConvertible
|
||||
of tyPtr, tyCString: result = isConvertible
|
||||
of tyPtr:
|
||||
# 'pointer' is NOT compatible to regionized pointers
|
||||
# so 'dealloc(regionPtr)' fails:
|
||||
if a.len == 1: result = isConvertible
|
||||
of tyCString: result = isConvertible
|
||||
else: discard
|
||||
of tyString:
|
||||
case a.kind
|
||||
|
||||
@@ -1366,6 +1366,65 @@ not nilable pointers. The details of this analysis are still to be specified
|
||||
here.
|
||||
|
||||
|
||||
Memory regions
|
||||
--------------
|
||||
|
||||
The types ``ref`` and ``ptr`` can get an optional `region`:idx: annotation.
|
||||
A region has to be an object type.
|
||||
|
||||
Regions are very useful to separate user space and kernel memory in the
|
||||
development of OS kernels:
|
||||
|
||||
.. code-block:: nimrod
|
||||
type
|
||||
Kernel = object
|
||||
Userspace = object
|
||||
|
||||
var a: ptr[Kernel, Stat]
|
||||
var b: ptr[Userspace, Stat]
|
||||
|
||||
# the following does not compile as the pointer types are incompatible:
|
||||
a = b
|
||||
|
||||
In order to make generic code easier tor write ``ptr T`` is a subtype
|
||||
of ``ptr[R, T]`` for any ``R``.
|
||||
|
||||
Furthermore the subtype relation of the region object types is lifted to
|
||||
the pointer types: If ``A <: B`` then ``ptr[T, A] <: ptr[T, B]``. This can be
|
||||
used to model subregions of memory. As a special typing rule ``ptr[R, T]`` is
|
||||
not compatible to ``pointer`` to prevent the following from compiling:
|
||||
|
||||
.. code-block:: nimrod
|
||||
# from system
|
||||
proc dealloc(p: pointer)
|
||||
|
||||
# wrap some scripting language
|
||||
type
|
||||
PythonsHeap = object
|
||||
PyObjectHeader = object
|
||||
rc: int
|
||||
typ: pointer
|
||||
PyObject = ptr[PythonsHeap, PyObjectHeader]
|
||||
|
||||
proc createPyObject(): PyObject {.importc: "...".}
|
||||
proc destroyPyObject(x: PyObject) {.importc: "...".}
|
||||
|
||||
var foo = createPyObject()
|
||||
# type error here, how convenient:
|
||||
dealloc(foo)
|
||||
|
||||
|
||||
Future directions:
|
||||
|
||||
* Memory regions might become available for ``string`` and ``seq`` too.
|
||||
* Bultin regions like ``private``, ``global`` and ``local`` will
|
||||
prove very useful for the upcoming OpenCL target.
|
||||
* Bultin "regions" can model ``lent`` and ``unique`` pointers.
|
||||
* Syntactially ``ptr`` might become an infix operator so that ``region ptr T``
|
||||
is transformed into ``ptr[region, T]``.
|
||||
|
||||
|
||||
|
||||
Procedural type
|
||||
---------------
|
||||
A `procedural type`:idx: is internally a pointer to a procedure. ``nil`` is
|
||||
|
||||
1
todo.txt
1
todo.txt
@@ -1,7 +1,6 @@
|
||||
version 0.9.4
|
||||
=============
|
||||
|
||||
- document region pointers
|
||||
|
||||
Bugs
|
||||
====
|
||||
|
||||
@@ -145,6 +145,7 @@ Language Additions
|
||||
- Anonymous iterators are now supported and iterators can capture variables
|
||||
of an outer proc.
|
||||
- The experimental ``strongSpaces`` parsing mode has been implemented.
|
||||
- You can annotate pointer types with regions for increased type safety.
|
||||
|
||||
|
||||
Tools improvements
|
||||
|
||||
Reference in New Issue
Block a user