summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorAndreas Rumpf <andreas@andreas-desktop>2010-07-29 21:30:04 +0200
committerAndreas Rumpf <andreas@andreas-desktop>2010-07-29 21:30:04 +0200
commitff02ce2d50d8a4b445f9fba6076527c3db62425c (patch)
tree065d5ecddb38f871e516b49c333f565b6cba9b31 /lib
parent804e2ac89d378b87e0ec8c723f607aa4271c57bb (diff)
downloadNim-ff02ce2d50d8a4b445f9fba6076527c3db62425c.tar.gz
handling of compiler procs improved for DLL generation
Diffstat (limited to 'lib')
-rwxr-xr-xlib/nimrtl.nim39
-rwxr-xr-xlib/pure/strutils.nim41
-rwxr-xr-xlib/system.nim54
-rw-r--r--lib/system/cgprocs.nim14
-rwxr-xr-xlib/system/dyncalls.nim7
-rwxr-xr-xlib/system/gc.nim22
-rwxr-xr-xlib/system/inclrtl.nim45
-rwxr-xr-xlib/system/mmdisp.nim75
-rwxr-xr-xlib/system/repr.nim263
-rwxr-xr-xlib/system/sysio.nim8
-rwxr-xr-xlib/system/sysstr.nim11
11 files changed, 302 insertions, 277 deletions
diff --git a/lib/nimrtl.nim b/lib/nimrtl.nim
new file mode 100755
index 000000000..c61824f49
--- /dev/null
+++ b/lib/nimrtl.nim
@@ -0,0 +1,39 @@
+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2010 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## Main file to generate a DLL from the standard library. 
+## The default Nimrtl does not only contain the ``system`` module, but these 
+## too:
+##
+## * strutils
+## * parseutils
+## * parseopt
+## * parsecfg
+## * strtabs
+## * times
+## * os
+## * osproc
+## * pegs
+## * unicode
+## * ropes
+## * re
+## 
+## So the resulting dynamic library is quite big. However, it is very easy to
+## strip modules out. Just modify the ``import`` statement in
+## ``lib/nimrtl.nim`` and recompile. Note that simply *adding* a module
+## here is not sufficient, though.
+
+when system.appType != "lib":
+  {.error: "This file has to be compiled as a library!".}
+
+when not defined(createNimRtl): 
+  {.error: "This file has to be compiled with '-d:createNimRtl'".}
+
+
+
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index 38f6ffa9a..ee56deab3 100755
--- a/lib/pure/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -125,19 +125,6 @@ proc find*(s: string, chars: set[char], start: int = 0): int {.noSideEffect.}
   ## Searches for `chars` in `s` starting at position `start`. If `s` contains

   ## none of the characters in `chars`, -1 is returned.

 

-proc replaceStr*(s, sub, by: string): string {.noSideEffect, deprecated.}

-  ## Replaces `sub` in `s` by the string `by`.

-  ## **Deprecated since version 0.8.0**: Use `replace` instead.

-

-proc replaceStr*(s: string, sub, by: char): string {.noSideEffect, deprecated.}

-  ## optimized version for characters.

-  ## **Deprecated since version 0.8.0**: Use `replace` instead.

-

-proc deleteStr*(s: var string, first, last: int) {.deprecated.}

-  ## Deletes in `s` the characters at position `first` .. `last`. This modifies

-  ## `s` itself, it does not return a copy.

-  ## **Deprecated since version 0.8.0**: Use `delete` instead.

-

 proc toOctal*(c: char): string

   ## Converts a character `c` to its octal representation. The resulting

   ## string may not have a leading zero. Its length is always exactly 3.

@@ -241,24 +228,6 @@ iterator splitLines*(s: string): string =
     else: break # was '\0'

     first = last

 

-proc splitLinesSeq*(s: string): seq[string] {.noSideEffect, deprecated.} =

-  ## The same as `splitLines`, but is a proc that returns a sequence 

-  ## of substrings.

-  ## **Deprecated since version 0.8.0**: Use `splitLines` instead.

-  accumulateResult(splitLines(s))

-

-proc splitSeq*(s: string, seps: set[char] = Whitespace): seq[string] {.

-  noSideEffect, deprecated.} =

-  ## The same as `split`, but is a proc that returns a sequence of substrings.

-  ## **Deprecated since version 0.8.0**: Use `split` instead.

-  accumulateResult(split(s, seps))

-

-proc splitSeq*(s: string, sep: char): seq[string] {.noSideEffect, 

-                                                    deprecated.} =

-  ## The same as `split`, but is a proc that returns a sequence of substrings.

-  ## **Deprecated since version 0.8.0**: Use `split` instead.

-  accumulateResult(split(s, sep))

-

 proc splitLines*(s: string): seq[string] {.noSideEffect.} =

   ## The same as the `splitLines` iterator, but is a proc that returns a 

   ## sequence of substrings.

@@ -328,12 +297,6 @@ proc ParseHexInt*(s: string): int {.noSideEffect, procvar.}
   ## following optional prefixes: ``0x``, ``0X``, ``#``. 

   ## Underscores within `s` are ignored.

 

-# the stringify and format operators:

