summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2012-07-19 19:04:18 +0300
committerZahary Karadjov <zahary@gmail.com>2012-07-19 19:43:58 +0300
commit4841b6390c136a0e6a4f641d0d45f65a422809f6 (patch)
tree7a3d574d3f2f04d7dece4e7126e9ab5073809bd8 /compiler
parent035b715dfdcb65396b2e5cbc443b051d5f4ace53 (diff)
downloadNim-4841b6390c136a0e6a4f641d0d45f65a422809f6.tar.gz
removed nimdat in favor of per-module dat init procs
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/ast.nim2
-rwxr-xr-xcompiler/ccgexprs.nim7
-rwxr-xr-xcompiler/ccgtypes.nim38
-rwxr-xr-xcompiler/cgen.nim88
-rw-r--r--compiler/cgendata.nim10
-rwxr-xr-xcompiler/main.nim3
6 files changed, 73 insertions, 75 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 7bd893a07..c28cb6e0b 100755
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -567,6 +567,8 @@ type
                               # for a conditional:
                               # 1 iff the symbol is defined, else 0
                               # (or not in symbol table)
+                              # for modules, a unique index correspinding
+                              # to the order of compilation 
     offset*: int              # offset of record field
     loc*: TLoc
     annex*: PLib              # additional fields (seldom used, so we use a
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 7b24e86db..78e9e5c31 100755
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -1004,15 +1004,10 @@ proc genNewFinalize(p: BProc, e: PNode) =
     oldModule: BModule
   refType = skipTypes(e.sons[1].typ, abstractVarRange)
   InitLocExpr(p, e.sons[1], a)
-  # This is a little hack:
-  # XXX this is also a bug, if the finalizer expression produces side-effects
-  oldModule = p.module
-  p.module = gNimDat
   InitLocExpr(p, e.sons[2], f)
-  p.module = oldModule
   initLoc(b, locExpr, a.t, OnHeap)
   ti = genTypeInfo(p.module, refType)
