Merge pull request #57 from zah/codegen-fixes

Codegen fixes
This commit is contained in:
Araq
2011-09-20 11:59:06 -07:00
9 changed files with 102 additions and 69 deletions

View File

@@ -105,7 +105,7 @@ proc bitSetToWord(s: TBitSet, size: int): BiggestInt =
proc genRawSetData(cs: TBitSet, size: int): PRope =
var frmt: TFormatStr
if size > 8:
result = toRope('{' & tnl)
result = ropef("{$n")
for i in countup(0, size - 1):
if i < size - 1:
# not last iteration?
@@ -128,7 +128,7 @@ proc genSetNode(p: BProc, n: PNode): PRope =
if id == gid:
# not found in cache:
inc(gid)
appf(p.module.s[cfsData], "static NIM_CONST $1 $2 = $3;",
appf(p.module.s[cfsData], "static NIM_CONST $1 $2 = $3;$n",
[getTypeDesc(p.module, n.typ), result, genRawSetData(cs, size)])
else:
result = genRawSetData(cs, size)
@@ -371,8 +371,8 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
else:
storage = getTypeDesc(p.module, t)
var tmp = getTempName()
appcg(p, cpsLocals, "$1 $2;", [storage, tmp])
appcg(p, cpsStmts, "$1 = #$2($3, $4);", [tmp, toRope(prc[m]),
appcg(p, cpsLocals, "$1 $2;$n", [storage, tmp])
appcg(p, cpsStmts, "$1 = #$2($3, $4);$n", [tmp, toRope(prc[m]),
rdLoc(a), rdLoc(b)])
if size < platform.IntSize or t.kind in {tyRange, tyEnum, tySet}:
appcg(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n",
@@ -797,14 +797,14 @@ proc fixupCall(p: BProc, t: PNode, d: var TLoc, pl: PRope) =
app(pl, addrLoc(d))
app(pl, ")")
app(p.s[cpsStmts], pl)
app(p.s[cpsStmts], ';' & tnl)
appf(p.s[cpsStmts], ";$n")
else:
var tmp: TLoc
getTemp(p, typ.sons[0], tmp)
app(pl, addrLoc(tmp))
app(pl, ")")
app(p.s[cpsStmts], pl)
app(p.s[cpsStmts], ';' & tnl)
appf(p.s[cpsStmts], ";$n")
genAssignment(p, d, tmp, {}) # no need for deep copying
else:
app(pl, ")")
@@ -817,7 +817,7 @@ proc fixupCall(p: BProc, t: PNode, d: var TLoc, pl: PRope) =
else:
app(pl, ")")
app(p.s[cpsStmts], pl)
app(p.s[cpsStmts], ';' & tnl)
appf(p.s[cpsStmts], ";$n")
proc openArrayLoc(a: TLoc): PRope =
case skipTypes(a.t, abstractVar).kind
@@ -926,14 +926,14 @@ proc genNamedParamCall(p: BProc, t: PNode, d: var TLoc) =
app(pl, addrLoc(d))
app(pl, "]")
app(p.s[cpsStmts], pl)
app(p.s[cpsStmts], ';' & tnl)
appf(p.s[cpsStmts], ";$n")
else:
var tmp: TLoc
getTemp(p, typ.sons[0], tmp)
app(pl, addrLoc(tmp))
app(pl, "]")
app(p.s[cpsStmts], pl)
app(p.s[cpsStmts], ';' & tnl)
appf(p.s[cpsStmts], ";$n")
genAssignment(p, d, tmp, {}) # no need for deep copying
else:
app(pl, "]")
@@ -946,7 +946,7 @@ proc genNamedParamCall(p: BProc, t: PNode, d: var TLoc) =
else:
app(pl, "]")
app(p.s[cpsStmts], pl)
app(p.s[cpsStmts], ';' & tnl)
appf(p.s[cpsStmts], ";$n")
proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
# <Nimrod code>
@@ -1839,7 +1839,7 @@ proc genConstSimpleList(p: BProc, n: PNode): PRope =
for i in countup(0, length - 2):
appf(result, "$1,$n", [genNamedConstExpr(p, n.sons[i])])
if length > 0: app(result, genNamedConstExpr(p, n.sons[length - 1]))
app(result, '}' & tnl)
appf(result, "}$n")
proc genConstExpr(p: BProc, n: PNode): PRope =
case n.Kind

View File

@@ -13,22 +13,6 @@ const
stringCaseThreshold = 8
# above X strings a hash-switch for strings is generated
proc genLineDir(p: BProc, t: PNode) =
var line = toLinenumber(t.info) # BUGFIX
if line < 0:
line = 0 # negative numbers are not allowed in #line
if optLineDir in p.Options and line > 0:
appff(p.s[cpsStmts], "#line $2 $1$n", "; line $2 \"$1\"$n",
[makeCString(toFilename(t.info)), toRope(line)])
if ({optStackTrace, optEndb} * p.Options == {optStackTrace, optEndb}) and
(p.prc == nil or sfPure notin p.prc.flags):
appcg(p, cpsStmts, "#endb($1);$n", [toRope(line)])
elif ({optLineTrace, optStackTrace} * p.Options ==
{optLineTrace, optStackTrace}) and
(p.prc == nil or sfPure notin p.prc.flags):
appf(p.s[cpsStmts], "F.line = $1;F.filename = $2;$n",
[toRope(line), makeCString(toFilename(t.info).extractFilename)])
proc genVarTuple(p: BProc, n: PNode) =
var tup, field: TLoc
if n.kind != nkVarTuple: InternalError(n.info, "genVarTuple")
@@ -171,14 +155,14 @@ proc genWhileStmt(p: BProc, t: PNode) =
setlen(p.blocks, length + 1)
p.blocks[length].id = - p.labels # negative because it isn't used yet
p.blocks[length].nestedTryStmts = p.nestedTryStmts.len
app(p.s[cpsStmts], "while (1) {" & tnl)
appf(p.s[cpsStmts], "while (1) {$n")
initLocExpr(p, t.sons[0], a)
if (t.sons[0].kind != nkIntLit) or (t.sons[0].intVal == 0):
p.blocks[length].id = abs(p.blocks[length].id)
appf(p.s[cpsStmts], "if (!$1) goto $2;$n", [rdLoc(a), Labl])
genStmts(p, t.sons[1])
if p.blocks[length].id > 0: appf(p.s[cpsStmts], "} $1: ;$n", [Labl])
else: app(p.s[cpsStmts], '}' & tnl)
else: appf(p.s[cpsStmts], "}$n")
setlen(p.blocks, len(p.blocks) - 1)
dec(p.withinLoop)
@@ -231,9 +215,9 @@ proc genRaiseStmt(p: BProc, t: PNode) =
genLineDir(p, t)
# reraise the last exception:
#if gCmd == cmdCompileToCpp:
# appcg(p, cpsStmts, "throw;" & tnl)
# appcg(p, cpsStmts, "throw;$n")
#else:
appcg(p, cpsStmts, "#reraiseException();" & tnl)
appcg(p, cpsStmts, "#reraiseException();$n")
proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
rangeFormat, eqFormat: TFormatStr, labl: TLabel) =
@@ -326,7 +310,7 @@ proc genStringCase(p: BProc, t: PNode) =
if branches[j] != nil:
appf(p.s[cpsStmts], "case $1: $n$2break;$n",
[intLiteral(j), branches[j]])
app(p.s[cpsStmts], '}' & tnl) # else statement:
appf(p.s[cpsStmts], "}$n") # else statement:
if t.sons[sonsLen(t) - 1].kind != nkOfBranch:
appf(p.s[cpsStmts], "goto LA$1;$n", [toRope(p.labels)])
# third pass: generate statements
@@ -388,13 +372,13 @@ proc genOrdinalCase(p: BProc, n: PNode) =
genStmts(p, branch[length-1])
else:
# else part of case statement:
app(p.s[cpsStmts], "default:" & tnl)
appf(p.s[cpsStmts], "default:$n")
genStmts(p, branch[0])
hasDefault = true
app(p.s[cpsStmts], "break;" & tnl)
appf(p.s[cpsStmts], "break;$n")
if (hasAssume in CC[ccompiler].props) and not hasDefault:
app(p.s[cpsStmts], "default: __assume(0);" & tnl)
app(p.s[cpsStmts], '}' & tnl)
appf(p.s[cpsStmts], "default: __assume(0);$n")
appf(p.s[cpsStmts], "}$n")
if Lend != nil: fixLabel(p, Lend)
proc genCaseStmt(p: BProc, t: PNode) =
@@ -453,7 +437,7 @@ proc genTryStmtCpp(p: BProc, t: PNode) =
appf(p.s[cpsLocals], "volatile NIM_BOOL $1 = NIM_FALSE;$n", [rethrowFlag])
if optStackTrace in p.Options:
appcg(p, cpsStmts, "#setFrame((TFrame*)&F);$n")
app(p.s[cpsStmts], "try {" & tnl)
appf(p.s[cpsStmts], "try {$n")
add(p.nestedTryStmts, t)
genStmts(p, t.sons[0])
length = sonsLen(t)
@@ -467,7 +451,7 @@ proc genTryStmtCpp(p: BProc, t: PNode) =
blen = sonsLen(t.sons[i])
if blen == 1:
# general except section:
app(p.s[cpsStmts], "default: " & tnl)
appf(p.s[cpsStmts], "default:$n")
genStmts(p, t.sons[i].sons[0])
else:
for j in countup(0, blen - 2):
@@ -476,10 +460,10 @@ proc genTryStmtCpp(p: BProc, t: PNode) =
genStmts(p, t.sons[i].sons[blen - 1])
if rethrowFlag != nil:
appf(p.s[cpsStmts], "$1 = NIM_FALSE; ", [rethrowFlag])
app(p.s[cpsStmts], "break;" & tnl)
appf(p.s[cpsStmts], "break;$n")
inc(i)
if t.sons[1].kind == nkExceptBranch:
app(p.s[cpsStmts], "}}" & tnl) # end of catch-switch statement
appf(p.s[cpsStmts], "}}$n") # end of catch-switch statement
appcg(p, cpsStmts, "#popSafePoint();")
discard pop(p.nestedTryStmts)
if (i < length) and (t.sons[i].kind == nkFinally):
@@ -528,10 +512,10 @@ proc genTryStmt(p: BProc, t: PNode) =
var blen = sonsLen(t.sons[i])
if blen == 1:
# general except section:
if i > 1: app(p.s[cpsStmts], "else {" & tnl)
if i > 1: appf(p.s[cpsStmts], "else {$n")
genStmts(p, t.sons[i].sons[0])
appcg(p, cpsStmts, "$1.status = 0;#popCurrentException();$n", [safePoint])
if i > 1: app(p.s[cpsStmts], '}' & tnl)
if i > 1: appf(p.s[cpsStmts], "}$n")
else:
var orExpr: PRope = nil
for j in countup(0, blen - 2):
@@ -547,7 +531,7 @@ proc genTryStmt(p: BProc, t: PNode) =
appcg(p, cpsStmts, "$1.status = 0;#popCurrentException();}$n",
[safePoint])
inc(i)
app(p.s[cpsStmts], '}' & tnl) # end of if statement
appf(p.s[cpsStmts], "}$n") # end of if statement
discard pop(p.nestedTryStmts)
if i < length and t.sons[i].kind == nkFinally:
genStmts(p, t.sons[i].sons[0])

View File

@@ -520,7 +520,7 @@ proc finishTypeDescriptions(m: BModule) =
while i < len(m.typeStack):
discard getTypeDesc(m, m.typeStack[i])
inc(i)
proc genProcHeader(m: BModule, prc: PSym): PRope =
var
rettype, params: PRope
@@ -529,6 +529,7 @@ proc genProcHeader(m: BModule, prc: PSym): PRope =
var check = initIntSet()
fillLoc(prc.loc, locProc, prc.typ, mangleName(prc), OnUnknown)
genProcParams(m, prc.typ, rettype, params, check)
genCLineDir(result, prc.ast.sons[codePos])
appf(result, "$1($2, $3)$4",
[toRope(CallingConvToStr[prc.typ.callConv]), rettype, prc.loc.r, params])

View File

@@ -103,6 +103,12 @@ proc toCChar*(c: Char): string =
of '\0'..'\x1F', '\x80'..'\xFF': result = '\\' & toOctal(c)
of '\'', '\"', '\\': result = '\\' & c
else: result = $(c)
proc makeSingleLineCString*(s: string): string =
result = "\""
for c in items(s):
result.add(c.toCChar)
result.add('\"')
proc makeCString*(s: string): PRope =
# BUGFIX: We have to split long strings into many ropes. Otherwise
@@ -113,10 +119,10 @@ proc makeCString*(s: string): PRope =
var res: string
result = nil
res = "\""
for i in countup(0, len(s) + 0 - 1):
if (i - 0 + 1) mod MaxLineLength == 0:
for i in countup(0, len(s) - 1):
if (i + 1) mod MaxLineLength == 0:
add(res, '\"')
add(res, "\n")
add(res, tnl)
app(result, toRope(res)) # reset:
setlen(res, 1)
res[0] = '\"'
@@ -129,8 +135,8 @@ proc makeLLVMString*(s: string): PRope =
var res: string
result = nil
res = "c\""
for i in countup(0, len(s) + 0 - 1):
if (i - 0 + 1) mod MaxLineLength == 0:
for i in countup(0, len(s) - 1):
if (i + 1) mod MaxLineLength == 0:
app(result, toRope(res))
setlen(res, 0)
case s[i]

View File

@@ -13,7 +13,7 @@
import
ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp,
options, intsets,
nversion, nimsets, msgs, crc, bitsets, idents, lists, types, ccgutils, os,
nversion, nimsets, msgs, crc, bitsets, idents, lists, types, ccgutils, os,
times, ropes, math, passes, rodread, wordrecg, treetab, cgmeth,
rodutils, renderer
@@ -204,7 +204,10 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: openarray[PRope]): PRope =
if j > high(args) + 1:
internalError("ropes: invalid format string $" & $(j))
app(result, args[j - 1])
of 'N', 'n':
of 'n':
if not (optLineDir in gOptions): app(result, tnl)
inc(i)
of 'N':
app(result, tnl)
inc(i)
else: InternalError("ropes: invalid format string $" & frmt[i])
@@ -241,6 +244,30 @@ proc appcg(p: BProc, s: TCProcSection, frmt: TFormatStr,
args: openarray[PRope]) =
app(p.s[s], ropecg(p.module, frmt, args))
proc safeLineNm(t: PNode) : int =
result = toLinenumber(t.info) # BUGFIX
if result < 0: result = 0 # negative numbers are not allowed in #line
proc genCLineDir(r: var PRope, filename: string, line: int) =
assert line >= 0
if optLineDir in gOptions:
appff(r, "$N#line $2 $1$N", "; line $2 \"$1\"$n",
[toRope(makeSingleLineCString(filename)), toRope(line)])
proc genCLineDir(r: var PRope, t: PNode) =
genCLineDir(r, t.info.toFullPath, t.safeLineNm)
proc genLineDir(p: BProc, t: PNode) =
var line = t.safeLineNm
genCLineDir(p.s[cpsStmts], t.info.toFullPath, line)
if ({optStackTrace, optEndb} * p.Options == {optStackTrace, optEndb}) and
(p.prc == nil or sfPure notin p.prc.flags):
appcg(p, cpsStmts, "#endb($1);$n", [toRope(line)])
elif ({optLineTrace, optStackTrace} * p.Options ==
{optLineTrace, optStackTrace}) and
(p.prc == nil or sfPure notin p.prc.flags):
appf(p.s[cpsStmts], "F.line = $1;F.filename = $2;$n",
[toRope(line), makeCString(toFilename(t.info).extractFilename)])
include "ccgtypes.nim"
@@ -546,13 +573,13 @@ proc cgsym(m: BModule, name: string): PRope =
result = sym.loc.r
proc generateHeaders(m: BModule) =
app(m.s[cfsHeaders], "#include \"nimbase.h\"" & tnl & tnl)
app(m.s[cfsHeaders], tnl & "#include \"nimbase.h\"" & tnl)
var it = PStrEntry(m.headerFiles.head)
while it != nil:
if it.data[0] notin {'\"', '<'}:
appf(m.s[cfsHeaders], "#include \"$1\"$n", [toRope(it.data)])
appf(m.s[cfsHeaders], "$N#include \"$1\"$N", [toRope(it.data)])
else:
appf(m.s[cfsHeaders], "#include $1$n", [toRope(it.data)])
appf(m.s[cfsHeaders], "$N#include $1$N", [toRope(it.data)])
it = PStrEntry(it.Next)
proc getFrameDecl(p: BProc) =
@@ -629,24 +656,24 @@ proc genProcAux(m: BModule, prc: PSym) =
if gProcProfile >= 64 * 1024:
InternalError(prc.info, "too many procedures for profiling")
discard cgsym(m, "profileData")
app(p.s[cpsLocals], "ticks NIM_profilingStart;" & tnl)
appf(p.s[cpsLocals], "ticks NIM_profilingStart;$n")
if prc.loc.a < 0:
appf(m.s[cfsDebugInit], "profileData[$1].procname = $2;$n", [
toRope(gProcProfile),
makeCString(prc.name.s)])
prc.loc.a = gProcProfile
inc(gProcProfile)
prepend(p.s[cpsInit], toRope("NIM_profilingStart = getticks();" & tnl))
prepend(p.s[cpsInit], ropef("NIM_profilingStart = getticks();$n"))
app(generatedProc, p.s[cpsInit])
app(generatedProc, p.s[cpsStmts])
if p.beforeRetNeeded: app(generatedProc, "BeforeRet: ;" & tnl)
if p.beforeRetNeeded: appf(generatedProc, "BeforeRet: $n;")
if optStackTrace in prc.options: app(generatedProc, deinitFrame(p))
if (optProfiler in prc.options) and (gCmd != cmdCompileToLLVM):
appf(generatedProc,
"profileData[$1].total += elapsed(getticks(), NIM_profilingStart);$n",
[toRope(prc.loc.a)])
app(generatedProc, returnStmt)
app(generatedProc, '}' & tnl)
appf(generatedProc, "}$n")
app(m.s[cfsProcs], generatedProc)
proc genProcPrototype(m: BModule, sym: PSym) =
@@ -667,8 +694,8 @@ proc genProcNoForward(m: BModule, prc: PSym) =
if lfImportCompilerProc in prc.loc.flags:
# dependency to a compilerproc:
discard cgsym(m, prc.name.s)
return
genProcPrototype(m, prc)
return
genProcPrototype(m, prc)
if lfNoDecl in prc.loc.Flags: nil
elif prc.typ.callConv == ccInline:
# We add inline procs to the calling module to enable C based inlining.
@@ -854,7 +881,7 @@ proc genInitCode(m: BModule) =
app(prc, m.initProc.s[cpsStmts])
if optStackTrace in m.initProc.options and not m.PreventStackTrace:
app(prc, deinitFrame(m.initProc))
app(prc, '}' & tnl & tnl)
appf(prc, "}$n$n")
app(m.s[cfsProcs], prc)
proc genModule(m: BModule, cfilenoext: string): PRope =

View File

@@ -414,7 +414,7 @@ proc UnknownLineInfo*(): TLineInfo =
result.fileIndex = -1
var
filenames: seq[string] = @[]
filenames: seq[tuple[filename: string, fullpath: string]] = @[]
msgContext: seq[TLineInfo] = @[]
proc pushInfoContext*(info: TLineInfo) =
@@ -425,10 +425,16 @@ proc popInfoContext*() =
proc includeFilename*(f: string): int =
for i in countdown(high(filenames), low(filenames)):
if filenames[i] == f:
if filenames[i].filename == f:
return i
result = len(filenames)
filenames.add(f)
var fullpath: string
try: fullpath = expandFilename(f)
except: fullpath = ""
filenames.add((filename: f, fullpath: fullpath))
proc newLineInfo*(filename: string, line, col: int): TLineInfo =
result.fileIndex = includeFilename(filename)
@@ -437,7 +443,11 @@ proc newLineInfo*(filename: string, line, col: int): TLineInfo =
proc ToFilename*(info: TLineInfo): string =
if info.fileIndex < 0: result = "???"
else: result = filenames[info.fileIndex]
else: result = filenames[info.fileIndex].filename
proc toFullPath*(info: TLineInfo): string =
if info.fileIndex < 0: result = "???"
else: result = filenames[info.fileIndex].fullpath
proc ToLinenumber*(info: TLineInfo): int {.inline.} =
result = info.line

View File

@@ -66,7 +66,8 @@ proc HandleCmdLine() =
var filename = ""
ProcessCmdLine(passCmd1, command, filename)
if filename != "":
var p = splitFile(filename)
var fullPath = expandFilename(filename)
var p = splitFile(fullPath)
options.projectPath = p.dir
options.projectName = p.name
nimconf.LoadConfig(filename) # load the right config file

View File

@@ -59,7 +59,7 @@
#
import
msgs, strutils, platform, hashes, crc
msgs, strutils, platform, hashes, crc, options
const
CacheLeafs* = true
@@ -319,7 +319,10 @@ proc ropef(frmt: TFormatStr, args: openarray[PRope]): PRope =
if j > high(args) + 1:
internalError("ropes: invalid format string $" & $(j))
app(result, args[j - 1])
of 'N', 'n':
of 'n':
if not (optLineDir in gOptions): app(result, tnl)
inc i
of 'N':
app(result, tnl)
inc(i)
else: InternalError("ropes: invalid format string $" & frmt[i])

View File

@@ -74,7 +74,8 @@ icc.options.linker = "-cxxlib"
@if windows:
gcc.path = r"$nimrod\dist\mingw\bin"
@end
gcc.options.debug = "-g"
gcc.options.debug = "-g3 -O0"
@if macosx:
@if not release:
gcc.options.always = "-w -fasm-blocks -O1"