-proc toString*[Ty](x: Ty): string {.deprecated.}

-  ## This generic proc is the same as the stringify operator `$`.

-  ##

-  ## **Deprecated since version 0.8.2:** Use `$` instead.

-

 proc repeatChar*(count: int, c: Char = ' '): string

   ## Returns a string of length `count` consisting only of

   ## the character `c`.

@@ -670,10 +633,6 @@ proc delete*(s: var string, first, last: int) =
     inc(j)

   setlen(s, newLen)

 

-proc replaceStr(s, sub, by: string): string = return replace(s, sub, by)

-proc replaceStr(s: string, sub, by: char): string = return replace(s, sub, by)

-proc deleteStr(s: var string, first, last: int) = delete(s, first, last)

-

 # parsing numbers:

 

 proc toHex(x: BiggestInt, len: int): string =

diff --git a/lib/system.nim b/lib/system.nim
index d3450902e..fec31eba0 100755
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -667,6 +667,8 @@ proc `&` * (x: char, y: string): string {.
 proc add*(x: var string, y: char) {.magic: "AppendStrCh", noSideEffect.}
 proc add*(x: var string, y: string) {.magic: "AppendStrStr", noSideEffect.}
 
+include "system/cgprocs"
+
 when not defined(ECMAScript):
   {.push overflow_checks:off}
   proc add* (x: var string, y: cstring) =
@@ -732,7 +734,6 @@ type
     ## is the signed integer type that should be used for converting
     ## pointers to integer addresses for readability.
 
-type
   BiggestInt* = int64
     ## is an alias for the biggest signed integer type the Nimrod compiler
     ## supports. Currently this is ``int64``, but it is platform-dependant
@@ -767,7 +768,7 @@ type # these work for most platforms:
   cstringArray* {.importc: "char**", nodecl.} = ptr array [0..50_000, cstring]
     ## This is binary compatible to the type ``char**`` in *C*. The array's
     ## high value is large enough to disable bounds checking in practice.
-    ## Use cstringArrayToSeq to convert it into a ``seq[string]``.
+    ## Use `cstringArrayToSeq` to convert it into a ``seq[string]``.
 
   TEndian* = enum ## is a type describing the endianness of a processor.
     littleEndian, bigEndian
@@ -823,6 +824,8 @@ const
     ## a string that describes the application type. Possible values:
     ## "console", "gui", "lib".
   
+include "system/inclrtl"
+  
 proc toFloat*(i: int): float {.
   magic: "ToFloat", noSideEffect, importc: "toFloat".}
   ## converts an integer `i` into a ``float``. If the conversion
@@ -897,23 +900,23 @@ proc equalMem*(a, b: Pointer, size: int): bool {.
   ## otherwise. Like any procedure dealing with raw memory this is
   ## *unsafe*.
 
-proc alloc*(size: int): pointer {.noconv.}
+proc alloc*(size: int): pointer {.noconv, rtl.}
   ## allocates a new memory block with at least ``size`` bytes. The
   ## block has to be freed with ``realloc(block, 0)`` or
   ## ``dealloc(block)``. The block is not initialized, so reading
   ## from it before writing to it is undefined behaviour!
-proc alloc0*(size: int): pointer {.noconv.}
+proc alloc0*(size: int): pointer {.noconv, rtl.}
   ## allocates a new memory block with at least ``size`` bytes. The
   ## block has to be freed with ``realloc(block, 0)`` or
   ## ``dealloc(block)``. The block is initialized with all bytes
   ## containing zero, so it is somewhat safer than ``alloc``.
-proc realloc*(p: Pointer, newsize: int): pointer {.noconv.}
+proc realloc*(p: Pointer, newsize: int): pointer {.noconv, rtl.}
   ## grows or shrinks a given memory block. If p is **nil** then a new
   ## memory block is returned. In either way the block has at least
   ## ``newsize`` bytes. If ``newsize == 0`` and p is not **nil**
   ## ``realloc`` calls ``dealloc(p)``. In other cases the block has to
   ## be freed with ``dealloc``.
-proc dealloc*(p: Pointer) {.noconv.}
+proc dealloc*(p: Pointer) {.noconv, rtl.}
   ## frees the memory allocated with ``alloc``, ``alloc0`` or
   ## ``realloc``. This procedure is dangerous! If one forgets to
   ## free the memory a leak occurs; if one tries to access freed
@@ -1009,14 +1012,14 @@ var
 
 # GC interface:
 
-proc getOccupiedMem*(): int
+proc getOccupiedMem*(): int {.rtl.}
   ## returns the number of bytes that are owned by the process and hold data.
 
-proc getFreeMem*(): int
+proc getFreeMem*(): int {.rtl.}
   ## returns the number of bytes that are owned by the process, but do not
   ## hold any meaningful data.
 
-proc getTotalMem*(): int
+proc getTotalMem*(): int {.rtl.}
   ## returns the number of bytes that are owned by the process.
 
 
@@ -1205,15 +1208,15 @@ proc each*[T](data: var openArray[T], op: proc (x: var T)) =
 
 # ----------------- GC interface ---------------------------------------------
 
-proc GC_disable*()
+proc GC_disable*() {.rtl.}
   ## disables the GC. If called n-times, n calls to `GC_enable` are needed to
   ## reactivate the GC. Note that in most circumstances one should only disable
   ## the mark and sweep phase with `GC_disableMarkAndSweep`.
 
-proc GC_enable*()
+proc GC_enable*() {.rtl.}
   ## enables the GC again.
 
-proc GC_fullCollect*()
+proc GC_fullCollect*() {.rtl.}
   ## forces a full garbage collection pass.
   ## Ordinary code does not need to call this (and should not).
 
@@ -1224,18 +1227,18 @@ type
     gcOptimizeTime,    ## optimize for speed
     gcOptimizeSpace    ## optimize for memory footprint
 
-proc GC_setStrategy*(strategy: TGC_Strategy)
+proc GC_setStrategy*(strategy: TGC_Strategy) {.rtl.}
   ## tells the GC the desired strategy for the application.
 
-proc GC_enableMarkAndSweep*()
-proc GC_disableMarkAndSweep*()
+proc GC_enableMarkAndSweep*() {.rtl.}
+proc GC_disableMarkAndSweep*() {.rtl.}
   ## the current implementation uses a reference counting garbage collector
   ## with a seldomly run mark and sweep phase to free cycles. The mark and
   ## sweep phase may take a long time and is not needed if the application
   ## does not create cycles. Thus the mark and sweep phase can be deactivated
   ## and activated separately from the rest of the GC.
 
-proc GC_getStatistics*(): string
+proc GC_getStatistics*(): string {.rtl.}
   ## returns an informative string about the GC's activity. This may be useful
   ## for tweaking.
   
@@ -1372,23 +1375,14 @@ when not defined(EcmaScript) and not defined(NimrodVM):
       ## appropriately. It also annoys people if redirection via ``>output.txt``
       ## does not work because the program writes to ``stderr``.
 
-  proc OpenFile*(f: var TFile, filename: string,
-                 mode: TFileMode = fmRead, 
-                 bufSize: int = -1): Bool {.deprecated.}
-    ## **Deprecated since version 0.8.0**: Use `open` instead.
-
-  proc OpenFile*(f: var TFile, filehandle: TFileHandle,
-                 mode: TFileMode = fmRead): Bool {.deprecated.}
-    ## **Deprecated since version 0.8.0**: Use `open` instead.
-
   proc Open*(f: var TFile, filename: string,
              mode: TFileMode = fmRead, bufSize: int = -1): Bool
     ## Opens a file named `filename` with given `mode`.
     ##
     ## Default mode is readonly. Returns true iff the file could be opened.
     ## This throws no exception if the file could not be opened. The reason is
-    ## that the programmer needs to provide an appropriate error message anyway
-    ## (yes, even in scripts).
+    ## that the programmer needs to provide an appropriate error message 
+    ## anyway.
 
   proc Open*(f: var TFile, filehandle: TFileHandle,
              mode: TFileMode = fmRead): Bool
@@ -1403,10 +1397,6 @@ when not defined(EcmaScript) and not defined(NimrodVM):
     ##
     ## Default mode is readonly. Returns true iff the file could be reopened.
 
-  proc CloseFile*(f: TFile) {.importc: "fclose", nodecl, deprecated.}
-    ## Closes the file.
-    ## **Deprecated since version 0.8.0**: Use `close` instead.
-
   proc Close*(f: TFile) {.importc: "fclose", nodecl.}
     ## Closes the file.
 
@@ -1545,7 +1535,7 @@ when not defined(EcmaScript) and not defined(NimrodVM):
   const
     GenericSeqSize = (2 * sizeof(int))
     
-  proc reprAny(p: pointer, typ: PNimType): string {.compilerproc.}
+  proc reprAny(p: pointer, typ: PNimType): string {.compilerRtl.}
 
   proc getDiscriminant(aa: Pointer, n: ptr TNimNode): int =
     assert(n.kind == nkCase)
diff --git a/lib/system/cgprocs.nim b/lib/system/cgprocs.nim
new file mode 100644
index 000000000..40aca033b
--- /dev/null
+++ b/lib/system/cgprocs.nim
@@ -0,0 +1,14 @@
+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2010 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+# Headers for procs that the code generator depends on ("compilerprocs")
+
+proc addChar(s: NimString, c: char): NimString {.compilerProc.}
+
+
diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim
index 0946ee355..cb665c5cb 100755
--- a/lib/system/dyncalls.nim
+++ b/lib/system/dyncalls.nim
@@ -24,7 +24,12 @@ proc nimUnloadLibrary(lib: TLibHandle) {.compilerproc.}
 proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr {.compilerproc.}
 
 proc nimLoadLibraryError(path: string) {.compilerproc, noinline.} =
-  raise newException(EInvalidLibrary, "could not load: " & path)
+  when true:
+    # carefully written to avoid memory allocation:
+    stdout.write("could not load: ")
+    quit(path)
+  else:
+    raise newException(EInvalidLibrary, "could not load: " & path)
 
 # this code was inspired from Lua's source code:
 # Lua - An Extensible Extension Language
diff --git a/lib/system/gc.nim b/lib/system/gc.nim
index 1e9cd5a4a..f21f5bc01 100755
--- a/lib/system/gc.nim
+++ b/lib/system/gc.nim
@@ -74,13 +74,13 @@ var
     # This is wasteful but safe. This is a lock against recursive garbage
     # collection, not a lock for threads!
 
-proc unsureAsgnRef(dest: ppointer, src: pointer) {.compilerproc.}
+proc unsureAsgnRef(dest: ppointer, src: pointer) {.compilerRtl.}
   # unsureAsgnRef updates the reference counters only if dest is not on the
   # stack. It is used by the code generator if it cannot decide wether a
   # reference is in the stack or not (this can happen for var parameters).
-#proc growObj(old: pointer, newsize: int): pointer {.compilerproc.}
-proc newObj(typ: PNimType, size: int): pointer {.compilerproc.}
-proc newSeq(typ: PNimType, len: int): pointer {.compilerproc.}
+
+proc newObj(typ: PNimType, size: int): pointer {.compilerRtl.}
+proc newSeq(typ: PNimType, len: int): pointer {.compilerRtl.}
 
 proc addZCT(s: var TCellSeq, c: PCell) {.noinline.} =
   if (c.refcount and rcZct) == 0:
@@ -214,8 +214,10 @@ proc prepareDealloc(cell: PCell) =
     (cast[TFinalizer](cell.typ.finalizer))(cellToUsr(cell))
     dec(recGcLock)
 
-proc setStackBottom(theStackBottom: pointer) {.compilerproc.} =
-  stackBottom = theStackBottom
+proc setStackBottom(theStackBottom: pointer) {.compilerRtl.} =
+  # the first init must be the one that defines the stack bottom:
+  if stackBottom == nil:
+    stackBottom = theStackBottom
 
 proc PossibleRoot(gch: var TGcHeap, c: PCell) {.inline.} =
   if canbeCycleRoot(c): incl(gch.cycleRoots, c)
@@ -236,10 +238,10 @@ proc incRef(c: PCell) {.inline.} =
   if canBeCycleRoot(c):
     incl(gch.cycleRoots, c)
 
-proc nimGCref(p: pointer) {.compilerproc, inline.} = incRef(usrToCell(p))
-proc nimGCunref(p: pointer) {.compilerproc, inline.} = decRef(usrToCell(p))
+proc nimGCref(p: pointer) {.compilerRtl, inl.} = incRef(usrToCell(p))
+proc nimGCunref(p: pointer) {.compilerRtl, inl.} = decRef(usrToCell(p))
 
-proc asgnRef(dest: ppointer, src: pointer) {.compilerproc, inline.} =
+proc asgnRef(dest: ppointer, src: pointer) {.compilerRtl, inl.} =
   # the code generator calls this proc!
   assert(not isOnStack(dest))
   # BUGFIX: first incRef then decRef!
@@ -247,7 +249,7 @@ proc asgnRef(dest: ppointer, src: pointer) {.compilerproc, inline.} =
   if dest^ != nil: decRef(usrToCell(dest^))
   dest^ = src
 
-proc asgnRefNoCycle(dest: ppointer, src: pointer) {.compilerproc, inline.} =
+proc asgnRefNoCycle(dest: ppointer, src: pointer) {.compilerRtl, inl.} =
   # the code generator calls this proc if it is known at compile time that no 
   # cycle is possible.
   if src != nil: 
diff --git a/lib/system/inclrtl.nim b/lib/system/inclrtl.nim
new file mode 100755
index 000000000..28965b4b1
--- /dev/null
+++ b/lib/system/inclrtl.nim
@@ -0,0 +1,45 @@
+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2010 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## Pragmas for RTL generation. Has to be an include, because user-defined
+## pragmas cannot be exported.
+
+# There are 3 different usages:
+# 1) Ordinary imported code.
+# 2) Imported from nimrtl.
+#    -> defined(useNimRtl) or appType == "lib" and not defined(createNimRtl)
+# 3) Exported into nimrtl.
+#    -> appType == "lib" and defined(createNimRtl)
+
+when defined(createNimRtl):
+  when defined(useNimRtl): 
+    {.error: "Cannot create and use nimrtl at the same time!".}
+  elif appType != "lib":
+    {.error: "nimrtl must be build as a library!".}
+
+when defined(createNimRtl): 
+  # NOTE: compilerproc cannot make use of name mangling!
+  {.pragma: rtl, exportc: "nimrtl_$1", dynlib.}
+  {.pragma: inl.}
+  {.pragma: compilerRtl, compilerproc, exportc: "nimrtl_$1", dynlib.}
+elif defined(useNimRtl):
+  when hostOS == "windows": 
+    const nimrtl* = "nimrtl.dll"
+  elif hostOS == "macosx":
+    const nimrtl* = "nimrtl.dynlib"
+  else: 
+    const nimrtl* = "libnimrtl.so"
+  {.pragma: rtl, importc: "nimrtl_$1", dynlib: nimrtl.}
+  {.pragma: inl.}
+  {.pragma: compilerRtl, compilerproc, importc: "nimrtl_$1", dynlib: nimrtl.}
+else:
+  {.pragma: rtl.}
+  {.pragma: inl, inline.}
+  {.pragma: compilerRtl, compilerproc.}
+
diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim
index 44b3f7326..ff61ea1fe 100755
--- a/lib/system/mmdisp.nim
+++ b/lib/system/mmdisp.nim
@@ -187,60 +187,35 @@ elif defined(nogc):
     dest^ = src
 
   include "system/cellsets"
-elif appType == "lib": 
-  {.warning: "gc in a library context may not work".}
-  when hostOS == "windows": 
-    const nimrtl = "nimrtl.dll"
-  elif hostOS == "macosx":
-    const nimrtl = "nimrtl.dynlib"
-  else: 
-    const nimrtl = "libnimrtl.so"
-  
-  when not defined(includeGC):
-    # ordinary client; use the GC from nimrtl.dll:
-    proc initGC() {.cdecl, importc, dynlib: nimrtl.}
-    proc GC_disable() {.cdecl, importc, dynlib: nimrtl.}
-    proc GC_enable() {.cdecl, importc, dynlib: nimrtl.}
-    proc GC_fullCollect() {.cdecl, importc, dynlib: nimrtl.}
-    proc GC_setStrategy(strategy: TGC_Strategy) {.
-      cdecl, importc, dynlib: nimrtl.}
-    proc GC_enableMarkAndSweep() {.cdecl, importc, dynlib: nimrtl.}
-    proc GC_disableMarkAndSweep() {.cdecl, importc, dynlib: nimrtl.}
-    proc GC_getStatistics(): string {.cdecl, importc, dynlib: nimrtl.}
-
-    proc newObj(typ: PNimType, size: int): pointer {.
-      compilerproc, cdecl, importc, dynlib: nimrtl.}
-    proc newSeq(typ: PNimType, len: int): pointer {.
-      compilerproc, cdecl, importc, dynlib: nimrtl.}
-    proc growObj(old: pointer, newsize: int): pointer {.
-      cdecl, importc, dynlib: nimrtl.}
-      
-    proc setStackBottom(theStackBottom: pointer) {.
-      compilerproc, cdecl, importc, dynlib: nimrtl.}
-    proc nimGCref(p: pointer) {.
-      compilerproc, cdecl, importc, dynlib: nimrtl.}
-    proc nimGCunref(p: pointer) {.
-      compilerproc, cdecl, importc, dynlib: nimrtl.}
-    
-    # The write barrier is performance critical!
-    # XXX We should ensure that they are inlined here.
-    # Later implementations will do this.
+elif defined(useNimRtl): 
+  proc initGC() = nil
+
+  proc newObj(typ: PNimType, size: int): pointer {.compilerRtl.}
+  proc newSeq(typ: PNimType, len: int): pointer {.compilerRtl.}
+  proc growObj(old: pointer, newsize: int): pointer {.rtl.}
     
-    proc unsureAsgnRef(dest: ppointer, src: pointer) {.
-      compilerproc, cdecl, importc, dynlib: nimrtl.}
-    proc asgnRef(dest: ppointer, src: pointer) {.
-      compilerproc, cdecl, importc, dynlib: nimrtl.}
-    proc asgnRefNoCycle(dest: ppointer, src: pointer) {.
-      compilerproc, cdecl, importc, dynlib: nimrtl.}
+  proc setStackBottom(theStackBottom: pointer) {.compilerProc, inline.} = 
+    # This happens before setStackBottom has been loaded by dlsym(), so
+    # we simply provide a dummy implemenation here for the code gen. No
+    # harm is done by this.
+    nil
     
-  else:
-    # include the GC and export it!
-    include "system/alloc"
-    include "system/cellsets"
-    assert(sizeof(TCell) == sizeof(TFreeCell))
-    include "system/gc"
+  proc nimGCref(p: pointer) {.compilerRtl.}
+  proc nimGCunref(p: pointer) {.compilerRtl.}
+  
+  # The write barrier is performance critical!
+  # XXX We should ensure that they are inlined here.
+  # Later implementations will do this.
   
+  proc unsureAsgnRef(dest: ppointer, src: pointer) {.
+    compilerRtl.}
+  proc asgnRef(dest: ppointer, src: pointer) {.
+    compilerRtl.}
+  proc asgnRefNoCycle(dest: ppointer, src: pointer) {.
+    compilerRtl.}
+
   include "system/cellsets"    
+
 else:
   include "system/alloc"
   include "system/cellsets"
diff --git a/lib/system/repr.nim b/lib/system/repr.nim
index e340f1d7c..b597cb0ce 100755
--- a/lib/system/repr.nim
+++ b/lib/system/repr.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nimrod's Runtime Library
-#        (c) Copyright 2009 Andreas Rumpf
+#        (c) Copyright 2010 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -35,15 +35,15 @@ proc reprStrAux(result: var string, s: string) =
     else: result.add(c)
   add result, "\""
 
-proc reprStr(s: string): string {.compilerproc.} =
+proc reprStr(s: string): string {.compilerRtl.} =
   result = ""
   reprStrAux(result, s)
 
-proc reprBool(x: bool): string {.compilerproc.} =
+proc reprBool(x: bool): string {.compilerRtl.} =
   if x: result = "true"
   else: result = "false"
 
-proc reprChar(x: char): string {.compilerproc.} =
+proc reprChar(x: char): string {.compilerRtl.} =
   result = "\'"
   case x
   of '"': add result, "\\\""
@@ -52,7 +52,7 @@ proc reprChar(x: char): string {.compilerproc.} =
   else: add result, x
   add result, "\'"
 
-proc reprEnum(e: int, typ: PNimType): string {.compilerproc.} =
+proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} =
   if e <% typ.node.len: # BUGFIX
     result = $typ.node.sons[e].name
   else:
@@ -97,7 +97,7 @@ proc reprSetAux(result: var string, p: pointer, typ: PNimType) =
         inc(elemCounter)
   add result, "}"
 
-proc reprSet(p: pointer, typ: PNimType): string {.compilerproc.} =
+proc reprSet(p: pointer, typ: PNimType): string {.compilerRtl.} =
   result = ""
   reprSetAux(result, p, typ)
 
@@ -108,122 +108,123 @@ type
     recdepth: int       # do not recurse endless
     indent: int         # indentation
 
-proc initReprClosure(cl: var TReprClosure) =
-  Init(cl.marked)
-  cl.recdepth = -1      # default is to display everything!
-  cl.indent = 0
-
-proc deinitReprClosure(cl: var TReprClosure) =
-  Deinit(cl.marked)
-
-proc reprBreak(result: var string, cl: TReprClosure) =
-  add result, "\n"
-  for i in 0..cl.indent-1: add result, ' '
-
-proc reprAux(result: var string, p: pointer, typ: PNimType,
-             cl: var TReprClosure)
-
-proc reprArray(result: var string, p: pointer, typ: PNimType,
-               cl: var TReprClosure) =
-  add result, "["
-  var bs = typ.base.size
-  for i in 0..typ.size div bs - 1:
-    if i > 0: add result, ", "
-    reprAux(result, cast[pointer](cast[TAddress](p) + i*bs), typ.base, cl)
-  add result, "]"
-
-proc reprSequence(result: var string, p: pointer, typ: PNimType,
+when not defined(useNimRtl):
+  proc initReprClosure(cl: var TReprClosure) =
+    Init(cl.marked)
+    cl.recdepth = -1      # default is to display everything!
+    cl.indent = 0
+
+  proc deinitReprClosure(cl: var TReprClosure) =
+    Deinit(cl.marked)
+
+  proc reprBreak(result: var string, cl: TReprClosure) =
+    add result, "\n"
+    for i in 0..cl.indent-1: add result, ' '
+
+  proc reprAux(result: var string, p: pointer, typ: PNimType,
+               cl: var TReprClosure)
+
+  proc reprArray(result: var string, p: pointer, typ: PNimType,
+                 cl: var TReprClosure) =
+    add result, "["
+    var bs = typ.base.size
+    for i in 0..typ.size div bs - 1:
+      if i > 0: add result, ", "
+      reprAux(result, cast[pointer](cast[TAddress](p) + i*bs), typ.base, cl)
+    add result, "]"
+
+  proc reprSequence(result: var string, p: pointer, typ: PNimType,
+                    cl: var TReprClosure) =
+    if p == nil:
+      add result, "nil"
+      return
+    result.add(reprPointer(p) & "[")
+    var bs = typ.base.size
+    for i in 0..cast[PGenericSeq](p).len-1:
+      if i > 0: add result, ", "
+      reprAux(result, cast[pointer](cast[TAddress](p) + GenericSeqSize + i*bs),
+              typ.Base, cl)
+    add result, "]"
+
+  proc reprRecordAux(result: var string, p: pointer, n: ptr TNimNode,
+                     cl: var TReprClosure) =
+    case n.kind
+    of nkNone: assert(false)
+    of nkSlot:
+      add result, $n.name
+      add result, " = "
+      reprAux(result, cast[pointer](cast[TAddress](p) + n.offset), n.typ, cl)
+    of nkList:
+      for i in 0..n.len-1:
+        if i > 0: add result, ",\n"
+        reprRecordAux(result, p, n.sons[i], cl)
+    of nkCase:
+      var m = selectBranch(p, n)
+      reprAux(result, cast[pointer](cast[TAddress](p) + n.offset), n.typ, cl)
+      if m != nil: reprRecordAux(result, p, m, cl)
+
+  proc reprRecord(result: var string, p: pointer, typ: PNimType,
                   cl: var TReprClosure) =
-  if p == nil:
-    add result, "nil"
-    return
-  result.add(reprPointer(p) & "[")
-  var bs = typ.base.size
-  for i in 0..cast[PGenericSeq](p).len-1:
-    if i > 0: add result, ", "
-    reprAux(result, cast[pointer](cast[TAddress](p) + GenericSeqSize + i*bs),
-            typ.Base, cl)
-  add result, "]"
-
-proc reprRecordAux(result: var string, p: pointer, n: ptr TNimNode,
-                   cl: var TReprClosure) =
-  case n.kind
-  of nkNone: assert(false)
-  of nkSlot:
-    add result, $n.name
-    add result, " = "
-    reprAux(result, cast[pointer](cast[TAddress](p) + n.offset), n.typ, cl)
-  of nkList:
-    for i in 0..n.len-1:
-      if i > 0: add result, ",\n"
-      reprRecordAux(result, p, n.sons[i], cl)
-  of nkCase:
-    var m = selectBranch(p, n)
-    reprAux(result, cast[pointer](cast[TAddress](p) + n.offset), n.typ, cl)
-    if m != nil: reprRecordAux(result, p, m, cl)
-
-proc reprRecord(result: var string, p: pointer, typ: PNimType,
-                cl: var TReprClosure) =
-  add result, "["
-  reprRecordAux(result, p, typ.node, cl)
-  add result, "]"
+    add result, "["
+    reprRecordAux(result, p, typ.node, cl)
+    add result, "]"
 
-proc reprRef(result: var string, p: pointer, typ: PNimType,
-             cl: var TReprClosure) =
-  # we know that p is not nil here:
-  when defined(boehmGC) or defined(nogc):
-    var cell = cast[PCell](p)
-  else:
-    var cell = usrToCell(p)
-  add result, "ref " & reprPointer(p)
-  if cell notin cl.marked:
-    # only the address is shown:
-    incl(cl.marked, cell)
-    add result, " --> "
-    reprAux(result, p, typ.base, cl)
-
-proc reprAux(result: var string, p: pointer, typ: PNimType,
-             cl: var TReprClosure) =
-  if cl.recdepth == 0:
-    add result, "..."
-    return
-  dec(cl.recdepth)
-  case typ.kind
-  of tySet: reprSetAux(result, p, typ)
-  of tyArray: reprArray(result, p, typ, cl)
-  of tyTuple, tyPureObject: reprRecord(result, p, typ, cl)
-  of tyObject: 
-    var t = cast[ptr PNimType](p)^
-    reprRecord(result, p, t, cl)
-  of tyRef, tyPtr:
-    assert(p != nil)
-    if cast[ppointer](p)^ == nil: add result, "nil"
-    else: reprRef(result, cast[ppointer](p)^, typ, cl)
-  of tySequence:
-    reprSequence(result, cast[ppointer](p)^, typ, cl)
-  of tyInt: add result, $(cast[ptr int](p)^)
-  of tyInt8: add result, $int(cast[ptr Int8](p)^)
-  of tyInt16: add result, $int(cast[ptr Int16](p)^)
-  of tyInt32: add result, $int(cast[ptr Int32](p)^)
-  of tyInt64: add result, $(cast[ptr Int64](p)^)
-  of tyFloat: add result, $(cast[ptr float](p)^)
-  of tyFloat32: add result, $(cast[ptr float32](p)^)
-  of tyFloat64: add result, $(cast[ptr float64](p)^)
-  of tyEnum: add result, reprEnum(cast[ptr int](p)^, typ)
-  of tyBool: add result, reprBool(cast[ptr bool](p)^)
-  of tyChar: add result, reprChar(cast[ptr char](p)^)
-  of tyString: reprStrAux(result, cast[ptr string](p)^)
-  of tyCString: reprStrAux(result, $(cast[ptr cstring](p)^))
-  of tyRange: reprAux(result, p, typ.base, cl)
-  of tyProc, tyPointer:
-    if cast[ppointer](p)^ == nil: add result, "nil"
-    else: add result, reprPointer(cast[ppointer](p)^)
-  else:
-    add result, "(invalid data!)"
-  inc(cl.recdepth)
+  proc reprRef(result: var string, p: pointer, typ: PNimType,
+               cl: var TReprClosure) =
+    # we know that p is not nil here:
+    when defined(boehmGC) or defined(nogc):
+      var cell = cast[PCell](p)
+    else:
+      var cell = usrToCell(p)
+    add result, "ref " & reprPointer(p)
+    if cell notin cl.marked:
+      # only the address is shown:
+      incl(cl.marked, cell)
+      add result, " --> "
+      reprAux(result, p, typ.base, cl)
+
+  proc reprAux(result: var string, p: pointer, typ: PNimType,
+               cl: var TReprClosure) =
+    if cl.recdepth == 0:
+      add result, "..."
+      return
+    dec(cl.recdepth)
+    case typ.kind
+    of tySet: reprSetAux(result, p, typ)
+    of tyArray: reprArray(result, p, typ, cl)
+    of tyTuple, tyPureObject: reprRecord(result, p, typ, cl)
+    of tyObject: 
+      var t = cast[ptr PNimType](p)^
+      reprRecord(result, p, t, cl)
+    of tyRef, tyPtr:
+      assert(p != nil)
+      if cast[ppointer](p)^ == nil: add result, "nil"
+      else: reprRef(result, cast[ppointer](p)^, typ, cl)
+    of tySequence:
+      reprSequence(result, cast[ppointer](p)^, typ, cl)
+    of tyInt: add result, $(cast[ptr int](p)^)
+    of tyInt8: add result, $int(cast[ptr Int8](p)^)
+    of tyInt16: add result, $int(cast[ptr Int16](p)^)
+    of tyInt32: add result, $int(cast[ptr Int32](p)^)
+    of tyInt64: add result, $(cast[ptr Int64](p)^)
+    of tyFloat: add result, $(cast[ptr float](p)^)
+    of tyFloat32: add result, $(cast[ptr float32](p)^)
+    of tyFloat64: add result, $(cast[ptr float64](p)^)
+    of tyEnum: add result, reprEnum(cast[ptr int](p)^, typ)
+    of tyBool: add result, reprBool(cast[ptr bool](p)^)
+    of tyChar: add result, reprChar(cast[ptr char](p)^)
+    of tyString: reprStrAux(result, cast[ptr string](p)^)
+    of tyCString: reprStrAux(result, $(cast[ptr cstring](p)^))
+    of tyRange: reprAux(result, p, typ.base, cl)
+    of tyProc, tyPointer:
+      if cast[ppointer](p)^ == nil: add result, "nil"
+      else: add result, reprPointer(cast[ppointer](p)^)
+    else:
+      add result, "(invalid data!)"
+    inc(cl.recdepth)
 
 proc reprOpenArray(p: pointer, length: int, elemtyp: PNimType): string {.
-                   compilerproc.} =
+                   compilerRtl.} =
   var
     cl: TReprClosure
   initReprClosure(cl)
@@ -235,15 +236,17 @@ proc reprOpenArray(p: pointer, length: int, elemtyp: PNimType): string {.
   add result, "]"
   deinitReprClosure(cl)
 
-proc reprAny(p: pointer, typ: PNimType): string =
-  var
-    cl: TReprClosure
-  initReprClosure(cl)
-  result = ""
-  if typ.kind in {tyObject, tyPureObject, tyTuple, tyArray, tySet}:
-    reprAux(result, p, typ, cl)
-  else:
-    var p = p
-    reprAux(result, addr(p), typ, cl)
-  add result, "\n"
-  deinitReprClosure(cl)
+when not defined(useNimRtl):
+  proc reprAny(p: pointer, typ: PNimType): string =
+    var
+      cl: TReprClosure
+    initReprClosure(cl)
+    result = ""
+    if typ.kind in {tyObject, tyPureObject, tyTuple, tyArray, tySet}:
+      reprAux(result, p, typ, cl)
+    else:
+      var p = p
+      reprAux(result, addr(p), typ, cl)
+    add result, "\n"
+    deinitReprClosure(cl)
+
diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim
index 1dcc2ab3a..e342296c7 100755
--- a/lib/system/sysio.nim
+++ b/lib/system/sysio.nim
@@ -135,14 +135,6 @@ proc open(f: var TFile, filehandle: TFileHandle, mode: TFileMode): bool =
   f = fdopen(filehandle, FormatOpen[mode])
   result = f != nil
 
-proc OpenFile(f: var TFile, filename: string,
-              mode: TFileMode = fmRead,
-              bufSize: int = -1): Bool =
-  result = open(f, filename, mode, bufSize)
-  
-proc openFile(f: var TFile, filehandle: TFileHandle, mode: TFileMode): bool =
-  result = open(f, filehandle, mode)
-
 # C routine that is used here:
 proc fread(buf: Pointer, size, n: int, f: TFile): int {.
   importc: "fread", noDecl.}
diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim
index 20a49093b..41efdf431 100755
--- a/lib/system/sysstr.nim
+++ b/lib/system/sysstr.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nimrod's Runtime Library
-#        (c) Copyright 2009 Andreas Rumpf
+#        (c) Copyright 2010 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -88,7 +88,8 @@ proc copyStrLast(s: NimString, start, last: int): NimString {.exportc.} =
 proc copyStr(s: NimString, start: int): NimString {.exportc.} =
   return copyStrLast(s, start, s.len-1)
 
-proc addChar(s: NimString, c: char): NimString {.compilerProc.} =
+proc addChar(s: NimString, c: char): NimString =
+  # is compilerproc!
   result = s
   if result.len >= result.space:
     result.space = resize(result.space)
@@ -196,7 +197,7 @@ proc incrSeq(seq: PGenericSeq, elemSize: int): PGenericSeq {.compilerProc.} =
     inc(result.len)
 
 proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
-    compilerProc.} =
+    compilerRtl.} =
   when false:
     # broken version:
     result = seq
@@ -223,7 +224,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
     result.len = newLen
 
 # --------------- other string routines ----------------------------------
-proc nimIntToStr(x: int): string {.compilerproc.} =
+proc nimIntToStr(x: int): string {.compilerRtl.} =
   result = newString(sizeof(x)*4)
   var i = 0
   var y = x
@@ -246,7 +247,7 @@ proc nimFloatToStr(x: float): string {.compilerproc.} =
   c_sprintf(buf, "%#g", x)
   return $buf
 
-proc nimInt64ToStr(x: int64): string {.compilerproc.} =
+proc nimInt64ToStr(x: int64): string {.compilerRtl.} =
   # we don't rely on C's runtime here as some C compiler's
   # int64 support is weak
   result = newString(sizeof(x)*4)