diff options
author | Andreas Rumpf <andreas@andreas-desktop> | 2010-07-29 21:30:04 +0200 |
---|---|---|
committer | Andreas Rumpf <andreas@andreas-desktop> | 2010-07-29 21:30:04 +0200 |
commit | ff02ce2d50d8a4b445f9fba6076527c3db62425c (patch) | |
tree | 065d5ecddb38f871e516b49c333f565b6cba9b31 /lib | |
parent | 804e2ac89d378b87e0ec8c723f607aa4271c57bb (diff) | |
download | Nim-ff02ce2d50d8a4b445f9fba6076527c3db62425c.tar.gz |
handling of compiler procs improved for DLL generation
Diffstat (limited to 'lib')
-rwxr-xr-x | lib/nimrtl.nim | 39 | ||||
-rwxr-xr-x | lib/pure/strutils.nim | 41 | ||||
-rwxr-xr-x | lib/system.nim | 54 | ||||
-rw-r--r-- | lib/system/cgprocs.nim | 14 | ||||
-rwxr-xr-x | lib/system/dyncalls.nim | 7 | ||||
-rwxr-xr-x | lib/system/gc.nim | 22 | ||||
-rwxr-xr-x | lib/system/inclrtl.nim | 45 | ||||
-rwxr-xr-x | lib/system/mmdisp.nim | 75 | ||||
-rwxr-xr-x | lib/system/repr.nim | 263 | ||||
-rwxr-xr-x | lib/system/sysio.nim | 8 | ||||
-rwxr-xr-x | lib/system/sysstr.nim | 11 |
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) |