summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2010-08-24 00:19:16 +0200
committerAraq <rumpf_a@web.de>2010-08-24 00:19:16 +0200
commite439c6b02e62837e1387e339d72fca91afd3981a (patch)
treee2b03747c77e8d7d05d7b0a947d4693dc78ee9ac
parentb1ca3ab7c517e5e6b1b9f549e3572c84dad77fb3 (diff)
downloadNim-e439c6b02e62837e1387e339d72fca91afd3981a.tar.gz
bugfix: init of temps
-rwxr-xr-x.bzrignore18
-rwxr-xr-xlib/nimbase.h11
-rwxr-xr-xlib/pure/json.nim2
-rwxr-xr-xlib/pure/strtabs.nim2
-rwxr-xr-xlib/system.nim6
-rwxr-xr-xlib/system/systhread.nim26
-rwxr-xr-x[-rw-r--r--]lib/wrappers/expat.nim0
-rwxr-xr-xrod/ccgexprs.nim18
-rwxr-xr-xrod/ccgstmts.nim23
-rwxr-xr-xrod/cgen.nim46
-rwxr-xr-xrod/evals.nim2
-rwxr-xr-xrod/nimrod.ini4
-rwxr-xr-xrod/semstmts.nim8
-rwxr-xr-xrod/semtypes.nim15
-rwxr-xr-xtodo.txt2
15 files changed, 107 insertions, 76 deletions
diff --git a/.bzrignore b/.bzrignore
deleted file mode 100755
index a638ed4bd..000000000
--- a/.bzrignore
+++ /dev/null
@@ -1,18 +0,0 @@
-web/*.html
-doc/*.html
-*.o
-*.pyc
-*.pyo
-*.obj
-*.ppu
-*.exe
-*.dll
-*.zip
-*.tar.gz
-dist
-web
-misc
-lib/base/devel
-lib/base/devel/*
-lib/devel
-lib/devel/*
diff --git a/lib/nimbase.h b/lib/nimbase.h
index 5bc644dc9..01c3ece20 100755
--- a/lib/nimbase.h
+++ b/lib/nimbase.h
@@ -433,4 +433,15 @@ struct NimException {
 
 #define NIM_POSIX_INIT  __attribute__((constructor)) 
 
+
+#if defined(_MSCVER) && defined(__i386__)
+__declspec(naked) int __fastcall NimXadd(volatile int* pNum, int val) {
+  __asm {
+    lock xadd dword ptr [ECX], EDX
+    mov EAX, EDX
+    ret
+  }
+}
+#endif
+
 #endif
diff --git a/lib/pure/json.nim b/lib/pure/json.nim
index bc52fb886..0fd2a9f01 100755
--- a/lib/pure/json.nim
+++ b/lib/pure/json.nim
@@ -345,6 +345,8 @@ proc next*(my: var TJsonParser) =
   ## retrieves the first/next event. This controls the parser.
   var tk = getTok(my)
   var i = my.state.len-1
+  # the following code is a state machine. If we had proper coroutines,
+  # the code could be much simpler.
   case my.state[i]
   of stateEof:
     if tk == tkEof:
diff --git a/lib/pure/strtabs.nim b/lib/pure/strtabs.nim
index 9779be5ff..1ac8930b0 100755
--- a/lib/pure/strtabs.nim
+++ b/lib/pure/strtabs.nim
@@ -73,7 +73,7 @@ proc mustRehash(length, counter: int): bool =
   assert(length > counter)
   result = (length * 2 < counter * 3) or (length - counter < 4)
 
-proc nextTry(h, maxHash: THash): THash =
+proc nextTry(h, maxHash: THash): THash {.inline.} =
   result = ((5 * h) + 1) and maxHash
 
 proc RawGet(t: PStringTable, key: string): int =
diff --git a/lib/system.nim b/lib/system.nim
index 626002794..0152ebf23 100755
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1303,6 +1303,12 @@ when not defined(EcmaScript) and not defined(NimrodVM):
 
 when not defined(EcmaScript) and not defined(NimrodVM):
 
+  proc atomicInc*(memLoc: var int, x: int): int {.inline.}
+    ## atomic increment of `memLoc`. Returns the value after the operation.
+  
+  proc atomicDec*(memLoc: var int, x: int): int {.inline.}
+    ## atomic decrement of `memLoc`. Returns the value after the operation.
+
   proc initGC()
 
   proc initStackBottom() {.inline.} = 
diff --git a/lib/system/systhread.nim b/lib/system/systhread.nim
index 611191e70..68121661f 100755
--- a/lib/system/systhread.nim
+++ b/lib/system/systhread.nim
@@ -7,9 +7,35 @@
 #    distribution, for details about the copyright.
 #
 
+when defined(gcc) or defined(llvm_gcc):
+  proc sync_add_and_fetch(p: var int, val: int): int {.
+    importc: "__sync_add_and_fetch", nodecl.}
+  proc sync_sub_and_fetch(p: var int, val: int): int {.
+    importc: "__sync_sub_and_fetch", nodecl.}
+elif defined(vcc):
+  proc sync_add_and_fetch(p: var int, val: int): int {.
+    importc: "NimXadd", nodecl.}
+
 const
   isMultiThreaded* = true
   maxThreads = 256
+
+proc atomicInc(memLoc: var int, x: int): int =
+  when isMultiThreaded:
+    result = sync_add_and_fetch(memLoc, x)
+  else:
+    inc(memLoc, x)
+    result = memLoc
+  
+proc atomicDec(memLoc: var int, x: int): int =
+  when isMultiThreaded:
+    when defined(sync_sub_and_fetch):
+      result = sync_sub_and_fetch(memLoc, x)
+    else:
+      result = sync_add_and_fetch(memLoc, -x)
+  else:
+    dec(memLoc, x)
+    result = memLoc  
   
 type
   TThread* {.final, pure.} = object
diff --git a/lib/wrappers/expat.nim b/lib/wrappers/expat.nim
index 59e698263..59e698263 100644..100755
--- a/lib/wrappers/expat.nim
+++ b/lib/wrappers/expat.nim
diff --git a/rod/ccgexprs.nim b/rod/ccgexprs.nim
index 88599f8f4..7ea90eec8 100755
--- a/rod/ccgexprs.nim
+++ b/rod/ccgexprs.nim
@@ -153,21 +153,6 @@ proc getStorageLoc(n: PNode): TStorageLoc =
     result = getStorageLoc(n.sons[0])
   else: result = OnUnknown
 
-proc rdLoc(a: TLoc): PRope =
-  # 'read' location (deref if indirect)
-  result = a.r
-  if lfIndirect in a.flags: result = ropef("(*$1)", [result])
-
-proc addrLoc(a: TLoc): PRope =
-  result = a.r
-  if not (lfIndirect in a.flags): result = con("&", result)
-
-proc rdCharLoc(a: TLoc): PRope =
-  # read a location that may need a char-cast:
-  result = rdLoc(a)
-  if skipTypes(a.t, abstractRange).kind == tyChar:
-    result = ropef("((NU8)($1))", [result])
-
 type
   TAssignmentFlag = enum
     needToCopy, needForSubtypeCheck, afDestIsNil, afDestIsNotNil, afSrcIsNil,
@@ -1242,7 +1227,8 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
       initLocExpr(p, e.sons[2], b)
       if d.k == locNone: getTemp(p, a.t, d)
       appf(p.s[cpsStmts],
-           "for ($1 = 0; $1 < $2; $1++) $n" & "  $3[$1] = $4[$1] $6 $5[$1];$n", [
+           "for ($1 = 0; $1 < $2; $1++) $n" & 
+           "  $3[$1] = $4[$1] $6 $5[$1];$n", [
           rdLoc(i), toRope(size), rdLoc(d), rdLoc(a), rdLoc(b),
           toRope(lookupOpr[op])])
     of mInSet: genInOp(p, e, d)
diff --git a/rod/ccgstmts.nim b/rod/ccgstmts.nim
index f07dfb7e4..88deb7f12 100755
--- a/rod/ccgstmts.nim
+++ b/rod/ccgstmts.nim
@@ -44,29 +44,6 @@ proc genReturnStmt(p: BProc, t: PNode) =
   finishTryStmt(p, p.nestedTryStmts)
   appff(p.s[cpsStmts], "goto BeforeRet;$n", "br label %BeforeRet$n", [])
 
-proc initVariable(p: BProc, v: PSym) = 
-  if containsGarbageCollectedRef(v.typ) or (v.ast == nil): 
-    if not (skipTypes(v.typ, abstractVarRange).Kind in
-        {tyArray, tyArrayConstr, tySet, tyTuple, tyObject}): 
-      if gCmd == cmdCompileToLLVM: 
-        appf(p.s[cpsStmts], "store $2 0, $2* $1$n", 
-             [addrLoc(v.loc), getTypeDesc(p.module, v.loc.t)])
-      else: 
-        appf(p.s[cpsStmts], "$1 = 0;$n", [rdLoc(v.loc)])
-    else: 
-      if gCmd == cmdCompileToLLVM: 
-        app(p.module.s[cfsProcHeaders], 
-            "declare void @llvm.memset.i32(i8*, i8, i32, i32)" & tnl)
-        inc(p.labels, 2)
-        appf(p.s[cpsStmts], "%LOC$3 = getelementptr $2* null, %NI 1$n" &
-            "%LOC$4 = cast $2* %LOC$3 to i32$n" &
-            "call void @llvm.memset.i32(i8* $1, i8 0, i32 %LOC$4, i32 0)$n", [
-            addrLoc(v.loc), getTypeDesc(p.module, v.loc.t), toRope(p.labels), 
-            toRope(p.labels - 1)])
-      else: 
-        appf(p.s[cpsStmts], "memset((void*)$1, 0, sizeof($2));$n", 
-             [addrLoc(v.loc), rdLoc(v.loc)])
-  
 proc genVarTuple(p: BProc, n: PNode) = 
   var 
     L: int
diff --git a/rod/cgen.nim b/rod/cgen.nim
index 691fb29fb..415eb1a9c 100755
--- a/rod/cgen.nim
+++ b/rod/cgen.nim
@@ -236,6 +236,51 @@ include "ccgtypes.nim"
 
 # ------------------------------ Manager of temporaries ------------------
 
+proc rdLoc(a: TLoc): PRope =
+  # 'read' location (deref if indirect)
+  result = a.r
+  if lfIndirect in a.flags: result = ropef("(*$1)", [result])
+
+proc addrLoc(a: TLoc): PRope =
+  result = a.r
+  if not (lfIndirect in a.flags): result = con("&", result)
+
+proc rdCharLoc(a: TLoc): PRope =
+  # read a location that may need a char-cast:
+  result = rdLoc(a)
+  if skipTypes(a.t, abstractRange).kind == tyChar:
+    result = ropef("((NU8)($1))", [result])
+
+proc zeroLoc(p: BProc, loc: TLoc) = 
+  if not (skipTypes(loc.t, abstractVarRange).Kind in
+      {tyArray, tyArrayConstr, tySet, tyTuple, tyObject}): 
+    if gCmd == cmdCompileToLLVM: 
+      appf(p.s[cpsStmts], "store $2 0, $2* $1$n", 
+           [addrLoc(loc), getTypeDesc(p.module, loc.t)])
+    else: 
+      appf(p.s[cpsStmts], "$1 = 0;$n", [rdLoc(loc)])
+  else: 
+    if gCmd == cmdCompileToLLVM: 
+      app(p.module.s[cfsProcHeaders], 
+          "declare void @llvm.memset.i32(i8*, i8, i32, i32)" & tnl)
+      inc(p.labels, 2)
+      appf(p.s[cpsStmts], "%LOC$3 = getelementptr $2* null, %NI 1$n" &
+          "%LOC$4 = cast $2* %LOC$3 to i32$n" &
+          "call void @llvm.memset.i32(i8* $1, i8 0, i32 %LOC$4, i32 0)$n", [
+          addrLoc(loc), getTypeDesc(p.module, loc.t), toRope(p.labels), 
+          toRope(p.labels - 1)])
+    else: 
+      appf(p.s[cpsStmts], "memset((void*)$1, 0, sizeof($2));$n", 
+           [addrLoc(loc), rdLoc(loc)])
+
+proc initVariable(p: BProc, v: PSym) = 
+  if containsGarbageCollectedRef(v.typ) or (v.ast == nil): 
+    zeroLoc(p, v.loc)
+    
+proc initTemp(p: BProc, tmp: var TLoc) = 
+  if containsGarbageCollectedRef(tmp.t):
+    zeroLoc(p, tmp)
+
 proc getTemp(p: BProc, t: PType, result: var TLoc) = 
   inc(p.labels)
   if gCmd == cmdCompileToLLVM: 
@@ -248,6 +293,7 @@ proc getTemp(p: BProc, t: PType, result: var TLoc) =
   result.t = getUniqueType(t)
   result.s = OnStack
   result.flags = {}
+  initTemp(p, result)
 
 proc cstringLit(p: BProc, r: var PRope, s: string): PRope = 
   if gCmd == cmdCompileToLLVM: 
diff --git a/rod/evals.nim b/rod/evals.nim
index 4232bb832..4f0aeb6c6 100755
--- a/rod/evals.nim
+++ b/rod/evals.nim
@@ -315,7 +315,7 @@ proc evalFieldAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
   for i in countup(0, sonsLen(n) - 1): 
     if x.sons[i].kind != nkExprColonExpr: 
       InternalError(n.info, "evalFieldAccess")
-    if x.sons[i].sons[0].sym.name.id == field.id: 
+    if x.sons[i].sons[0].sym.name.id == field.name.id: 
       result = x.sons[i].sons[1]
       if not aliasNeeded(result, flags): result = copyTree(result)
       return
diff --git a/rod/nimrod.ini b/rod/nimrod.ini
index 9e3445c44..118ef6223 100755
--- a/rod/nimrod.ini
+++ b/rod/nimrod.ini
@@ -2,8 +2,8 @@
 Name: "Nimrod"
 Version: "$version"
 ; Windows and i386 must be first!
-OS: "windows" ;linux;macosx;freebsd;netbsd;openbsd;solaris"
-CPU: "i386" ;amd64"  # ;sparc;powerpc
+OS: "windows;linux;macosx;freebsd;netbsd;openbsd;solaris"
+CPU: "i386;amd64;powerpc"  # ;sparc
 Authors: "Andreas Rumpf"
 Description: """This is the Nimrod Compiler. Nimrod is a new statically typed,
 imperative programming language, that supports procedural, functional, object
diff --git a/rod/semstmts.nim b/rod/semstmts.nim
index e700f8e71..cadecad40 100755
--- a/rod/semstmts.nim
+++ b/rod/semstmts.nim
@@ -663,10 +663,14 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
     n.sons[genericParamsPos] = semGenericParamList(c, n.sons[genericParamsPos])
     gp = n.sons[genericParamsPos]
   else: 
-    gp = newNodeI(nkGenericParams, n.info) # process parameters:
+    gp = newNodeI(nkGenericParams, n.info)
+  # process parameters:
   if n.sons[paramsPos] != nil: 
     semParamList(c, n.sons[ParamsPos], gp, s)
-    if sonsLen(gp) > 0: n.sons[genericParamsPos] = gp
+    if sonsLen(gp) > 0: 
+      if n.sons[genericParamsPos] == nil:
+        # we have a list of implicit type parameters:
+        n.sons[genericParamsPos] = gp
     addParams(c, s.typ.n)
   else: 
     s.typ = newTypeS(tyProc, c)
diff --git a/rod/semtypes.nim b/rod/semtypes.nim
index a88490ce0..f5fae4811 100755
--- a/rod/semtypes.nim
+++ b/rod/semtypes.nim
@@ -485,15 +485,9 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, prev: PType): PType =
   result.callConv = lastOptionEntry(c).defaultCC
   result.n = newNodeI(nkFormalParams, n.info)
   if (genericParams != nil) and (sonsLen(genericParams) == 0): IntSetInit(cl)
-  if n.sons[0] == nil: 
-    addSon(result, nil)       # return type
-    addSon(result.n, newNodeI(nkType, n.info)) 
-    # BUGFIX: nkType must exist!
-    # XXX but it does not, if n.sons[paramsPos] == nil?
-  else: 
-    addSon(result, nil)
-    res = newNodeI(nkType, n.info)
-    addSon(result.n, res)
+  addSon(result, nil) # return type
+  res = newNodeI(nkType, n.info)
+  addSon(result.n, res)
   IntSetInit(check)
   var counter = 0
   for i in countup(1, sonsLen(n) - 1): 
@@ -531,9 +525,8 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, prev: PType): PType =
     res.typ = result.sons[0]
 
 proc semStmtListType(c: PContext, n: PNode, prev: PType): PType = 
-  var length: int
   checkMinSonsLen(n, 1)
-  length = sonsLen(n)
+  var length = sonsLen(n)
   for i in countup(0, length - 2): 
     n.sons[i] = semStmt(c, n.sons[i])
   if length > 0: 
diff --git a/todo.txt b/todo.txt
index 6536a6e19..e752e5862 100755
--- a/todo.txt
+++ b/todo.txt
@@ -17,8 +17,6 @@ Bugs
 ----
 - proc (x: int) is passable to proc (x: var int)  !?
 - detected by pegs module 64bit: p(result, result) should use a temporary!
-- seq[TLoc] in C code generator always failed --> probably some reference
-  counting is wrong; try to reproduce this in the GC test
 - the parser allows empty object case branches
 - SDL event handling