summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-02-24 19:18:57 +0100
committerAraq <rumpf_a@web.de>2015-02-24 19:19:08 +0100
commitf4a0400de285feec8fe07a41b5a0191728614227 (patch)
treed7ed5c7a33e84318c2909196101969aebef9487d
parentf3756d2ccb6059c4b2a51e8565df0fcd7d8a57d5 (diff)
downloadNim-f4a0400de285feec8fe07a41b5a0191728614227.tar.gz
fixes #2199, fixes #2197
-rw-r--r--compiler/ccgcalls.nim2
-rw-r--r--compiler/ccgstmts.nim3
-rw-r--r--compiler/ccgutils.nim48
-rw-r--r--lib/system/sysio.nim2
-rw-r--r--todo.txt1
5 files changed, 31 insertions, 25 deletions
diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim
index fb878a83e..200ff91e0 100644
--- a/compiler/ccgcalls.nim
+++ b/compiler/ccgcalls.nim
@@ -133,7 +133,7 @@ proc genArg(p: BProc, n: PNode, param: PSym; call: PNode): PRope =
     var n = if n.kind != nkHiddenAddr: n else: n.sons[0]
     result = openArrayLoc(p, n)
   elif ccgIntroducedPtr(param):
-    initLocExprSingleUse(p, n, a)
+    initLocExpr(p, n, a)
     result = addrLoc(a)
   elif p.module.compileToCpp and param.typ.kind == tyVar and 
       n.kind == nkHiddenAddr:
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index 61568c9e6..a4938c9ac 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -203,7 +203,8 @@ proc genSingleVar(p: BProc, a: PNode) =
     registerGcRoot(p, v)
   else:
     let imm = isAssignedImmediately(a.sons[2])
-    if imm and p.module.compileToCpp and p.splitDecls == 0:
+    if imm and p.module.compileToCpp and p.splitDecls == 0 and
+        not containsHiddenPointer(v.typ):
       # C++ really doesn't like things like 'Foo f; f = x' as that invokes a
       # parameterless constructor followed by an assignment operator. So we
       # generate better code here:
diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim
index e4ce0aa6c..134619d4a 100644
--- a/compiler/ccgutils.nim
+++ b/compiler/ccgutils.nim
@@ -69,7 +69,20 @@ when false:
   proc echoStats*() =
     for i in countup(low(TTypeKind), high(TTypeKind)): 
       echo i, " ", gTypeTable[i].counter
-  
+
+proc slowSearch(key: PType; k: TTypeKind): PType =
+  # tuples are quite horrible as C does not support them directly and
+  # tuple[string, string] is a (strange) subtype of
+  # tuple[nameA, nameB: string]. This bites us here, so we
+  # use 'sameBackendType' instead of 'sameType'.
+  if idTableHasObjectAsKey(gTypeTable[k], key): return key
+  for h in countup(0, high(gTypeTable[k].data)):
+    var t = PType(gTypeTable[k].data[h].key)
+    if t != nil and sameBackendType(t, key): 
+      return t
+  idTablePut(gTypeTable[k], key, key)
+  result = key
+
 proc getUniqueType*(key: PType): PType = 
   # this is a hotspot in the compiler!
   if key == nil: return 
@@ -96,23 +109,20 @@ proc getUniqueType*(key: PType): PType =
     #if obj.sym != nil and obj.sym.name.s == "TOption":
     #  echo "for ", typeToString(key), " I returned "
     #  debug result
+  of tyPtr, tyRef, tyVar:
+    let elemType = lastSon(key)
+    if elemType.kind in {tyBool, tyChar, tyInt..tyUInt64}:
+      # no canonicalization for integral types, so that e.g. ``ptr pid_t`` is
+      # produced instead of ``ptr NI``.
+      result = key
+    else:
+      result = slowSearch(key, k)
   of tyArrayConstr, tyGenericInvocation, tyGenericBody,
      tyOpenArray, tyArray, tySet, tyRange, tyTuple,
-     tyPtr, tyRef, tySequence, tyForward, tyVarargs, tyProxy, tyVar:
-    # tuples are quite horrible as C does not support them directly and
-    # tuple[string, string] is a (strange) subtype of
-    # tuple[nameA, nameB: string]. This bites us here, so we 
-    # use 'sameBackendType' instead of 'sameType'.
-
+     tySequence, tyForward, tyVarargs, tyProxy:
     # we have to do a slow linear search because types may need
     # to be compared by their structure:
-    if idTableHasObjectAsKey(gTypeTable[k], key): return key 
-    for h in countup(0, high(gTypeTable[k].data)): 
-      var t = PType(gTypeTable[k].data[h].key)
-      if t != nil and sameBackendType(t, key): 
-        return t
-    idTablePut(gTypeTable[k], key, key)
-    result = key
+    result = slowSearch(key, k)
   of tyObject:
     if tfFromGeneric notin key.flags:
       # fast case; lookup per id suffices:
@@ -139,14 +149,8 @@ proc getUniqueType*(key: PType): PType =
       result = key
     else:
       # ugh, we need the canon here:
-      if idTableHasObjectAsKey(gTypeTable[k], key): return key 
-      for h in countup(0, high(gTypeTable[k].data)): 
-        var t = PType(gTypeTable[k].data[h].key)
-        if t != nil and sameBackendType(t, key): 
-          return t
-      idTablePut(gTypeTable[k], key, key)
-      result = key
-      
+      result = slowSearch(key, k)
+
 proc tableGetType*(tab: TIdTable, key: PType): RootRef = 
   # returns nil if we need to declare this type
   result = idTableGet(tab, key)
diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim
index 5d68d112e..a05398a09 100644
--- a/lib/system/sysio.nim
+++ b/lib/system/sysio.nim
@@ -188,7 +188,7 @@ when defined(windows) and not defined(useWinAnsi):
     proc wfopen(filename, mode: WideCString): pointer {.
       importcpp: "_wfopen((const wchar_t*)#, (const wchar_t*)#)", nodecl.}
     proc wfreopen(filename, mode: WideCString, stream: File): File {.
-      importc: "_wfreopen((const wchar_t*)#, (const wchar_t*)#)", nodecl.}
+      importcpp: "_wfreopen((const wchar_t*)#, (const wchar_t*)#, #)", nodecl.}
   else:
     proc wfopen(filename, mode: WideCString): pointer {.
       importc: "_wfopen", nodecl.}
diff --git a/todo.txt b/todo.txt
index 79fe9d05a..3fed10aeb 100644
--- a/todo.txt
+++ b/todo.txt
@@ -10,6 +10,7 @@ version 0.10.4
 version 1.0
 ===========
 
+- figure out why C++ bootstrapping is so much slower
 - nimsuggest: auto-completion needs to work in 'class' macros
 - improve the docs for inheritance
 - The bitwise 'not' operator will be renamed to 'bnot' to