-  appf(gNimDat.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
+  appf(p.module.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
   b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [
       getTypeDesc(p.module, refType),
       ti, getTypeDesc(p.module, skipTypes(reftype.sons[0], abstractRange))])
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index eb75895f8..e3efe2d13 100755
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -886,41 +886,43 @@ include ccgtrav
 
 proc genTypeInfo(m: BModule, typ: PType): PRope = 
   var t = getUniqueType(typ)
-  # gNimDat contains all the type information nowadays:
-  var dataGenerated = ContainsOrIncl(gNimDat.typeInfoMarker, t.id)
   result = ropef("NTI$1", [toRope(t.id)])
-  if not ContainsOrIncl(m.typeInfoMarker, t.id): 
-    # declare type information structures:
+  let owner = typ.skipTypes(abstractPtrs).owner.getModule
+  if owner != m.module:
+    # make sure the type info is created in the owner module
+    discard genTypeInfo(owner.bmod, typ)
+    # refenrece the type info as extern here
     discard cgsym(m, "TNimType")
     discard cgsym(m, "TNimNode")
     appf(m.s[cfsVars], "extern TNimType* $1; /* $2 */$n", 
          [result, toRope(typeToString(t))])
-  if dataGenerated: return 
+    return
+  if ContainsOrIncl(m.typeInfoMarker, t.id): return
   case t.kind
   of tyEmpty: result = toRope"0"
   of tyPointer, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64, tyVar:
-    genTypeInfoAuxBase(gNimDat, t, result, toRope"0")
+    genTypeInfoAuxBase(m, t, result, toRope"0")
   of tyProc:
     if t.callConv != ccClosure:
-      genTypeInfoAuxBase(gNimDat, t, result, toRope"0")
+      genTypeInfoAuxBase(m, t, result, toRope"0")
     else:
-      genTupleInfo(gNimDat, fakeClosureType(t.owner), result)
+      genTupleInfo(m, fakeClosureType(t.owner), result)
   of tySequence, tyRef:
-    genTypeInfoAux(gNimDat, t, result)
+    genTypeInfoAux(m, t, result)
     if optRefcGC in gGlobalOptions:
-      let markerProc = genTraverseProc(gNimDat, t, tiNew)
-      appf(gNimDat.s[cfsTypeInit3], "$1->marker = $2;$n", [result, markerProc])
-  of tyPtr, tyRange: genTypeInfoAux(gNimDat, t, result)
-  of tyArrayConstr, tyArray: genArrayInfo(gNimDat, t, result)
-  of tySet: genSetInfo(gNimDat, t, result)
-  of tyEnum: genEnumInfo(gNimDat, t, result)
-  of tyObject: genObjectInfo(gNimDat, t, result)
+      let markerProc = genTraverseProc(m, t, tiNew)
+      appf(m.s[cfsTypeInit3], "$1->marker = $2;$n", [result, markerProc])
+  of tyPtr, tyRange: genTypeInfoAux(m, t, result)
+  of tyArrayConstr, tyArray: genArrayInfo(m, t, result)
+  of tySet: genSetInfo(m, t, result)
+  of tyEnum: genEnumInfo(m, t, result)
+  of tyObject: genObjectInfo(m, t, result)
   of tyTuple: 
-    # if t.n != nil: genObjectInfo(gNimDat, t, result)
+    # if t.n != nil: genObjectInfo(m, t, result)
     # else:
     # BUGFIX: use consistently RTTI without proper field names; otherwise
     # results are not deterministic!
-    genTupleInfo(gNimDat, t, result)
+    genTupleInfo(m, t, result)
   else: InternalError("genTypeInfo(" & $t.kind & ')')
 
 proc genTypeSection(m: BModule, n: PNode) = 
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index c7bfced73..c23084f5c 100755
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -819,11 +819,12 @@ proc getFileHeader(cfilenoext: string): PRope =
 proc genMainProc(m: BModule) = 
   const 
     CommonMainBody =
-        "\tnim__datInit();$n" &
-        "\tsystemInit();$n" &
+        "\tsystemDatInit();$n" &
         "$1" &
         "$2" &
-        "$3"
+        "\tsystemInit();$n" &
+        "$3" &
+        "$4"
     PosixNimMain = 
         "int cmdCount;$n" & 
         "char** cmdLine;$n" & 
@@ -877,7 +878,7 @@ proc genMainProc(m: BModule) =
                               platform.targetOS == osStandalone: "".toRope
                             else: ropecg(m, "\t#initStackBottom();$n")
   inc(m.labels)
-  appcg(m, m.s[cfsProcs], nimMain, [initStackBottomCall,
+  appcg(m, m.s[cfsProcs], nimMain, [mainDatInit, initStackBottomCall,
         gBreakpoints, mainModInit, toRope(m.labels)])
   if optNoMain notin gGlobalOptions:
     appcg(m, m.s[cfsProcs], otherMain, [])
@@ -885,12 +886,20 @@ proc genMainProc(m: BModule) =
 proc getInitName(m: PSym): PRope = 
   result = ropeff("$1Init", "@$1Init", [toRope(m.name.s)])
 
+proc getDatInitName(m: PSym): PRope =
+  result = ropeff("$1DatInit", "@$1DatInit", [toRope(m.name.s)])
+
 proc registerModuleToMain(m: PSym) = 
-  var initname = getInitName(m)
-  appff(mainModProcs, "N_NOINLINE(void, $1)(void);$n", 
-        "declare void $1() noinline$n", [initname])
-  if not (sfSystemModule in m.flags): 
-    appff(mainModInit, "$1();$n", "call void ()* $1$n", [initname])
+  var
+    init = m.getInitName
+    datInit = m.getDatInitName
+  appff(mainModProcs, "N_NOINLINE(void, $1)(void);$N",
+                      "declare void $1() noinline$N", [init])
+  appff(mainModProcs, "N_NOINLINE(void, $1)(void);$N",
+                      "declare void $1() noinline$N", [datInit])
+  if not (sfSystemModule in m.flags):
+    appff(mainModInit, "\t$1();$n", "call void ()* $1$n", [init])
+    appff(mainDatInit, "\t$1();$n", "call void ()* $1$n", [datInit])
   
 proc genInitCode(m: BModule) = 
   if optProfiler in m.initProc.options: 
@@ -914,25 +923,17 @@ proc genInitCode(m: BModule) =
     getFrameDecl(m.initProc)
   
   app(prc, initGCFrame(m.initProc))
-  
+ 
   app(prc, genSectionStart(cpsLocals))
   app(prc, m.initProc.s(cpsLocals))
   app(prc, m.preInitProc.s(cpsLocals))
   app(prc, genSectionEnd(cpsLocals))
 
-  app(prc, genSectionStart(cfsTypeInit1))
-  app(prc, m.s[cfsTypeInit1])
   if optStackTrace in m.initProc.options and not m.PreventStackTrace: 
     var procname = CStringLit(m.initProc, prc, m.module.name.s)
     var filename = CStringLit(m.initProc, prc, toFilename(m.module.info))
     app(prc, initFrame(m.initProc, procname, filename))
-  app(prc, genSectionEnd(cfsTypeInit1))
-  
-  for i in cfsTypeInit2..cfsDynLibInit:
-    app(prc, genSectionStart(i))
-    app(prc, m.s[i])
-    app(prc, genSectionEnd(i))
-  
+ 
   app(prc, genSectionStart(cpsInit))
   app(prc, m.preInitProc.s(cpsInit))
   app(prc, m.initProc.s(cpsInit))
@@ -945,7 +946,17 @@ proc genInitCode(m: BModule) =
     app(prc, deinitFrame(m.initProc))
   app(prc, genSectionEnd(cpsStmts))
   app(prc, deinitGCFrame(m.initProc))
-  appf(prc, "}$n$n")
+  appf(prc, "}$N$N")
+
+  prc.appff("N_NOINLINE(void, $1)(void) {$n",
+            "define void $1() noinline {$n", [getDatInitName(m.module)])
+
+  for i in cfsTypeInit1..cfsDynLibInit:
+    app(prc, genSectionStart(i))
+    app(prc, m.s[i])
+    app(prc, genSectionEnd(i))
+  
+  appf(prc, "}$N$N")
   # we cannot simply add the init proc to ``m.s[cfsProcs]`` anymore because
   # that would lead to a *nesting* of merge sections which the merger does
   # not support. So we add it to another special section: ``cfsInitProc``
@@ -987,22 +998,15 @@ proc rawNewModule(module: PSym, filename: string): BModule =
 
 proc newModule(module: PSym, filename: string): BModule = 
   result = rawNewModule(module, filename)
+  if gModules.len <= module.position: gModules.setLen(module.position + 1)
+  gModules[module.position] = result
+
   if (optDeadCodeElim in gGlobalOptions): 
     if (sfDeadCodeElim in module.flags): 
       InternalError("added pending module twice: " & filename)
     addPendingModule(result)
 
-proc registerTypeInfoModule() = 
-  const moduleName = "nim__dat"
-  var s = NewSym(skModule, getIdent(moduleName), nil)
-  gNimDat = rawNewModule(s, (options.gProjectPath / moduleName) & ".nim")
-  gNimDat.PreventStackTrace = true
-  addPendingModule(gNimDat)
-  appff(mainModProcs, "N_NOINLINE(void, $1)(void);$n", 
-        "declare void $1() noinline$n", [getInitName(s)])
-
 proc myOpen(module: PSym, filename: string): PPassContext = 
-  if gNimDat == nil: registerTypeInfoModule()
   result = newModule(module, filename)
 
 proc getCFile(m: BModule): string =
@@ -1010,11 +1014,6 @@ proc getCFile(m: BModule): string =
 
 proc myOpenCached(module: PSym, filename: string, 
                   rd: PRodReader): PPassContext = 
-  if gNimDat == nil:
-    registerTypeInfoModule()
-    gNimDat.fromCache = true
-    readMergeInfo(getCFile(gNimDat), gNimDat)
-    
   var m = newModule(module, filename)
   readMergeInfo(getCFile(m), m)
   result = m
@@ -1100,9 +1099,6 @@ proc myClose(b: PPassContext, n: PNode): PNode =
   # cached modules need to registered too: 
   registerModuleToMain(m.module)
   
-  if optDeadCodeElim notin gGlobalOptions and
-      sfDeadCodeElim notin m.module.flags: 
-    finishModule(m)
   if sfMainModule in m.module.flags: 
     var disp = generateMethodDispatchers()
     for i in 0..sonsLen(disp)-1: genProcAux(m, disp.sons[i].sym)
@@ -1111,16 +1107,12 @@ proc myClose(b: PPassContext, n: PNode): PNode =
     # deps are allowed (and the system module is processed in the wrong
     # order anyway)
     while gForwardedProcsCounter > 0: 
-      for i in countup(0, high(gPendingModules)): 
-        finishModule(gPendingModules[i])
-    for i in countup(0, high(gPendingModules)): 
-      writeModule(gPendingModules[i], pending=true)
-    setlen(gPendingModules, 0)
-  if optDeadCodeElim notin gGlobalOptions and
-      sfDeadCodeElim notin m.module.flags:
-    writeModule(m, pending=false)
-  if sfMainModule in m.module.flags: writeMapping(gMapping)
-      
+      for i in countup(0, high(gModules)): 
+        finishModule(gModules[i])
+    for i in countup(0, high(gModules)): 
+      writeModule(gModules[i], pending=true)
+    writeMapping(gMapping)
+
 proc cgenPass(): TPass = 
   initPass(result)
   result.open = myOpen
diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim
index 72c7ceae5..fabad86ab 100644
--- a/compiler/cgendata.nim
+++ b/compiler/cgendata.nim
@@ -112,14 +112,14 @@ type
     labels*: natural          # for generating unique module-scope names
 
 var
-  mainModProcs*, mainModInit*: PRope # parts of the main module
+  mainModProcs*, mainModInit*, mainDatInit*: PRope # parts of the main module
   gMapping*: PRope             # the generated mapping file (if requested)
   gProcProfile*: Natural       # proc profile counter
   gPendingModules*: seq[BModule] = @[] # list of modules that are not
                                        # finished with code generation
+  gModules*: seq[BModule] = @[] # list of all compiled modules
   gForwardedProcsCounter*: int = 0
-  gNimDat*: BModule            # generated global data
-
+ 
 proc s*(p: BProc, s: TCProcSection): var PRope {.inline.} =
   # section in the current block
   result = p.blocks[p.blocks.len - 1].sections[s]
@@ -128,6 +128,10 @@ proc procSec*(p: BProc, s: TCProcSection): var PRope {.inline.} =
   # top level proc sections
   result = p.blocks[0].sections[s]
 
+proc bmod*(module: PSym): BModule =
+  # obtains the BModule for a given module PSym
+  result = gModules[module.position]
+
 proc newProc*(prc: PSym, module: BModule): BProc = 
   new(result)
   result.prc = prc
diff --git a/compiler/main.nim b/compiler/main.nim
index d3a40a32d..a9b00c4d2 100755
--- a/compiler/main.nim
+++ b/compiler/main.nim
@@ -39,6 +39,7 @@ proc registerModule(filename: string, module: PSym) =
 proc getModule(filename: string): PSym =
   result = compMods[filename]
 
+var gModulesCount = 0
 proc newModule(filename: string): PSym = 
   # We cannot call ``newSym`` here, because we have to circumvent the ID
   # mechanism, which we do in order to assign each module a persistent ID. 
@@ -51,6 +52,8 @@ proc newModule(filename: string): PSym =
   
   result.owner = result       # a module belongs to itself
   result.info = newLineInfo(filename, 1, 1)
+  result.position = gModulesCount
+  inc gModulesCount
   incl(result.flags, sfUsed)
   initStrTable(result.tab)
   RegisterModule(filename, result)