diff options
-rwxr-xr-x | lib/nimbase.h | 2 | ||||
-rwxr-xr-x | lib/nimrtl.cfg | 5 | ||||
-rwxr-xr-x | lib/system.nim | 104 | ||||
-rwxr-xr-x[-rw-r--r--] | lib/system/cgprocs.nim | 2 | ||||
-rwxr-xr-x | lib/system/gc.nim | 3 | ||||
-rwxr-xr-x | rod/cgen.nim | 71 | ||||
-rwxr-xr-x | tests/gc/gctest.nim | 22 | ||||
-rwxr-xr-x | todo.txt | 1 | ||||
-rwxr-xr-x | web/news.txt | 2 |
9 files changed, 101 insertions, 111 deletions
diff --git a/lib/nimbase.h b/lib/nimbase.h index 8e80b8261..5bc644dc9 100755 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -431,4 +431,6 @@ struct NimException { }; #endif +#define NIM_POSIX_INIT __attribute__((constructor)) + #endif diff --git a/lib/nimrtl.cfg b/lib/nimrtl.cfg new file mode 100755 index 000000000..b60de183a --- /dev/null +++ b/lib/nimrtl.cfg @@ -0,0 +1,5 @@ +# The RTL.dll needs to be compiled with these options! + +--app:lib +--define:createNimRtl + diff --git a/lib/system.nim b/lib/system.nim index abad660f1..1addece93 100755 --- a/lib/system.nim +++ b/lib/system.nim @@ -666,6 +666,56 @@ 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.} + +type + TEndian* = enum ## is a type describing the endianness of a processor. + littleEndian, bigEndian + +const + isMainModule* {.magic: "IsMainModule".}: bool = false + ## is true only when accessed in the main module. This works thanks to + ## compiler magic. It is useful to embed testing code in a module. + + CompileDate* {.magic: "CompileDate"}: string = "0000-00-00" + ## is the date of compilation as a string of the form + ## ``YYYY-MM-DD``. This works thanks to compiler magic. + + CompileTime* {.magic: "CompileTime"}: string = "00:00:00" + ## is the time of compilation as a string of the form + ## ``HH:MM:SS``. This works thanks to compiler magic. + + NimrodVersion* {.magic: "NimrodVersion"}: string = "0.0.0" + ## is the version of Nimrod as a string. + ## This works thanks to compiler magic. + + NimrodMajor* {.magic: "NimrodMajor"}: int = 0 + ## is the major number of Nimrod's version. + ## This works thanks to compiler magic. + + NimrodMinor* {.magic: "NimrodMinor"}: int = 0 + ## is the minor number of Nimrod's version. + ## This works thanks to compiler magic. + + NimrodPatch* {.magic: "NimrodPatch"}: int = 0 + ## is the patch number of Nimrod's version. + ## This works thanks to compiler magic. + + cpuEndian* {.magic: "CpuEndian"}: TEndian = littleEndian + ## is the endianness of the target CPU. This is a valuable piece of + ## information for low-level code only. This works thanks to compiler magic. + + hostOS* {.magic: "HostOS"}: string = "" + ## a string that describes the host operating system. Possible values: + ## "windows", "macosx", "linux", "netbsd", "freebsd", "openbsd", "solaris", + ## "aix". + + hostCPU* {.magic: "HostCPU"}: string = "" + ## a string that describes the host CPU. Possible values: + ## "i386", "alpha", "powerpc", "sparc", "amd64", "mips", "arm". + + appType* {.magic: "AppType"}: string = "" + ## a string that describes the application type. Possible values: + ## "console", "gui", "lib". include "system/inclrtl" include "system/cgprocs" @@ -771,59 +821,10 @@ type # these work for most platforms: ## high value is large enough to disable bounds checking in practice. ## Use `cstringArrayToSeq` to convert it into a ``seq[string]``. - TEndian* = enum ## is a type describing the endianness of a processor. - littleEndian, bigEndian - PFloat32* = ptr Float32 ## an alias for ``ptr float32`` PFloat64* = ptr Float64 ## an alias for ``ptr float64`` PInt64* = ptr Int64 ## an alias for ``ptr int64`` PInt32* = ptr Int32 ## an alias for ``ptr int32`` - -const - isMainModule* {.magic: "IsMainModule".}: bool = false - ## is true only when accessed in the main module. This works thanks to - ## compiler magic. It is useful to embed testing code in a module. - - CompileDate* {.magic: "CompileDate"}: string = "0000-00-00" - ## is the date of compilation as a string of the form - ## ``YYYY-MM-DD``. This works thanks to compiler magic. - - CompileTime* {.magic: "CompileTime"}: string = "00:00:00" - ## is the time of compilation as a string of the form - ## ``HH:MM:SS``. This works thanks to compiler magic. - - NimrodVersion* {.magic: "NimrodVersion"}: string = "0.0.0" - ## is the version of Nimrod as a string. - ## This works thanks to compiler magic. - - NimrodMajor* {.magic: "NimrodMajor"}: int = 0 - ## is the major number of Nimrod's version. - ## This works thanks to compiler magic. - - NimrodMinor* {.magic: "NimrodMinor"}: int = 0 - ## is the minor number of Nimrod's version. - ## This works thanks to compiler magic. - - NimrodPatch* {.magic: "NimrodPatch"}: int = 0 - ## is the patch number of Nimrod's version. - ## This works thanks to compiler magic. - - cpuEndian* {.magic: "CpuEndian"}: TEndian = littleEndian - ## is the endianness of the target CPU. This is a valuable piece of - ## information for low-level code only. This works thanks to compiler magic. - - hostOS* {.magic: "HostOS"}: string = "" - ## a string that describes the host operating system. Possible values: - ## "windows", "macosx", "linux", "netbsd", "freebsd", "openbsd", "solaris", - ## "aix". - - hostCPU* {.magic: "HostCPU"}: string = "" - ## a string that describes the host CPU. Possible values: - ## "i386", "alpha", "powerpc", "sparc", "amd64", "mips", "arm". - - appType* {.magic: "AppType"}: string = "" - ## a string that describes the application type. Possible values: - ## "console", "gui", "lib". proc toFloat*(i: int): float {. magic: "ToFloat", noSideEffect, importc: "toFloat".} @@ -1305,7 +1306,10 @@ when not defined(EcmaScript) and not defined(NimrodVM): proc initGC() proc initStackBottom() {.inline.} = - var locals: array[0..7, int] + # WARNING: This is very fragile! An array size of 8 does not work on my + # Linux 64bit system. Very strange, but we are at the will of GCC's + # optimizer... + var locals {.volatile.}: pointer setStackBottom(addr(locals)) var diff --git a/lib/system/cgprocs.nim b/lib/system/cgprocs.nim index 99f802910..cabdcafc4 100644..100755 --- a/lib/system/cgprocs.nim +++ b/lib/system/cgprocs.nim @@ -21,6 +21,6 @@ proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr {.compilerproc.} proc nimLoadLibraryError(path: string) {.compilerproc, noinline.} -proc setStackBottom(theStackBottom: pointer) {.compilerRtl.} +proc setStackBottom(theStackBottom: pointer) {.compilerRtl, noinline.} diff --git a/lib/system/gc.nim b/lib/system/gc.nim index d1a3e8273..2ad22d8b6 100755 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -491,10 +491,11 @@ else: const stackIncreases = false proc setStackBottom(theStackBottom: pointer) = + #c_fprintf(c_stdout, "stack bottom: %p;\n", theStackBottom) # the first init must be the one that defines the stack bottom: if stackBottom == nil: stackBottom = theStackBottom else: - var a = cast[TAddress](theStackBottom) + var a = cast[TAddress](theStackBottom) # and not PageMask - PageSize*2 var b = cast[TAddress](stackBottom) when stackIncreases: stackBottom = cast[pointer](min(a, b)) diff --git a/rod/cgen.nim b/rod/cgen.nim index b5cf04b58..562b660eb 100755 --- a/rod/cgen.nim +++ b/rod/cgen.nim @@ -700,74 +700,51 @@ proc getFileHeader(cfilenoext: string): PRope = proc genMainProc(m: BModule) = const - CommonMainBody = " #setStackBottom(dummy);$n" & " nim__datInit();$n" & - " systemInit();$n" & "$1" & "$2" - CommonMainBodyLLVM = " %MOC$3 = bitcast [8 x %NI]* %dummy to i8*$n" & - " call void @#setStackBottom(i8* %MOC$3)$n" & - " call void @nim__datInit()$n" & " call void systemInit()$n" & "$1" & + CommonMainBody = + " nim__datInit();$n" & + " systemInit();$n" & + "$1" & "$2" - PosixNimMain = "int cmdCount;$n" & "char** cmdLine;$n" & "char** gEnv;$n" & - "N_CDECL(void, NimMain)(void) {$n" & " int dummy[8];$n" & + PosixNimMain = + "int cmdCount;$n" & + "char** cmdLine;$n" & + "char** gEnv;$n" & + "N_CDECL(void, NimMain)(void) {$n" & CommonMainBody & "}$n" PosixCMain = "int main(int argc, char** args, char** env) {$n" & " cmdLine = args;$n" & " cmdCount = argc;$n" & " gEnv = env;$n" & " NimMain();$n" & " return 0;$n" & "}$n" - PosixNimMainLLVM = "@cmdCount = linkonce i32$n" & - "@cmdLine = linkonce i8**$n" & "@gEnv = linkonce i8**$n" & - "define void @NimMain(void) {$n" & " %dummy = alloca [8 x %NI]$n" & - CommonMainBodyLLVM & "}$n" - PosixCMainLLVM = "define i32 @main(i32 %argc, i8** %args, i8** %env) {$n" & - " store i8** %args, i8*** @cmdLine$n" & - " store i32 %argc, i32* @cmdCount$n" & - " store i8** %env, i8*** @gEnv$n" & " call void @NimMain()$n" & - " ret i32 0$n" & "}$n" - WinNimMain = "N_CDECL(void, NimMain)(void) {$n" & " int dummy[8];$n" & + WinNimMain = "N_CDECL(void, NimMain)(void) {$n" & CommonMainBody & "}$n" WinCMain = "N_STDCALL(int, WinMain)(HINSTANCE hCurInstance, $n" & " HINSTANCE hPrevInstance, $n" & " LPSTR lpCmdLine, int nCmdShow) {$n" & " NimMain();$n" & " return 0;$n" & "}$n" - WinNimMainLLVM = "define void @NimMain(void) {$n" & - " %dummy = alloca [8 x %NI]$n" & CommonMainBodyLLVM & "}$n" - WinCMainLLVM = "define stdcall i32 @WinMain(i32 %hCurInstance, $n" & - " i32 %hPrevInstance, $n" & - " i8* %lpCmdLine, i32 %nCmdShow) {$n" & - " call void @NimMain()$n" & " ret i32 0$n" & "}$n" WinNimDllMain = "N_LIB_EXPORT N_CDECL(void, NimMain)(void) {$n" & - " int dummy[8];$n" & CommonMainBody & "}$n" + CommonMainBody & "}$n" WinCDllMain = "BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, $n" & " LPVOID lpvReserved) {$n" & " NimMain();$n" & " return 1;$n" & "}$n" - WinNimDllMainLLVM = WinNimMainLLVM - WinCDllMainLLVM = - "define stdcall i32 @DllMain(i32 %hinstDLL, i32 %fwdreason, $n" & - " i8* %lpvReserved) {$n" & - " call void @NimMain()$n" & " ret i32 1$n" & "}$n" + PosixNimDllMain = WinNimDllMain + PosixCDllMain = + "void NIM_POSIX_INIT NimMainInit(void) {$n" & + " NimMain();$n}$n" var nimMain, otherMain: TFormatStr if (platform.targetOS == osWindows) and (gGlobalOptions * {optGenGuiApp, optGenDynLib} != {}): if optGenGuiApp in gGlobalOptions: - if gCmd == cmdCompileToLLVM: - nimMain = WinNimMainLLVM - otherMain = WinCMainLLVM - else: - nimMain = WinNimMain - otherMain = WinCMain + nimMain = WinNimMain + otherMain = WinCMain else: - if gCmd == cmdCompileToLLVM: - nimMain = WinNimDllMainLLVM - otherMain = WinCDllMainLLVM - else: - nimMain = WinNimDllMain - otherMain = WinCDllMain + nimMain = WinNimDllMain + otherMain = WinCDllMain discard lists.IncludeStr(m.headerFiles, "<windows.h>") + elif optGenDynLib in gGlobalOptions: + nimMain = posixNimDllMain + otherMain = posixCDllMain else: - if gCmd == cmdCompileToLLVM: - nimMain = PosixNimMainLLVM - otherMain = PosixCMainLLVM - else: - nimMain = PosixNimMain - otherMain = PosixCMain + nimMain = PosixNimMain + otherMain = PosixCMain if gBreakpoints != nil: discard cgsym(m, "dbgRegisterBreakpoint") inc(m.labels) appcg(m, m.s[cfsProcs], nimMain, [ diff --git a/tests/gc/gctest.nim b/tests/gc/gctest.nim index f58dc3217..a2d97c944 100755 --- a/tests/gc/gctest.nim +++ b/tests/gc/gctest.nim @@ -28,15 +28,15 @@ type of nkList: sons: seq[PCaseNode] else: unused: seq[string] - TIdObj* = object of TObject - id*: int # unique id; use this for comparisons and not the pointers - - PIdObj* = ref TIdObj - PIdent* = ref TIdent - TIdent*{.acyclic.} = object of TIdObj - s*: string - next*: PIdent # for hash-table chaining - h*: int # hash value of s + TIdObj* = object of TObject + id*: int # unique id; use this for comparisons and not the pointers + + PIdObj* = ref TIdObj + PIdent* = ref TIdent + TIdent*{.acyclic.} = object of TIdObj + s*: string + next*: PIdent # for hash-table chaining + h*: int # hash value of s var flip: int @@ -145,8 +145,8 @@ proc buildBTree(father: var TBNode) = setSons(father) proc getIdent(identifier: cstring, length: int, h: int): PIdent = - new(result) - result.h = h + new(result) + result.h = h result.s = newString(length) proc main() = diff --git a/todo.txt b/todo.txt index 470661be1..773b68a97 100755 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,6 @@ For version 0.8.10 ================== -- support for generation of dynamic libraries - fix exception handling - fix implicit generic routines - fix the streams implementation so that they use methods diff --git a/web/news.txt b/web/news.txt index f70bb5bdd..b625ba209 100755 --- a/web/news.txt +++ b/web/news.txt @@ -58,6 +58,8 @@ Additions - The ``importc`` and ``exportc`` pragmas support format strings: ``proc p{.exportc: "nim_$1".}`` exports ``p`` as ``nim_p``. This is useful for user defined pragmas. +- The standard library can be built as a DLL. Generating DLLs has been + improved. 2010-03-14 Version 0.8.8 released |