Merge branch 'master' of github.com:Araq/Nimrod

This commit is contained in:
Araq 2012-06-19 22:38:48 +02:00
commit e0092cfae6
54 changed files with 1980 additions and 1251 deletions

View file

@ -153,6 +153,34 @@ proc appcg(p: BProc, s: TCProcSection, frmt: TFormatStr,
args: openarray[PRope]) =
app(p.s(s), ropecg(p.module, frmt, args))
var indent = "\t".toRope
proc indentLine(p: BProc, r: PRope): PRope =
result = r
for i in countup(0, p.blocks.len-1): prepend(result, indent)
proc line(p: BProc, s: TCProcSection, r: PRope) =
app(p.s(s), indentLine(p, r))
proc line(p: BProc, s: TCProcSection, r: string) =
app(p.s(s), indentLine(p, r.toRope))
proc lineF(p: BProc, s: TCProcSection, frmt: TFormatStr,
args: openarray[PRope]) =
app(p.s(s), indentLine(p, ropef(frmt, args)))
proc lineCg(p: BProc, s: TCProcSection, frmt: TFormatStr,
args: openarray[PRope]) =
app(p.s(s), indentLine(p, ropecg(p.module, frmt, args)))
proc appLineCg(p: BProc, r: var PRope, frmt: TFormatStr,
args: openarray[PRope]) =
app(r, indentLine(p, ropecg(p.module, frmt, args)))
proc lineFF(p: BProc, s: TCProcSection, cformat, llvmformat: string,
args: openarray[PRope]) =
if gCmd == cmdCompileToLLVM: lineF(p, s, llvmformat, args)
else: lineF(p, s, cformat, args)
proc safeLineNm(info: TLineInfo): int =
result = toLinenumber(info)
if result < 0: result = 0 # negative numbers are not allowed in #line
@ -171,11 +199,11 @@ proc genLineDir(p: BProc, t: PNode) =
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)])
lineCg(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",
lineF(p, cpsStmts, "F.line = $1;F.filename = $2;$n",
[toRope(line), makeCString(toFilename(t.info).extractFilename)])
include "ccgtypes.nim"
@ -211,11 +239,11 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
while (s.kind == tyObject) and (s.sons[0] != nil):
app(r, ".Sup")
s = skipTypes(s.sons[0], abstractInst)
appcg(p, section, "$1.m_type = $2;$n", [r, genTypeInfo(p.module, t)])
lineCg(p, section, "$1.m_type = $2;$n", [r, genTypeInfo(p.module, t)])
of frEmbedded:
# worst case for performance:
var r = if takeAddr: addrLoc(a) else: rdLoc(a)
appcg(p, section, "#objectInit($1, $2);$n", [r, genTypeInfo(p.module, t)])
lineCg(p, section, "#objectInit($1, $2);$n", [r, genTypeInfo(p.module, t)])
type
TAssignmentFlag = enum
@ -238,16 +266,16 @@ proc resetLoc(p: BProc, loc: var TLoc) =
nilLoc.r = toRope("NIM_NIL")
genRefAssign(p, loc, nilLoc, {afSrcIsNil})
else:
appf(p.s(cpsStmts), "$1 = 0;$n", [rdLoc(loc)])
lineF(p, cpsStmts, "$1 = 0;$n", [rdLoc(loc)])
else:
if loc.s != OnStack:
appcg(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
lineCg(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
[addrLoc(loc), genTypeInfo(p.module, loc.t)])
# XXX: generated reset procs should not touch the m_type
# field, so disabling this should be safe:
genObjectInit(p, cpsStmts, loc.t, loc, true)
else:
appf(p.s(cpsStmts), "memset((void*)$1, 0, sizeof($2));$n",
lineF(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n",
[addrLoc(loc), rdLoc(loc)])
# XXX: We can be extra clever here and call memset only
# on the bytes following the m_type field?
@ -255,9 +283,9 @@ proc resetLoc(p: BProc, loc: var TLoc) =
proc constructLoc(p: BProc, loc: TLoc, section = cpsStmts) =
if not isComplexValueType(skipTypes(loc.t, abstractVarRange)):
appf(p.s(section), "$1 = 0;$n", [rdLoc(loc)])
lineF(p, section, "$1 = 0;$n", [rdLoc(loc)])
else:
appf(p.s(section), "memset((void*)$1, 0, sizeof($2));$n",
lineF(p, section, "memset((void*)$1, 0, sizeof($2));$n",
[addrLoc(loc), rdLoc(loc)])
genObjectInit(p, section, loc.t, loc, true)
@ -285,7 +313,7 @@ proc getTemp(p: BProc, t: PType, result: var TLoc) =
result.r = con("%LOC", toRope(p.labels))
else:
result.r = con("LOC", toRope(p.labels))
appf(p.s(cpsLocals), "$1 $2;$n", [getTypeDesc(p.module, t), result.r])
lineF(p, cpsLocals, "$1 $2;$n", [getTypeDesc(p.module, t), result.r])
result.k = locTemp
result.a = - 1
result.t = getUniqueType(t)
@ -311,9 +339,9 @@ proc keepAlive(p: BProc, toKeepAlive: TLoc) =
result.flags = {}
if not isComplexValueType(skipTypes(toKeepAlive.t, abstractVarRange)):
appf(p.s[cpsStmts], "$1 = $2;$n", [rdLoc(result), rdLoc(toKeepAlive)])
lineF(p, cpsStmts, "$1 = $2;$n", [rdLoc(result), rdLoc(toKeepAlive)])
else:
appcg(p, cpsStmts,
lineCg(p, cpsStmts,
"memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
[addrLoc(result), addrLoc(toKeepAlive), rdLoc(result)])
@ -355,7 +383,7 @@ proc allocParam(p: BProc, s: PSym) =
var tmp = con("%LOC", toRope(p.labels))
incl(s.loc.flags, lfParamCopy)
incl(s.loc.flags, lfIndirect)
appf(p.s(cpsInit), "$1 = alloca $3$n" & "store $3 $2, $3* $1$n",
lineF(p, cpsInit, "$1 = alloca $3$n" & "store $3 $2, $3* $1$n",
[tmp, s.loc.r, getTypeDesc(p.module, s.loc.t)])
s.loc.r = tmp
@ -365,7 +393,7 @@ proc localDebugInfo(p: BProc, s: PSym) =
if skipTypes(s.typ, abstractVar).kind == tyOpenArray: return
var a = con("&", s.loc.r)
if (s.kind == skParam) and ccgIntroducedPtr(s): a = s.loc.r
appf(p.s(cpsInit),
lineF(p, cpsInit,
"F.s[$1].address = (void*)$3; F.s[$1].typ = $4; F.s[$1].name = $2;$n",
[toRope(p.frameLen), makeCString(normalize(s.name.s)), a,
genTypeInfo(p.module, s.loc.t)])
@ -378,13 +406,14 @@ proc assignLocalVar(p: BProc, s: PSym) =
if s.loc.k == locNone:
fillLoc(s.loc, locLocalVar, s.typ, mangleName(s), OnStack)
if s.kind == skLet: incl(s.loc.flags, lfNoDeepCopy)
app(p.s(cpsLocals), getTypeDesc(p.module, s.loc.t))
if sfRegister in s.flags: app(p.s(cpsLocals), " register")
var decl = getTypeDesc(p.module, s.loc.t)
if sfRegister in s.flags: app(decl, " register")
#elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds:
# app(p.s[cpsLocals], " GC_GUARD")
# app(decl, " GC_GUARD")
if (sfVolatile in s.flags) or (p.nestedTryStmts.len > 0):
app(p.s(cpsLocals), " volatile")
appf(p.s(cpsLocals), " $1;$n", [s.loc.r])
app(decl, " volatile")
appf(decl, " $1;$n", [s.loc.r])
line(p, cpsLocals, decl)
localDebugInfo(p, s)
include ccgthreadvars
@ -427,7 +456,7 @@ proc getLabel(p: BProc): TLabel =
result = con("LA", toRope(p.labels))
proc fixLabel(p: BProc, labl: TLabel) =
appf(p.s(cpsStmts), "$1: ;$n", [labl])
lineF(p, cpsStmts, "$1: ;$n", [labl])
proc genVarPrototype(m: BModule, sym: PSym)
proc requestConstImpl(p: BProc, sym: PSym)
@ -545,28 +574,28 @@ proc getFrameDecl(p: BProc) =
[toRope(p.frameLen)])
else:
slots = nil
appff(p.s(cpsLocals), "volatile struct {TFrame* prev;" &
"NCSTRING procname;NI line;NCSTRING filename;" &
"NI len;$n$1} F;$n",
lineFF(p, cpsLocals, "volatile struct {TFrame* prev;" &
"NCSTRING procname;NI line;NCSTRING filename;" &
"NI len;$1} F;$n",
"%TF = type {%TFrame*, i8*, %NI, %NI$1}$n" &
"%F = alloca %TF$n", [slots])
inc(p.labels)
prepend(p.s(cpsInit), ropeff("F.len = $1;$n",
prepend(p.s(cpsInit), indentLine(p, ropeff("F.len = $1;$n",
"%LOC$2 = getelementptr %TF %F, %NI 4$n" &
"store %NI $1, %NI* %LOC$2$n", [toRope(p.frameLen), toRope(p.labels)]))
"store %NI $1, %NI* %LOC$2$n", [toRope(p.frameLen), toRope(p.labels)])))
proc retIsNotVoid(s: PSym): bool =
result = (s.typ.sons[0] != nil) and not isInvalidReturnType(s.typ.sons[0])
proc initFrame(p: BProc, procname, filename: PRope): PRope =
result = ropecg(p.module,
"F.procname = $1;$n" &
"F.filename = $2;$n" &
"F.line = 0;$n" &
"#pushFrame((TFrame*)&F);$n", [procname, filename])
"\tF.procname = $1;$n" &
"\tF.filename = $2;$n" &
"\tF.line = 0;$n" &
"\t#pushFrame((TFrame*)&F);$n", [procname, filename])
proc deinitFrame(p: BProc): PRope =
result = ropecg(p.module, "#popFrame();$n")
result = ropecg(p.module, "\t#popFrame();$n")
proc closureSetup(p: BProc, prc: PSym) =
if prc.typ.callConv != ccClosure: return
@ -578,8 +607,8 @@ proc closureSetup(p: BProc, prc: PSym) =
#echo "created environment: ", env.id, " for ", prc.name.s
assignLocalVar(p, env)
# generate cast assignment:
appcg(p, cpsStmts, "$1 = ($2) ClEnv;$n", rdLoc(env.loc),
getTypeDesc(p.module, env.typ))
lineCg(p, cpsStmts, "$1 = ($2) ClEnv;$n", rdLoc(env.loc),
getTypeDesc(p.module, env.typ))
proc genProcAux(m: BModule, prc: PSym) =
var p = newProc(prc, m)
@ -593,7 +622,7 @@ proc genProcAux(m: BModule, prc: PSym) =
# declare the result symbol:
assignLocalVar(p, res)
assert(res.loc.r != nil)
returnStmt = ropeff("return $1;$n", "ret $1$n", [rdLoc(res.loc)])
returnStmt = ropeff("\treturn $1;$n", "ret $1$n", [rdLoc(res.loc)])
initLocalVar(p, res, immediateAsgn=false)
else:
fillResult(res)
@ -609,10 +638,10 @@ proc genProcAux(m: BModule, prc: PSym) =
genStmts(p, prc.getBody) # modifies p.locals, p.init, etc.
var generatedProc: PRope
if sfPure in prc.flags:
generatedProc = ropeff("$1 {$n$2$3$4}$n", "define $1 {$n$2$3$4}$n",
generatedProc = ropeff("$N$1 {$n$2$3$4}$N$N", "define $1 {$n$2$3$4}$N",
[header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)])
else:
generatedProc = ropeff("$1 {$n", "define $1 {$n", [header])
generatedProc = ropeff("$N$1 {$N", "$Ndefine $1 {$N", [header])
app(generatedProc, initGCFrame(p))
if optStackTrace in prc.options:
getFrameDecl(p)
@ -626,25 +655,25 @@ proc genProcAux(m: BModule, prc: PSym) =
if gProcProfile >= 64 * 1024:
InternalError(prc.info, "too many procedures for profiling")
discard cgsym(m, "profileData")
appf(p.s(cpsLocals), "ticks NIM_profilingStart;$n")
appf(p.s(cpsLocals), "\tticks NIM_profilingStart;$n")
if prc.loc.a < 0:
appf(m.s[cfsDebugInit], "profileData[$1].procname = $2;$n", [
appf(m.s[cfsDebugInit], "\tprofileData[$1].procname = $2;$n", [
toRope(gProcProfile),
makeCString(prc.name.s)])
prc.loc.a = gProcProfile
inc(gProcProfile)
prepend(p.s(cpsInit), ropef("NIM_profilingStart = getticks();$n"))
prepend(p.s(cpsInit), ropef("\tNIM_profilingStart = getticks();$n"))
app(generatedProc, p.s(cpsInit))
app(generatedProc, p.s(cpsStmts))
if p.beforeRetNeeded: appf(generatedProc, "BeforeRet: $n;")
if p.beforeRetNeeded: appf(generatedProc, "\tBeforeRet: ;$n")
app(generatedProc, deinitGCFrame(p))
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",
"\tprofileData[$1].total += elapsed(getticks(), NIM_profilingStart);$n",
[toRope(prc.loc.a)])
app(generatedProc, returnStmt)
appf(generatedProc, "}$n")
appf(generatedProc, "}$N")
app(m.s[cfsProcs], generatedProc)
proc genProcPrototype(m: BModule, sym: PSym) =