diff options
author | Araq <rumpf_a@web.de> | 2010-08-24 00:19:16 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2010-08-24 00:19:16 +0200 |
commit | e439c6b02e62837e1387e339d72fca91afd3981a (patch) | |
tree | e2b03747c77e8d7d05d7b0a947d4693dc78ee9ac | |
parent | b1ca3ab7c517e5e6b1b9f549e3572c84dad77fb3 (diff) | |
download | Nim-e439c6b02e62837e1387e339d72fca91afd3981a.tar.gz |
bugfix: init of temps
-rwxr-xr-x | .bzrignore | 18 | ||||
-rwxr-xr-x | lib/nimbase.h | 11 | ||||
-rwxr-xr-x | lib/pure/json.nim | 2 | ||||
-rwxr-xr-x | lib/pure/strtabs.nim | 2 | ||||
-rwxr-xr-x | lib/system.nim | 6 | ||||
-rwxr-xr-x | lib/system/systhread.nim | 26 | ||||
-rwxr-xr-x[-rw-r--r--] | lib/wrappers/expat.nim | 0 | ||||
-rwxr-xr-x | rod/ccgexprs.nim | 18 | ||||
-rwxr-xr-x | rod/ccgstmts.nim | 23 | ||||
-rwxr-xr-x | rod/cgen.nim | 46 | ||||
-rwxr-xr-x | rod/evals.nim | 2 | ||||
-rwxr-xr-x | rod/nimrod.ini | 4 | ||||
-rwxr-xr-x | rod/semstmts.nim | 8 | ||||
-rwxr-xr-x | rod/semtypes.nim | 15 | ||||
-rwxr-xr-x | todo.txt | 2 |
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 |