bugfix: init of temps

This commit is contained in:
Araq
2010-08-24 00:19:16 +02:00
parent b1ca3ab7c5
commit e439c6b02e
15 changed files with 107 additions and 76 deletions

View File

@@ -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/*

View File

@@ -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

View File

@@ -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:

View File

@@ -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 =

View File

@@ -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.} =

View File

@@ -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

0
lib/wrappers/expat.nim Normal file → Executable file
View File

View File

@@ -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)

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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:

View File

@@ -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