Less ropes (#10979)
* convert ropecg to a macro * fewer intermediate ropes
This commit is contained in:
parent
9f94199d0c
commit
1da98b1636
7 changed files with 451 additions and 349 deletions
|
|
@ -44,8 +44,19 @@ proc inExceptBlockLen(p: BProc): int =
|
|||
for x in p.nestedTryStmts:
|
||||
if x.inExcept: result.inc
|
||||
|
||||
proc startBlock(p: BProc, start: FormatStr = "{$n",
|
||||
args: varargs[Rope]): int {.discardable.}
|
||||
proc startBlockInternal(p: BProc): int {.discardable.} =
|
||||
inc(p.labels)
|
||||
result = len(p.blocks)
|
||||
setLen(p.blocks, result + 1)
|
||||
p.blocks[result].id = p.labels
|
||||
p.blocks[result].nestedTryStmts = p.nestedTryStmts.len.int16
|
||||
p.blocks[result].nestedExceptStmts = p.inExceptBlockLen.int16
|
||||
|
||||
template startBlock(p: BProc, start: FormatStr = "{$n",
|
||||
args: varargs[Rope]): int =
|
||||
lineCg(p, cpsStmts, start, args)
|
||||
startBlockInternal(p)
|
||||
|
||||
proc endBlock(p: BProc)
|
||||
|
||||
proc genVarTuple(p: BProc, n: PNode) =
|
||||
|
|
@ -70,7 +81,7 @@ proc genVarTuple(p: BProc, n: PNode) =
|
|||
|
||||
if forHcr:
|
||||
# check with the boolean if the initializing code for the tuple should be ran
|
||||
lineCg(p, cpsStmts, "if ($1)$n", hcrCond)
|
||||
lineCg(p, cpsStmts, "if ($1)$n", [hcrCond])
|
||||
startBlock(p)
|
||||
defer:
|
||||
if forHcr:
|
||||
|
|
@ -80,10 +91,10 @@ proc genVarTuple(p: BProc, n: PNode) =
|
|||
# insert the registration of the globals for the different parts of the tuple at the
|
||||
# start of the current scope (after they have been iterated) and init a boolean to
|
||||
# check if any of them is newly introduced and the initializing code has to be ran
|
||||
lineCg(p, cpsLocals, "NIM_BOOL $1 = NIM_FALSE;$n", hcrCond)
|
||||
lineCg(p, cpsLocals, "NIM_BOOL $1 = NIM_FALSE;$n", [hcrCond])
|
||||
for curr in hcrGlobals:
|
||||
lineCg(p, cpsLocals, "$1 |= hcrRegisterGlobal($4, \"$2\", sizeof($3), $5, (void**)&$2);$N",
|
||||
hcrCond, curr.loc.r, rdLoc(curr.loc), getModuleDllPath(p.module, n.sons[0].sym), curr.tp)
|
||||
[hcrCond, curr.loc.r, rdLoc(curr.loc), getModuleDllPath(p.module, n.sons[0].sym), curr.tp])
|
||||
|
||||
genLineDir(p, n)
|
||||
initLocExpr(p, n.sons[L-1], tup)
|
||||
|
|
@ -130,16 +141,6 @@ proc loadInto(p: BProc, le, ri: PNode, a: var TLoc) {.inline.} =
|
|||
else:
|
||||
expr(p, ri, a)
|
||||
|
||||
proc startBlock(p: BProc, start: FormatStr = "{$n",
|
||||
args: varargs[Rope]): int {.discardable.} =
|
||||
lineCg(p, cpsStmts, start, args)
|
||||
inc(p.labels)
|
||||
result = len(p.blocks)
|
||||
setLen(p.blocks, result + 1)
|
||||
p.blocks[result].id = p.labels
|
||||
p.blocks[result].nestedTryStmts = p.nestedTryStmts.len.int16
|
||||
p.blocks[result].nestedExceptStmts = p.inExceptBlockLen.int16
|
||||
|
||||
proc assignLabel(b: var TBlock): Rope {.inline.} =
|
||||
b.label = "LA" & b.id.rope
|
||||
result = b.label
|
||||
|
|
@ -192,9 +193,9 @@ proc genState(p: BProc, n: PNode) =
|
|||
let n0 = n[0]
|
||||
if n0.kind == nkIntLit:
|
||||
let idx = n.sons[0].intVal
|
||||
linefmt(p, cpsStmts, "STATE$1: ;$n", idx.rope)
|
||||
linefmt(p, cpsStmts, "STATE$1: ;$n", [idx])
|
||||
elif n0.kind == nkStrLit:
|
||||
linefmt(p, cpsStmts, "$1: ;$n", n0.strVal.rope)
|
||||
linefmt(p, cpsStmts, "$1: ;$n", [n0.strVal])
|
||||
|
||||
proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
|
||||
# Called by return and break stmts.
|
||||
|
|
@ -207,7 +208,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
|
|||
if not p.module.compileToCpp or optNoCppExceptions in p.config.globalOptions:
|
||||
# Pop safe points generated by try
|
||||
if not tryStmt.inExcept and not isDefined(p.config, "nimQuirky"):
|
||||
linefmt(p, cpsStmts, "#popSafePoint();$n")
|
||||
linefmt(p, cpsStmts, "#popSafePoint();$n", [])
|
||||
|
||||
# Pop this try-stmt of the list of nested trys
|
||||
# so we don't infinite recurse on it in the next step.
|
||||
|
|
@ -227,7 +228,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
|
|||
# Pop exceptions that was handled by the
|
||||
# except-blocks we are in
|
||||
for i in countdown(howManyExcepts-1, 0):
|
||||
linefmt(p, cpsStmts, "#popCurrentException();$n")
|
||||
linefmt(p, cpsStmts, "#popCurrentException();$n", [])
|
||||
|
||||
proc genGotoState(p: BProc, n: PNode) =
|
||||
# we resist the temptation to translate it into duff's device as it later
|
||||
|
|
@ -352,7 +353,7 @@ proc genSingleVar(p: BProc, a: PNode) =
|
|||
# put it in the locals section - mainly because of loops which
|
||||
# use the var in a call to resetLoc() in the statements section
|
||||
lineCg(targetProc, cpsLocals, "hcrRegisterGlobal($3, \"$1\", sizeof($2), $4, (void**)&$1);$n",
|
||||
v.loc.r, rdLoc(v.loc), getModuleDllPath(p.module, v), traverseProc)
|
||||
[v.loc.r, rdLoc(v.loc), getModuleDllPath(p.module, v), traverseProc])
|
||||
# nothing special left to do later on - let's avoid closing and reopening blocks
|
||||
forHcr = false
|
||||
|
||||
|
|
@ -361,7 +362,7 @@ proc genSingleVar(p: BProc, a: PNode) =
|
|||
# be able to re-run it but without the top level code - just the init of globals
|
||||
if forHcr:
|
||||
lineCg(targetProc, cpsStmts, "if (hcrRegisterGlobal($3, \"$1\", sizeof($2), $4, (void**)&$1))$N",
|
||||
v.loc.r, rdLoc(v.loc), getModuleDllPath(p.module, v), traverseProc)
|
||||
[v.loc.r, rdLoc(v.loc), getModuleDllPath(p.module, v), traverseProc])
|
||||
startBlock(targetProc)
|
||||
defer:
|
||||
if forHcr:
|
||||
|
|
@ -452,7 +453,7 @@ proc genReturnStmt(p: BProc, t: PNode) =
|
|||
# If we're in a finally block, and we came here by exception
|
||||
# consume it before we return.
|
||||
var safePoint = p.finallySafePoints[p.finallySafePoints.len-1]
|
||||
linefmt(p, cpsStmts, "if ($1.status != 0) #popCurrentException();$n", safePoint)
|
||||
linefmt(p, cpsStmts, "if ($1.status != 0) #popCurrentException();$n", [safePoint])
|
||||
lineF(p, cpsStmts, "goto BeforeRet_;$n", [])
|
||||
|
||||
proc genGotoForCase(p: BProc; caseStmt: PNode) =
|
||||
|
|
@ -589,7 +590,7 @@ proc genWhileStmt(p: BProc, t: PNode) =
|
|||
|
||||
if optProfiler in p.options:
|
||||
# invoke at loop body exit:
|
||||
linefmt(p, cpsStmts, "#nimProfile();$n")
|
||||
linefmt(p, cpsStmts, "#nimProfile();$n", [])
|
||||
endBlock(p)
|
||||
|
||||
dec(p.withinLoop)
|
||||
|
|
@ -690,7 +691,7 @@ proc genRaiseStmt(p: BProc, t: PNode) =
|
|||
lineCg(p, cpsStmts, "#raiseExceptionEx((#Exception*)$1, $2, $3, $4, $5);$n",
|
||||
[e, makeCString(typ.sym.name.s),
|
||||
makeCString(if p.prc != nil: p.prc.name.s else: p.module.module.name.s),
|
||||
makeCString(toFileName(p.config, t.info)), rope(toLinenumber(t.info))])
|
||||
makeCString(toFileName(p.config, t.info)), toLinenumber(t.info)])
|
||||
if optNimV2 in p.config.globalOptions:
|
||||
lineCg(p, cpsStmts, "$1 = NIM_NIL;$n", [e])
|
||||
else:
|
||||
|
|
@ -699,9 +700,9 @@ proc genRaiseStmt(p: BProc, t: PNode) =
|
|||
if p.module.compileToCpp and optNoCppExceptions notin p.config.globalOptions:
|
||||
line(p, cpsStmts, ~"throw;$n")
|
||||
else:
|
||||
linefmt(p, cpsStmts, "#reraiseException();$n")
|
||||
linefmt(p, cpsStmts, "#reraiseException();$n", [])
|
||||
|
||||
proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
|
||||
template genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
|
||||
rangeFormat, eqFormat: FormatStr, labl: TLabel) =
|
||||
var
|
||||
x, y: TLoc
|
||||
|
|
@ -731,10 +732,11 @@ proc genCaseSecondPass(p: BProc, t: PNode, d: var TLoc,
|
|||
exprBlock(p, t.sons[i].sons[0], d)
|
||||
result = lend
|
||||
|
||||
proc genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc,
|
||||
template genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc,
|
||||
rangeFormat, eqFormat: FormatStr,
|
||||
until: int, a: TLoc): TLabel =
|
||||
# generate a C-if statement for a Nim case statement
|
||||
var res: TLabel
|
||||
var labId = p.labels
|
||||
for i in 1..until:
|
||||
inc(p.labels)
|
||||
|
|
@ -747,12 +749,13 @@ proc genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc,
|
|||
inc(p.labels)
|
||||
var gotoTarget = p.labels
|
||||
lineF(p, cpsStmts, "goto LA$1_;$n", [rope(gotoTarget)])
|
||||
result = genCaseSecondPass(p, t, d, labId, until)
|
||||
res = genCaseSecondPass(p, t, d, labId, until)
|
||||
lineF(p, cpsStmts, "LA$1_: ;$n", [rope(gotoTarget)])
|
||||
else:
|
||||
result = genCaseSecondPass(p, t, d, labId, until)
|
||||
res = genCaseSecondPass(p, t, d, labId, until)
|
||||
res
|
||||
|
||||
proc genCaseGeneric(p: BProc, t: PNode, d: var TLoc,
|
||||
template genCaseGeneric(p: BProc, t: PNode, d: var TLoc,
|
||||
rangeFormat, eqFormat: FormatStr) =
|
||||
var a: TLoc
|
||||
initLocExpr(p, t.sons[0], a)
|
||||
|
|
@ -793,7 +796,7 @@ proc genStringCase(p: BProc, t: PNode, d: var TLoc) =
|
|||
# but we reserved a label, which we use later
|
||||
discard
|
||||
linefmt(p, cpsStmts, "switch (#hashString($1) & $2) {$n",
|
||||
rdLoc(a), rope(bitMask))
|
||||
[rdLoc(a), bitMask])
|
||||
for j in countup(0, high(branches)):
|
||||
if branches[j] != nil:
|
||||
lineF(p, cpsStmts, "case $1: $n$2break;$n",
|
||||
|
|
@ -895,7 +898,7 @@ proc genRestoreFrameAfterException(p: BProc) =
|
|||
p.hasCurFramePointer = true
|
||||
p.procSec(cpsLocals).add(ropecg(p.module, "\tTFrame* _nimCurFrame;$n", []))
|
||||
p.procSec(cpsInit).add(ropecg(p.module, "\t_nimCurFrame = #getFrame();$n", []))
|
||||
linefmt(p, cpsStmts, "#setFrame(_nimCurFrame);$n")
|
||||
linefmt(p, cpsStmts, "#setFrame(_nimCurFrame);$n", [])
|
||||
|
||||
proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
||||
# code to generate:
|
||||
|
|
@ -1006,25 +1009,25 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
|||
var safePoint: Rope
|
||||
if not quirkyExceptions:
|
||||
safePoint = getTempName(p.module)
|
||||
linefmt(p, cpsLocals, "#TSafePoint $1;$n", safePoint)
|
||||
linefmt(p, cpsStmts, "#pushSafePoint(&$1);$n", safePoint)
|
||||
linefmt(p, cpsLocals, "#TSafePoint $1;$n", [safePoint])
|
||||
linefmt(p, cpsStmts, "#pushSafePoint(&$1);$n", [safePoint])
|
||||
if isDefined(p.config, "nimStdSetjmp"):
|
||||
linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint)
|
||||
linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", [safePoint])
|
||||
elif isDefined(p.config, "nimSigSetjmp"):
|
||||
linefmt(p, cpsStmts, "$1.status = sigsetjmp($1.context, 0);$n", safePoint)
|
||||
linefmt(p, cpsStmts, "$1.status = sigsetjmp($1.context, 0);$n", [safePoint])
|
||||
elif isDefined(p.config, "nimRawSetjmp"):
|
||||
linefmt(p, cpsStmts, "$1.status = _setjmp($1.context);$n", safePoint)
|
||||
linefmt(p, cpsStmts, "$1.status = _setjmp($1.context);$n", [safePoint])
|
||||
else:
|
||||
linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint)
|
||||
linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", [safePoint])
|
||||
startBlock(p, "if ($1.status == 0) {$n", [safePoint])
|
||||
var length = sonsLen(t)
|
||||
add(p.nestedTryStmts, (t, false))
|
||||
expr(p, t.sons[0], d)
|
||||
if not quirkyExceptions:
|
||||
linefmt(p, cpsStmts, "#popSafePoint();$n")
|
||||
linefmt(p, cpsStmts, "#popSafePoint();$n", [])
|
||||
endBlock(p)
|
||||
startBlock(p, "else {$n")
|
||||
linefmt(p, cpsStmts, "#popSafePoint();$n")
|
||||
linefmt(p, cpsStmts, "#popSafePoint();$n", [])
|
||||
genRestoreFrameAfterException(p)
|
||||
elif 1 < length and t.sons[1].kind == nkExceptBranch:
|
||||
startBlock(p, "if (#getCurrentException()) {$n")
|
||||
|
|
@ -1041,30 +1044,28 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
|||
if i > 1: lineF(p, cpsStmts, "else", [])
|
||||
startBlock(p)
|
||||
if not quirkyExceptions:
|
||||
linefmt(p, cpsStmts, "$1.status = 0;$n", safePoint)
|
||||
linefmt(p, cpsStmts, "$1.status = 0;$n", [safePoint])
|
||||
expr(p, t.sons[i].sons[0], d)
|
||||
linefmt(p, cpsStmts, "#popCurrentException();$n")
|
||||
linefmt(p, cpsStmts, "#popCurrentException();$n", [])
|
||||
endBlock(p)
|
||||
else:
|
||||
var orExpr: Rope = nil
|
||||
for j in countup(0, blen - 2):
|
||||
assert(t.sons[i].sons[j].kind == nkType)
|
||||
if orExpr != nil: add(orExpr, "||")
|
||||
let isObjFormat = if not p.module.compileToCpp:
|
||||
"#isObj(#getCurrentException()->Sup.m_type, $1)"
|
||||
else: "#isObj(#getCurrentException()->m_type, $1)"
|
||||
|
||||
let checkFor = if optNimV2 in p.config.globalOptions:
|
||||
genTypeInfo2Name(p.module, t[i][j].typ)
|
||||
else:
|
||||
genTypeInfo(p.module, t[i][j].typ, t[i][j].info)
|
||||
appcg(p.module, orExpr, isObjFormat, [checkFor])
|
||||
let memberName = if p.module.compileToCpp: "m_type" else: "Sup.m_type"
|
||||
appcg(p.module, orExpr, "#isObj(#getCurrentException()->$1, $2)", [memberName, checkFor])
|
||||
|
||||
if i > 1: line(p, cpsStmts, "else ")
|
||||
startBlock(p, "if ($1) {$n", [orExpr])
|
||||
if not quirkyExceptions:
|
||||
linefmt(p, cpsStmts, "$1.status = 0;$n", safePoint)
|
||||
linefmt(p, cpsStmts, "$1.status = 0;$n", [safePoint])
|
||||
expr(p, t.sons[i].sons[blen-1], d)
|
||||
linefmt(p, cpsStmts, "#popCurrentException();$n")
|
||||
linefmt(p, cpsStmts, "#popCurrentException();$n", [])
|
||||
endBlock(p)
|
||||
inc(i)
|
||||
discard pop(p.nestedTryStmts)
|
||||
|
|
@ -1074,7 +1075,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
|||
genSimpleBlock(p, t.sons[i].sons[0])
|
||||
discard pop(p.finallySafePoints)
|
||||
if not quirkyExceptions:
|
||||
linefmt(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", safePoint)
|
||||
linefmt(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", [safePoint])
|
||||
|
||||
proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): Rope =
|
||||
var res = ""
|
||||
|
|
@ -1169,7 +1170,7 @@ proc genBreakPoint(p: BProc, t: PNode) =
|
|||
genLineDir(p, t) # BUGFIX
|
||||
appcg(p.module, p.module.g.breakpoints,
|
||||
"#dbgRegisterBreakpoint($1, (NCSTRING)$2, (NCSTRING)$3);$n", [
|
||||
rope(toLinenumber(t.info)), makeCString(toFilename(p.config, t.info)),
|
||||
toLinenumber(t.info), makeCString(toFilename(p.config, t.info)),
|
||||
makeCString(name)])
|
||||
|
||||
proc genWatchpoint(p: BProc, n: PNode) =
|
||||
|
|
@ -1212,7 +1213,7 @@ proc genDiscriminantCheck(p: BProc, a, tmp: TLoc, objtype: PType,
|
|||
var L = lengthOrd(p.config, field.typ)
|
||||
if not containsOrIncl(p.module.declaredThings, field.id):
|
||||
appcg(p.module, cfsVars, "extern $1",
|
||||
discriminatorTableDecl(p.module, t, field))
|
||||
[discriminatorTableDecl(p.module, t, field)])
|
||||
lineCg(p, cpsStmts,
|
||||
"#FieldDiscriminantCheck((NI)(NU)($1), (NI)(NU)($2), $3, $4);$n",
|
||||
[rdLoc(a), rdLoc(tmp), discriminatorTableName(p.module, t, field),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue