summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xlib/nimbase.h2
-rwxr-xr-xlib/nimrtl.cfg5
-rwxr-xr-xlib/system.nim104
-rwxr-xr-x[-rw-r--r--]lib/system/cgprocs.nim2
-rwxr-xr-xlib/system/gc.nim3
-rwxr-xr-xrod/cgen.nim71
-rwxr-xr-xtests/gc/gctest.nim22
-rwxr-xr-xtodo.txt1
-rwxr-xr-xweb/news.txt2
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