Cosmetic compiler cleanup (#12718)
* Cleanup compiler code base
* Unify add calls
* Unify len invocations
* Unify range operators
* Fix oversight
* Remove {.procvar.} pragma
* initCandidate -> newCandidate where reasonable
* Unify safeLen calls
This commit is contained in:
parent
b662842bd0
commit
7e747d11c6
109 changed files with 6115 additions and 6254 deletions
|
|
@ -46,7 +46,7 @@ proc inExceptBlockLen(p: BProc): int =
|
|||
|
||||
proc startBlockInternal(p: BProc): int {.discardable.} =
|
||||
inc(p.labels)
|
||||
result = len(p.blocks)
|
||||
result = p.blocks.len
|
||||
setLen(p.blocks, result + 1)
|
||||
p.blocks[result].id = p.labels
|
||||
p.blocks[result].nestedTryStmts = p.nestedTryStmts.len.int16
|
||||
|
|
@ -62,16 +62,15 @@ proc endBlock(p: BProc)
|
|||
proc genVarTuple(p: BProc, n: PNode) =
|
||||
var tup, field: TLoc
|
||||
if n.kind != nkVarTuple: internalError(p.config, n.info, "genVarTuple")
|
||||
var L = len(n)
|
||||
|
||||
# if we have a something that's been captured, use the lowering instead:
|
||||
for i in 0 .. L-3:
|
||||
for i in 0..<n.len-2:
|
||||
if n[i].kind != nkSym:
|
||||
genStmts(p, lowerTupleUnpacking(p.module.g.graph, n, p.prc))
|
||||
return
|
||||
|
||||
# check only the first son
|
||||
var forHcr = treatGlobalDifferentlyForHCR(p.module, n.sons[0].sym)
|
||||
var forHcr = treatGlobalDifferentlyForHCR(p.module, n[0].sym)
|
||||
let hcrCond = if forHcr: getTempName(p.module) else: nil
|
||||
var hcrGlobals: seq[tuple[loc: TLoc, tp: Rope]]
|
||||
# determine if the tuple is constructed at top-level scope or inside of a block (if/while/block)
|
||||
|
|
@ -85,10 +84,10 @@ proc genVarTuple(p: BProc, n: PNode) =
|
|||
startBlock(p)
|
||||
|
||||
genLineDir(p, n)
|
||||
initLocExpr(p, n.sons[L-1], tup)
|
||||
initLocExpr(p, n[^1], tup)
|
||||
var t = tup.t.skipTypes(abstractInst)
|
||||
for i in 0 .. L-3:
|
||||
let vn = n.sons[i]
|
||||
for i in 0..<n.len-2:
|
||||
let vn = n[i]
|
||||
let v = vn.sym
|
||||
if sfCompileTime in v.flags: continue
|
||||
var traverseProc: Rope
|
||||
|
|
@ -100,13 +99,13 @@ proc genVarTuple(p: BProc, n: PNode) =
|
|||
registerTraverseProc(p, v, traverseProc)
|
||||
else:
|
||||
assignLocalVar(p, vn)
|
||||
initLocalVar(p, v, immediateAsgn=isAssignedImmediately(p.config, n[L-1]))
|
||||
initLocalVar(p, v, immediateAsgn=isAssignedImmediately(p.config, n[^1]))
|
||||
initLoc(field, locExpr, vn, tup.storage)
|
||||
if t.kind == tyTuple:
|
||||
field.r = "$1.Field$2" % [rdLoc(tup), rope(i)]
|
||||
else:
|
||||
if t.n.sons[i].kind != nkSym: internalError(p.config, n.info, "genVarTuple")
|
||||
field.r = "$1.$2" % [rdLoc(tup), mangleRecFieldName(p.module, t.n.sons[i].sym)]
|
||||
if t.n[i].kind != nkSym: internalError(p.config, n.info, "genVarTuple")
|
||||
field.r = "$1.$2" % [rdLoc(tup), mangleRecFieldName(p.module, t.n[i].sym)]
|
||||
putLocIntoDest(p, v.loc, field)
|
||||
if forHcr or isGlobalInBlock:
|
||||
hcrGlobals.add((loc: v.loc, tp: if traverseProc == nil: ~"NULL" else: traverseProc))
|
||||
|
|
@ -121,12 +120,12 @@ proc genVarTuple(p: BProc, n: PNode) =
|
|||
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[0].sym), curr.tp])
|
||||
|
||||
|
||||
proc loadInto(p: BProc, le, ri: PNode, a: var TLoc) {.inline.} =
|
||||
if ri.kind in nkCallKinds and (ri.sons[0].kind != nkSym or
|
||||
ri.sons[0].sym.magic == mNone):
|
||||
if ri.kind in nkCallKinds and (ri[0].kind != nkSym or
|
||||
ri[0].sym.magic == mNone):
|
||||
genAsgnCall(p, le, ri, a)
|
||||
else:
|
||||
# this is a hacky way to fix #1181 (tmissingderef)::
|
||||
|
|
@ -153,7 +152,7 @@ proc blockBody(b: var TBlock): Rope =
|
|||
proc endBlock(p: BProc, blockEnd: Rope) =
|
||||
let topBlock = p.blocks.len-1
|
||||
# the block is merged into the parent block
|
||||
add(p.blocks[topBlock-1].sections[cpsStmts], p.blocks[topBlock].blockBody)
|
||||
p.blocks[topBlock-1].sections[cpsStmts].add(p.blocks[topBlock].blockBody)
|
||||
setLen(p.blocks, topBlock)
|
||||
# this is done after the block is popped so $n is
|
||||
# properly indented when pretty printing is enabled
|
||||
|
|
@ -190,7 +189,7 @@ proc genState(p: BProc, n: PNode) =
|
|||
internalAssert p.config, n.len == 1
|
||||
let n0 = n[0]
|
||||
if n0.kind == nkIntLit:
|
||||
let idx = n.sons[0].intVal
|
||||
let idx = n[0].intVal
|
||||
linefmt(p, cpsStmts, "STATE$1: ;$n", [idx])
|
||||
elif n0.kind == nkStrLit:
|
||||
linefmt(p, cpsStmts, "$1: ;$n", [n0.strVal])
|
||||
|
|
@ -201,7 +200,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
|
|||
|
||||
var stack = newSeq[tuple[fin: PNode, inExcept: bool]](0)
|
||||
|
||||
for i in 1 .. howManyTrys:
|
||||
for i in 1..howManyTrys:
|
||||
let tryStmt = p.nestedTryStmts.pop
|
||||
if not p.module.compileToCpp or optNoCppExceptions in p.config.globalOptions:
|
||||
# Pop safe points generated by try
|
||||
|
|
@ -236,7 +235,7 @@ proc genGotoState(p: BProc, n: PNode) =
|
|||
# case 0: goto STATE0;
|
||||
# ...
|
||||
var a: TLoc
|
||||
initLocExpr(p, n.sons[0], a)
|
||||
initLocExpr(p, n[0], a)
|
||||
lineF(p, cpsStmts, "switch ($1) {$n", [rdLoc(a)])
|
||||
p.beforeRetNeeded = true
|
||||
lineF(p, cpsStmts, "case -1:$n", [])
|
||||
|
|
@ -244,12 +243,12 @@ proc genGotoState(p: BProc, n: PNode) =
|
|||
howManyTrys = p.nestedTryStmts.len,
|
||||
howManyExcepts = p.inExceptBlockLen)
|
||||
lineF(p, cpsStmts, " goto BeforeRet_;$n", [])
|
||||
var statesCounter = lastOrd(p.config, n.sons[0].typ)
|
||||
var statesCounter = lastOrd(p.config, n[0].typ)
|
||||
if n.len >= 2 and n[1].kind == nkIntLit:
|
||||
statesCounter = getInt(n[1])
|
||||
let prefix = if n.len == 3 and n[2].kind == nkStrLit: n[2].strVal.rope
|
||||
else: rope"STATE"
|
||||
for i in 0i64 .. toInt64(statesCounter):
|
||||
for i in 0i64..toInt64(statesCounter):
|
||||
lineF(p, cpsStmts, "case $2: goto $1$2;$n", [prefix, rope(i)])
|
||||
lineF(p, cpsStmts, "}$n", [])
|
||||
|
||||
|
|
@ -257,11 +256,11 @@ proc genBreakState(p: BProc, n: PNode, d: var TLoc) =
|
|||
var a: TLoc
|
||||
initLoc(d, locExpr, n, OnUnknown)
|
||||
|
||||
if n.sons[0].kind == nkClosure:
|
||||
initLocExpr(p, n.sons[0].sons[1], a)
|
||||
if n[0].kind == nkClosure:
|
||||
initLocExpr(p, n[0][1], a)
|
||||
d.r = "(((NI*) $1)[1] < 0)" % [rdLoc(a)]
|
||||
else:
|
||||
initLocExpr(p, n.sons[0], a)
|
||||
initLocExpr(p, n[0], a)
|
||||
# the environment is guaranteed to contain the 'state' field at offset 1:
|
||||
d.r = "((((NI*) $1.ClE_0)[1]) < 0)" % [rdLoc(a)]
|
||||
|
||||
|
|
@ -322,12 +321,12 @@ proc genSingleVar(p: BProc, v: PSym; vn, value: PNode) =
|
|||
if value.kind in nkCallKinds and value[0].kind == nkSym and
|
||||
sfConstructor in value[0].sym.flags:
|
||||
var params: Rope
|
||||
let typ = skipTypes(value.sons[0].typ, abstractInst)
|
||||
let typ = skipTypes(value[0].typ, abstractInst)
|
||||
assert(typ.kind == tyProc)
|
||||
for i in 1..<value.len:
|
||||
if params != nil: params.add(~", ")
|
||||
assert(len(typ) == len(typ.n))
|
||||
add(params, genOtherArg(p, value, i, typ))
|
||||
assert(typ.len == typ.n.len)
|
||||
params.add(genOtherArg(p, value, i, typ))
|
||||
if params == nil:
|
||||
lineF(p, cpsStmts, "$#;$n", [decl])
|
||||
else:
|
||||
|
|
@ -368,15 +367,15 @@ proc genSingleVar(p: BProc, v: PSym; vn, value: PNode) =
|
|||
proc genSingleVar(p: BProc, a: PNode) =
|
||||
let v = a[0].sym
|
||||
if sfCompileTime in v.flags: return
|
||||
genSingleVar(p, v, a[0], a.sons[2])
|
||||
genSingleVar(p, v, a[0], a[2])
|
||||
|
||||
proc genClosureVar(p: BProc, a: PNode) =
|
||||
var immediateAsgn = a.sons[2].kind != nkEmpty
|
||||
var immediateAsgn = a[2].kind != nkEmpty
|
||||
var v: TLoc
|
||||
initLocExpr(p, a.sons[0], v)
|
||||
initLocExpr(p, a[0], v)
|
||||
genLineDir(p, a)
|
||||
if immediateAsgn:
|
||||
loadInto(p, a.sons[0], a.sons[2], v)
|
||||
loadInto(p, a[0], a[2], v)
|
||||
else:
|
||||
constructLoc(p, v)
|
||||
|
||||
|
|
@ -385,7 +384,7 @@ proc genVarStmt(p: BProc, n: PNode) =
|
|||
if it.kind == nkCommentStmt: continue
|
||||
if it.kind == nkIdentDefs:
|
||||
# can be a lifted var nowadays ...
|
||||
if it.sons[0].kind == nkSym:
|
||||
if it[0].kind == nkSym:
|
||||
genSingleVar(p, it)
|
||||
else:
|
||||
genClosureVar(p, it)
|
||||
|
|
@ -416,53 +415,53 @@ proc genIf(p: BProc, n: PNode, d: var TLoc) =
|
|||
if d.k == locTemp and isEmptyType(n.typ): d.k = locNone
|
||||
if it.len == 2:
|
||||
startBlock(p)
|
||||
initLocExprSingleUse(p, it.sons[0], a)
|
||||
initLocExprSingleUse(p, it[0], a)
|
||||
lelse = getLabel(p)
|
||||
inc(p.labels)
|
||||
lineF(p, cpsStmts, "if (!$1) goto $2;$n",
|
||||
[rdLoc(a), lelse])
|
||||
if p.module.compileToCpp:
|
||||
# avoid "jump to label crosses initialization" error:
|
||||
add(p.s(cpsStmts), "{")
|
||||
expr(p, it.sons[1], d)
|
||||
add(p.s(cpsStmts), "}")
|
||||
p.s(cpsStmts).add "{"
|
||||
expr(p, it[1], d)
|
||||
p.s(cpsStmts).add "}"
|
||||
else:
|
||||
expr(p, it.sons[1], d)
|
||||
expr(p, it[1], d)
|
||||
endBlock(p)
|
||||
if len(n) > 1:
|
||||
if n.len > 1:
|
||||
lineF(p, cpsStmts, "goto $1;$n", [lend])
|
||||
fixLabel(p, lelse)
|
||||
elif it.len == 1:
|
||||
startBlock(p)
|
||||
expr(p, it.sons[0], d)
|
||||
expr(p, it[0], d)
|
||||
endBlock(p)
|
||||
else: internalError(p.config, n.info, "genIf()")
|
||||
if len(n) > 1: fixLabel(p, lend)
|
||||
if n.len > 1: fixLabel(p, lend)
|
||||
|
||||
proc genReturnStmt(p: BProc, t: PNode) =
|
||||
if nfPreventCg in t.flags: return
|
||||
p.beforeRetNeeded = true
|
||||
genLineDir(p, t)
|
||||
if (t.sons[0].kind != nkEmpty): genStmts(p, t.sons[0])
|
||||
if (t[0].kind != nkEmpty): genStmts(p, t[0])
|
||||
blockLeaveActions(p,
|
||||
howManyTrys = p.nestedTryStmts.len,
|
||||
howManyExcepts = p.inExceptBlockLen)
|
||||
if (p.finallySafePoints.len > 0) and not p.noSafePoints:
|
||||
# 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]
|
||||
var safePoint = p.finallySafePoints[^1]
|
||||
linefmt(p, cpsStmts, "if ($1.status != 0) #popCurrentException();$n", [safePoint])
|
||||
lineF(p, cpsStmts, "goto BeforeRet_;$n", [])
|
||||
|
||||
proc genGotoForCase(p: BProc; caseStmt: PNode) =
|
||||
for i in 1 ..< caseStmt.len:
|
||||
for i in 1..<caseStmt.len:
|
||||
startBlock(p)
|
||||
let it = caseStmt.sons[i]
|
||||
for j in 0 .. it.len-2:
|
||||
if it.sons[j].kind == nkRange:
|
||||
let it = caseStmt[i]
|
||||
for j in 0..<it.len-1:
|
||||
if it[j].kind == nkRange:
|
||||
localError(p.config, it.info, "range notation not available for computed goto")
|
||||
return
|
||||
let val = getOrdValue(it.sons[j])
|
||||
let val = getOrdValue(it[j])
|
||||
lineF(p, cpsStmts, "NIMSTATE_$#:$n", [val.rope])
|
||||
genStmts(p, it.lastSon)
|
||||
endBlock(p)
|
||||
|
|
@ -473,7 +472,7 @@ iterator fieldValuePairs(n: PNode): tuple[memberSym, valueSym: PNode] =
|
|||
for identDefs in n:
|
||||
if identDefs.kind == nkIdentDefs:
|
||||
let valueSym = identDefs[^1]
|
||||
for i in 0 ..< identDefs.len-2:
|
||||
for i in 0..<identDefs.len-2:
|
||||
let memberSym = identDefs[i]
|
||||
yield((memberSym: memberSym, valueSym: valueSym))
|
||||
|
||||
|
|
@ -481,22 +480,22 @@ proc genComputedGoto(p: BProc; n: PNode) =
|
|||
# first pass: Generate array of computed labels:
|
||||
var casePos = -1
|
||||
var arraySize: int
|
||||
for i in 0 ..< n.len:
|
||||
let it = n.sons[i]
|
||||
for i in 0..<n.len:
|
||||
let it = n[i]
|
||||
if it.kind == nkCaseStmt:
|
||||
if lastSon(it).kind != nkOfBranch:
|
||||
localError(p.config, it.info,
|
||||
"case statement must be exhaustive for computed goto"); return
|
||||
casePos = i
|
||||
if enumHasHoles(it.sons[0].typ):
|
||||
if enumHasHoles(it[0].typ):
|
||||
localError(p.config, it.info,
|
||||
"case statement cannot work on enums with holes for computed goto"); return
|
||||
let aSize = lengthOrd(p.config, it.sons[0].typ)
|
||||
let aSize = lengthOrd(p.config, it[0].typ)
|
||||
if aSize > 10_000:
|
||||
localError(p.config, it.info,
|
||||
"case statement has too many cases for computed goto"); return
|
||||
arraySize = toInt(aSize)
|
||||
if firstOrd(p.config, it.sons[0].typ) != 0:
|
||||
if firstOrd(p.config, it[0].typ) != 0:
|
||||
localError(p.config, it.info,
|
||||
"case statement has to start at 0 for computed goto"); return
|
||||
if casePos < 0:
|
||||
|
|
@ -510,54 +509,54 @@ proc genComputedGoto(p: BProc; n: PNode) =
|
|||
gotoArray.addf("&&TMP$#_};$n", [rope(id+arraySize)])
|
||||
line(p, cpsLocals, gotoArray)
|
||||
|
||||
for j in 0 ..< casePos:
|
||||
genStmts(p, n.sons[j])
|
||||
for j in 0..<casePos:
|
||||
genStmts(p, n[j])
|
||||
|
||||
let caseStmt = n.sons[casePos]
|
||||
let caseStmt = n[casePos]
|
||||
var a: TLoc
|
||||
initLocExpr(p, caseStmt.sons[0], a)
|
||||
initLocExpr(p, caseStmt[0], a)
|
||||
# first goto:
|
||||
lineF(p, cpsStmts, "goto *$#[$#];$n", [tmp, a.rdLoc])
|
||||
|
||||
for i in 1 ..< caseStmt.len:
|
||||
for i in 1..<caseStmt.len:
|
||||
startBlock(p)
|
||||
let it = caseStmt.sons[i]
|
||||
for j in 0 .. it.len-2:
|
||||
if it.sons[j].kind == nkRange:
|
||||
let it = caseStmt[i]
|
||||
for j in 0..<it.len-1:
|
||||
if it[j].kind == nkRange:
|
||||
localError(p.config, it.info, "range notation not available for computed goto")
|
||||
return
|
||||
|
||||
let val = getOrdValue(it.sons[j])
|
||||
let val = getOrdValue(it[j])
|
||||
lineF(p, cpsStmts, "TMP$#_:$n", [intLiteral(toInt64(val)+id+1)])
|
||||
|
||||
genStmts(p, it.lastSon)
|
||||
|
||||
for j in casePos+1 ..< n.sons.len:
|
||||
genStmts(p, n.sons[j])
|
||||
for j in casePos+1..<n.len:
|
||||
genStmts(p, n[j])
|
||||
|
||||
for j in 0 ..< casePos:
|
||||
for j in 0..<casePos:
|
||||
# prevent new local declarations
|
||||
# compile declarations as assignments
|
||||
let it = n.sons[j]
|
||||
let it = n[j]
|
||||
if it.kind in {nkLetSection, nkVarSection}:
|
||||
let asgn = copyNode(it)
|
||||
asgn.kind = nkAsgn
|
||||
asgn.sons.setLen 2
|
||||
for sym, value in it.fieldValuePairs:
|
||||
if value.kind != nkEmpty:
|
||||
asgn.sons[0] = sym
|
||||
asgn.sons[1] = value
|
||||
asgn[0] = sym
|
||||
asgn[1] = value
|
||||
genStmts(p, asgn)
|
||||
else:
|
||||
genStmts(p, it)
|
||||
|
||||
var a: TLoc
|
||||
initLocExpr(p, caseStmt.sons[0], a)
|
||||
initLocExpr(p, caseStmt[0], a)
|
||||
lineF(p, cpsStmts, "goto *$#[$#];$n", [tmp, a.rdLoc])
|
||||
endBlock(p)
|
||||
|
||||
for j in casePos+1 ..< n.sons.len:
|
||||
genStmts(p, n.sons[j])
|
||||
for j in casePos+1..<n.len:
|
||||
genStmts(p, n[j])
|
||||
|
||||
|
||||
proc genWhileStmt(p: BProc, t: PNode) =
|
||||
|
|
@ -565,23 +564,23 @@ proc genWhileStmt(p: BProc, t: PNode) =
|
|||
# significantly worse code
|
||||
var
|
||||
a: TLoc
|
||||
assert(len(t) == 2)
|
||||
assert(t.len == 2)
|
||||
inc(p.withinLoop)
|
||||
genLineDir(p, t)
|
||||
|
||||
preserveBreakIdx:
|
||||
var loopBody = t.sons[1]
|
||||
var loopBody = t[1]
|
||||
if loopBody.stmtsContainPragma(wComputedGoto) and
|
||||
hasComputedGoto in CC[p.config.cCompiler].props:
|
||||
# for closure support weird loop bodies are generated:
|
||||
if loopBody.len == 2 and loopBody.sons[0].kind == nkEmpty:
|
||||
loopBody = loopBody.sons[1]
|
||||
if loopBody.len == 2 and loopBody[0].kind == nkEmpty:
|
||||
loopBody = loopBody[1]
|
||||
genComputedGoto(p, loopBody)
|
||||
else:
|
||||
p.breakIdx = startBlock(p, "while (1) {$n")
|
||||
p.blocks[p.breakIdx].isLoop = true
|
||||
initLocExpr(p, t.sons[0], a)
|
||||
if (t.sons[0].kind != nkIntLit) or (t.sons[0].intVal == 0):
|
||||
initLocExpr(p, t[0], a)
|
||||
if (t[0].kind != nkIntLit) or (t[0].intVal == 0):
|
||||
let label = assignLabel(p.blocks[p.breakIdx])
|
||||
lineF(p, cpsStmts, "if (!$1) goto $2;$n", [rdLoc(a), label])
|
||||
genStmts(p, loopBody)
|
||||
|
|
@ -602,30 +601,30 @@ proc genBlock(p: BProc, n: PNode, d: var TLoc) =
|
|||
d.flags.incl(lfEnforceDeref)
|
||||
preserveBreakIdx:
|
||||
p.breakIdx = startBlock(p)
|
||||
if n.sons[0].kind != nkEmpty:
|
||||
if n[0].kind != nkEmpty:
|
||||
# named block?
|
||||
assert(n.sons[0].kind == nkSym)
|
||||
var sym = n.sons[0].sym
|
||||
assert(n[0].kind == nkSym)
|
||||
var sym = n[0].sym
|
||||
sym.loc.k = locOther
|
||||
sym.position = p.breakIdx+1
|
||||
expr(p, n.sons[1], d)
|
||||
expr(p, n[1], d)
|
||||
endBlock(p)
|
||||
|
||||
proc genParForStmt(p: BProc, t: PNode) =
|
||||
assert(len(t) == 3)
|
||||
assert(t.len == 3)
|
||||
inc(p.withinLoop)
|
||||
genLineDir(p, t)
|
||||
|
||||
preserveBreakIdx:
|
||||
let forLoopVar = t.sons[0].sym
|
||||
let forLoopVar = t[0].sym
|
||||
var rangeA, rangeB: TLoc
|
||||
assignLocalVar(p, t.sons[0])
|
||||
assignLocalVar(p, t[0])
|
||||
#initLoc(forLoopVar.loc, locLocalVar, forLoopVar.typ, onStack)
|
||||
#discard mangleName(forLoopVar)
|
||||
let call = t.sons[1]
|
||||
assert(len(call) in {4, 5})
|
||||
initLocExpr(p, call.sons[1], rangeA)
|
||||
initLocExpr(p, call.sons[2], rangeB)
|
||||
let call = t[1]
|
||||
assert(call.len in {4, 5})
|
||||
initLocExpr(p, call[1], rangeA)
|
||||
initLocExpr(p, call[2], rangeB)
|
||||
|
||||
# $n at the beginning because of #9710
|
||||
if call.len == 4: # `||`(a, b, annotation)
|
||||
|
|
@ -633,29 +632,29 @@ proc genParForStmt(p: BProc, t: PNode) =
|
|||
"for ($1 = $2; $1 <= $3; ++$1)",
|
||||
[forLoopVar.loc.rdLoc,
|
||||
rangeA.rdLoc, rangeB.rdLoc,
|
||||
call.sons[3].getStr.rope])
|
||||
call[3].getStr.rope])
|
||||
else: # `||`(a, b, step, annotation)
|
||||
var step: TLoc
|
||||
initLocExpr(p, call.sons[3], step)
|
||||
initLocExpr(p, call[3], step)
|
||||
lineF(p, cpsStmts, "$n#pragma omp $5$n" &
|
||||
"for ($1 = $2; $1 <= $3; $1 += $4)",
|
||||
[forLoopVar.loc.rdLoc,
|
||||
rangeA.rdLoc, rangeB.rdLoc, step.rdLoc,
|
||||
call.sons[4].getStr.rope])
|
||||
call[4].getStr.rope])
|
||||
|
||||
p.breakIdx = startBlock(p)
|
||||
p.blocks[p.breakIdx].isLoop = true
|
||||
genStmts(p, t.sons[2])
|
||||
genStmts(p, t[2])
|
||||
endBlock(p)
|
||||
|
||||
dec(p.withinLoop)
|
||||
|
||||
proc genBreakStmt(p: BProc, t: PNode) =
|
||||
var idx = p.breakIdx
|
||||
if t.sons[0].kind != nkEmpty:
|
||||
if t[0].kind != nkEmpty:
|
||||
# named break?
|
||||
assert(t.sons[0].kind == nkSym)
|
||||
var sym = t.sons[0].sym
|
||||
assert(t[0].kind == nkSym)
|
||||
var sym = t[0].sym
|
||||
doAssert(sym.loc.k == locOther)
|
||||
idx = sym.position-1
|
||||
else:
|
||||
|
|
@ -704,17 +703,15 @@ proc genRaiseStmt(p: BProc, t: PNode) =
|
|||
|
||||
template genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
|
||||
rangeFormat, eqFormat: FormatStr, labl: TLabel) =
|
||||
var
|
||||
x, y: TLoc
|
||||
var length = len(b)
|
||||
for i in 0 .. length - 2:
|
||||
if b.sons[i].kind == nkRange:
|
||||
initLocExpr(p, b.sons[i].sons[0], x)
|
||||
initLocExpr(p, b.sons[i].sons[1], y)
|
||||
var x, y: TLoc
|
||||
for i in 0..<b.len - 1:
|
||||
if b[i].kind == nkRange:
|
||||
initLocExpr(p, b[i][0], x)
|
||||
initLocExpr(p, b[i][1], y)
|
||||
lineCg(p, cpsStmts, rangeFormat,
|
||||
[rdCharLoc(e), rdCharLoc(x), rdCharLoc(y), labl])
|
||||
else:
|
||||
initLocExpr(p, b.sons[i], x)
|
||||
initLocExpr(p, b[i], x)
|
||||
lineCg(p, cpsStmts, eqFormat, [rdCharLoc(e), rdCharLoc(x), labl])
|
||||
|
||||
proc genCaseSecondPass(p: BProc, t: PNode, d: var TLoc,
|
||||
|
|
@ -724,12 +721,11 @@ proc genCaseSecondPass(p: BProc, t: PNode, d: var TLoc,
|
|||
# bug #4230: avoid false sharing between branches:
|
||||
if d.k == locTemp and isEmptyType(t.typ): d.k = locNone
|
||||
lineF(p, cpsStmts, "LA$1_: ;$n", [rope(labId + i)])
|
||||
if t.sons[i].kind == nkOfBranch:
|
||||
var length = len(t.sons[i])
|
||||
exprBlock(p, t.sons[i].sons[length - 1], d)
|
||||
if t[i].kind == nkOfBranch:
|
||||
exprBlock(p, t[i][^1], d)
|
||||
lineF(p, cpsStmts, "goto $1;$n", [lend])
|
||||
else:
|
||||
exprBlock(p, t.sons[i].sons[0], d)
|
||||
exprBlock(p, t[i][0], d)
|
||||
result = lend
|
||||
|
||||
template genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc,
|
||||
|
|
@ -740,8 +736,8 @@ template genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc,
|
|||
var labId = p.labels
|
||||
for i in 1..until:
|
||||
inc(p.labels)
|
||||
if t.sons[i].kind == nkOfBranch: # else statement
|
||||
genCaseGenericBranch(p, t.sons[i], a, rangeFormat, eqFormat,
|
||||
if t[i].kind == nkOfBranch: # else statement
|
||||
genCaseGenericBranch(p, t[i], a, rangeFormat, eqFormat,
|
||||
"LA" & rope(p.labels) & "_")
|
||||
else:
|
||||
lineF(p, cpsStmts, "goto LA$1_;$n", [rope(p.labels)])
|
||||
|
|
@ -758,38 +754,37 @@ template genIfForCaseUntil(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)
|
||||
var lend = genIfForCaseUntil(p, t, d, rangeFormat, eqFormat, len(t)-1, a)
|
||||
initLocExpr(p, t[0], a)
|
||||
var lend = genIfForCaseUntil(p, t, d, rangeFormat, eqFormat, t.len-1, a)
|
||||
fixLabel(p, lend)
|
||||
|
||||
proc genCaseStringBranch(p: BProc, b: PNode, e: TLoc, labl: TLabel,
|
||||
branches: var openArray[Rope]) =
|
||||
var x: TLoc
|
||||
var length = len(b)
|
||||
for i in 0 .. length - 2:
|
||||
assert(b.sons[i].kind != nkRange)
|
||||
initLocExpr(p, b.sons[i], x)
|
||||
assert(b.sons[i].kind in {nkStrLit..nkTripleStrLit})
|
||||
var j = int(hashString(p.config, b.sons[i].strVal) and high(branches))
|
||||
for i in 0..<b.len - 1:
|
||||
assert(b[i].kind != nkRange)
|
||||
initLocExpr(p, b[i], x)
|
||||
assert(b[i].kind in {nkStrLit..nkTripleStrLit})
|
||||
var j = int(hashString(p.config, b[i].strVal) and high(branches))
|
||||
appcg(p.module, branches[j], "if (#eqStrings($1, $2)) goto $3;$n",
|
||||
[rdLoc(e), rdLoc(x), labl])
|
||||
|
||||
proc genStringCase(p: BProc, t: PNode, d: var TLoc) =
|
||||
# count how many constant strings there are in the case:
|
||||
var strings = 0
|
||||
for i in 1 ..< len(t):
|
||||
if t.sons[i].kind == nkOfBranch: inc(strings, len(t.sons[i]) - 1)
|
||||
for i in 1..<t.len:
|
||||
if t[i].kind == nkOfBranch: inc(strings, t[i].len - 1)
|
||||
if strings > stringCaseThreshold:
|
||||
var bitMask = math.nextPowerOfTwo(strings) - 1
|
||||
var branches: seq[Rope]
|
||||
newSeq(branches, bitMask + 1)
|
||||
var a: TLoc
|
||||
initLocExpr(p, t.sons[0], a) # fist pass: generate ifs+goto:
|
||||
initLocExpr(p, t[0], a) # fist pass: generate ifs+goto:
|
||||
var labId = p.labels
|
||||
for i in 1 ..< len(t):
|
||||
for i in 1..<t.len:
|
||||
inc(p.labels)
|
||||
if t.sons[i].kind == nkOfBranch:
|
||||
genCaseStringBranch(p, t.sons[i], a, "LA" & rope(p.labels) & "_",
|
||||
if t[i].kind == nkOfBranch:
|
||||
genCaseStringBranch(p, t[i], a, "LA" & rope(p.labels) & "_",
|
||||
branches)
|
||||
else:
|
||||
# else statement: nothing to do yet
|
||||
|
|
@ -797,28 +792,28 @@ proc genStringCase(p: BProc, t: PNode, d: var TLoc) =
|
|||
discard
|
||||
linefmt(p, cpsStmts, "switch (#hashString($1) & $2) {$n",
|
||||
[rdLoc(a), bitMask])
|
||||
for j in 0 .. high(branches):
|
||||
for j in 0..high(branches):
|
||||
if branches[j] != nil:
|
||||
lineF(p, cpsStmts, "case $1: $n$2break;$n",
|
||||
[intLiteral(j), branches[j]])
|
||||
lineF(p, cpsStmts, "}$n", []) # else statement:
|
||||
if t.sons[len(t)-1].kind != nkOfBranch:
|
||||
if t[^1].kind != nkOfBranch:
|
||||
lineF(p, cpsStmts, "goto LA$1_;$n", [rope(p.labels)])
|
||||
# third pass: generate statements
|
||||
var lend = genCaseSecondPass(p, t, d, labId, len(t)-1)
|
||||
var lend = genCaseSecondPass(p, t, d, labId, t.len-1)
|
||||
fixLabel(p, lend)
|
||||
else:
|
||||
genCaseGeneric(p, t, d, "", "if (#eqStrings($1, $2)) goto $3;$n")
|
||||
|
||||
proc branchHasTooBigRange(b: PNode): bool =
|
||||
for i in 0 .. len(b)-2:
|
||||
for i in 0..<b.len-1:
|
||||
# last son is block
|
||||
if (b.sons[i].kind == nkRange) and
|
||||
b.sons[i].sons[1].intVal - b.sons[i].sons[0].intVal > RangeExpandLimit:
|
||||
if (b[i].kind == nkRange) and
|
||||
b[i][1].intVal - b[i][0].intVal > RangeExpandLimit:
|
||||
return true
|
||||
|
||||
proc ifSwitchSplitPoint(p: BProc, n: PNode): int =
|
||||
for i in 1..n.len-1:
|
||||
for i in 1..<n.len:
|
||||
var branch = n[i]
|
||||
var stmtBlock = lastSon(branch)
|
||||
if stmtBlock.stmtsContainPragma(wLinearScanEnd):
|
||||
|
|
@ -828,8 +823,7 @@ proc ifSwitchSplitPoint(p: BProc, n: PNode): int =
|
|||
result = i
|
||||
|
||||
proc genCaseRange(p: BProc, branch: PNode) =
|
||||
var length = branch.len
|
||||
for j in 0 .. length-2:
|
||||
for j in 0..<branch.len-1:
|
||||
if branch[j].kind == nkRange:
|
||||
if hasSwitchRange in CC[p.config.cCompiler].props:
|
||||
lineF(p, cpsStmts, "case $1 ... $2:$n", [
|
||||
|
|
@ -849,7 +843,7 @@ proc genOrdinalCase(p: BProc, n: PNode, d: var TLoc) =
|
|||
|
||||
# generate if part (might be empty):
|
||||
var a: TLoc
|
||||
initLocExpr(p, n.sons[0], a)
|
||||
initLocExpr(p, n[0], a)
|
||||
var lend = if splitPoint > 0: genIfForCaseUntil(p, n, d,
|
||||
rangeFormat = "if ($1 >= $2 && $1 <= $3) goto $4;$n",
|
||||
eqFormat = "if ($1 == $2) goto $3;$n",
|
||||
|
|
@ -859,7 +853,7 @@ proc genOrdinalCase(p: BProc, n: PNode, d: var TLoc) =
|
|||
if splitPoint+1 < n.len:
|
||||
lineF(p, cpsStmts, "switch ($1) {$n", [rdCharLoc(a)])
|
||||
var hasDefault = false
|
||||
for i in splitPoint+1 ..< n.len:
|
||||
for i in splitPoint+1..<n.len:
|
||||
# bug #4230: avoid false sharing between branches:
|
||||
if d.k == locTemp and isEmptyType(n.typ): d.k = locNone
|
||||
var branch = n[i]
|
||||
|
|
@ -880,14 +874,14 @@ proc genCase(p: BProc, t: PNode, d: var TLoc) =
|
|||
genLineDir(p, t)
|
||||
if not isEmptyType(t.typ) and d.k == locNone:
|
||||
getTemp(p, t.typ, d)
|
||||
case skipTypes(t.sons[0].typ, abstractVarRange).kind
|
||||
case skipTypes(t[0].typ, abstractVarRange).kind
|
||||
of tyString:
|
||||
genStringCase(p, t, d)
|
||||
of tyFloat..tyFloat128:
|
||||
genCaseGeneric(p, t, d, "if ($1 >= $2 && $1 <= $3) goto $4;$n",
|
||||
"if ($1 == $2) goto $3;$n")
|
||||
else:
|
||||
if t.sons[0].kind == nkSym and sfGoto in t.sons[0].sym.flags:
|
||||
if t[0].kind == nkSym and sfGoto in t[0].sym.flags:
|
||||
genGotoForCase(p, t)
|
||||
else:
|
||||
genOrdinalCase(p, t, d)
|
||||
|
|
@ -926,7 +920,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
|||
genLineDir(p, t)
|
||||
discard cgsym(p.module, "popCurrentExceptionEx")
|
||||
let fin = if t[^1].kind == nkFinally: t[^1] else: nil
|
||||
add(p.nestedTryStmts, (fin, false))
|
||||
p.nestedTryStmts.add((fin, false))
|
||||
startBlock(p, "try {$n")
|
||||
expr(p, t[0], d)
|
||||
endBlock(p)
|
||||
|
|
@ -947,7 +941,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
|||
genExceptBranchBody(t[i][0])
|
||||
endBlock(p)
|
||||
else:
|
||||
for j in 0..t[i].len-2:
|
||||
for j in 0..<t[i].len-1:
|
||||
if t[i][j].isInfixAs():
|
||||
let exvar = t[i][j][2] # ex1 in `except ExceptType as ex1:`
|
||||
fillLoc(exvar.sym.loc, locTemp, exvar, mangleLocalName(p, exvar.sym), OnUnknown)
|
||||
|
|
@ -1023,40 +1017,38 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
|||
else:
|
||||
linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", [safePoint])
|
||||
startBlock(p, "if ($1.status == 0) {$n", [safePoint])
|
||||
let length = len(t)
|
||||
let fin = if t[^1].kind == nkFinally: t[^1] else: nil
|
||||
add(p.nestedTryStmts, (fin, quirkyExceptions))
|
||||
expr(p, t.sons[0], d)
|
||||
p.nestedTryStmts.add((fin, quirkyExceptions))
|
||||
expr(p, t[0], d)
|
||||
if not quirkyExceptions:
|
||||
linefmt(p, cpsStmts, "#popSafePoint();$n", [])
|
||||
endBlock(p)
|
||||
startBlock(p, "else {$n")
|
||||
linefmt(p, cpsStmts, "#popSafePoint();$n", [])
|
||||
genRestoreFrameAfterException(p)
|
||||
elif 1 < length and t.sons[1].kind == nkExceptBranch:
|
||||
elif 1 < t.len and t[1].kind == nkExceptBranch:
|
||||
startBlock(p, "if (#getCurrentException()) {$n")
|
||||
else:
|
||||
startBlock(p)
|
||||
p.nestedTryStmts[^1].inExcept = true
|
||||
var i = 1
|
||||
while (i < length) and (t.sons[i].kind == nkExceptBranch):
|
||||
while (i < t.len) and (t[i].kind == nkExceptBranch):
|
||||
# bug #4230: avoid false sharing between branches:
|
||||
if d.k == locTemp and isEmptyType(t.typ): d.k = locNone
|
||||
var blen = len(t.sons[i])
|
||||
if blen == 1:
|
||||
if t[i].len == 1:
|
||||
# general except section:
|
||||
if i > 1: lineF(p, cpsStmts, "else", [])
|
||||
startBlock(p)
|
||||
if not quirkyExceptions:
|
||||
linefmt(p, cpsStmts, "$1.status = 0;$n", [safePoint])
|
||||
expr(p, t.sons[i].sons[0], d)
|
||||
expr(p, t[i][0], d)
|
||||
linefmt(p, cpsStmts, "#popCurrentException();$n", [])
|
||||
endBlock(p)
|
||||
else:
|
||||
var orExpr: Rope = nil
|
||||
for j in 0 .. blen - 2:
|
||||
assert(t.sons[i].sons[j].kind == nkType)
|
||||
if orExpr != nil: add(orExpr, "||")
|
||||
for j in 0..<t[i].len - 1:
|
||||
assert(t[i][j].kind == nkType)
|
||||
if orExpr != nil: orExpr.add("||")
|
||||
let checkFor = if optTinyRtti in p.config.globalOptions:
|
||||
genTypeInfo2Name(p.module, t[i][j].typ)
|
||||
else:
|
||||
|
|
@ -1068,15 +1060,15 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
|||
startBlock(p, "if ($1) {$n", [orExpr])
|
||||
if not quirkyExceptions:
|
||||
linefmt(p, cpsStmts, "$1.status = 0;$n", [safePoint])
|
||||
expr(p, t.sons[i].sons[blen-1], d)
|
||||
expr(p, t[i][^1], d)
|
||||
linefmt(p, cpsStmts, "#popCurrentException();$n", [])
|
||||
endBlock(p)
|
||||
inc(i)
|
||||
discard pop(p.nestedTryStmts)
|
||||
endBlock(p) # end of else block
|
||||
if i < length and t.sons[i].kind == nkFinally:
|
||||
if i < t.len and t[i].kind == nkFinally:
|
||||
p.finallySafePoints.add(safePoint)
|
||||
genSimpleBlock(p, t.sons[i].sons[0])
|
||||
genSimpleBlock(p, t[i][0])
|
||||
discard pop(p.finallySafePoints)
|
||||
if not quirkyExceptions:
|
||||
linefmt(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", [safePoint])
|
||||
|
|
@ -1120,12 +1112,12 @@ proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): Rope =
|
|||
if x[j] in {'"', ':'}:
|
||||
# don't modify the line if already in quotes or
|
||||
# some clobber register list:
|
||||
add(result, x); add(result, "\L")
|
||||
result.add(x); result.add("\L")
|
||||
else:
|
||||
# ignore empty lines
|
||||
add(result, "\"")
|
||||
add(result, x)
|
||||
add(result, "\\n\"\n")
|
||||
result.add("\"")
|
||||
result.add(x)
|
||||
result.add("\\n\"\n")
|
||||
else:
|
||||
res.add("\L")
|
||||
result = res.rope
|
||||
|
|
@ -1139,25 +1131,25 @@ proc genAsmStmt(p: BProc, t: PNode) =
|
|||
# work:
|
||||
if p.prc == nil:
|
||||
# top level asm statement?
|
||||
add(p.module.s[cfsProcHeaders], runtimeFormat(CC[p.config.cCompiler].asmStmtFrmt, [s]))
|
||||
p.module.s[cfsProcHeaders].add runtimeFormat(CC[p.config.cCompiler].asmStmtFrmt, [s])
|
||||
else:
|
||||
add(p.s(cpsStmts), indentLine(p, runtimeFormat(CC[p.config.cCompiler].asmStmtFrmt, [s])))
|
||||
p.s(cpsStmts).add indentLine(p, runtimeFormat(CC[p.config.cCompiler].asmStmtFrmt, [s]))
|
||||
|
||||
proc determineSection(n: PNode): TCFileSection =
|
||||
result = cfsProcHeaders
|
||||
if n.len >= 1 and n.sons[0].kind in {nkStrLit..nkTripleStrLit}:
|
||||
let sec = n.sons[0].strVal
|
||||
if n.len >= 1 and n[0].kind in {nkStrLit..nkTripleStrLit}:
|
||||
let sec = n[0].strVal
|
||||
if sec.startsWith("/*TYPESECTION*/"): result = cfsTypes
|
||||
elif sec.startsWith("/*VARSECTION*/"): result = cfsVars
|
||||
elif sec.startsWith("/*INCLUDESECTION*/"): result = cfsHeaders
|
||||
|
||||
proc genEmit(p: BProc, t: PNode) =
|
||||
var s = genAsmOrEmitStmt(p, t.sons[1])
|
||||
var s = genAsmOrEmitStmt(p, t[1])
|
||||
if p.prc == nil:
|
||||
# top level emit pragma?
|
||||
let section = determineSection(t[1])
|
||||
genCLineDir(p.module.s[section], t.info, p.config)
|
||||
add(p.module.s[section], s)
|
||||
p.module.s[section].add(s)
|
||||
else:
|
||||
genLineDir(p, t)
|
||||
line(p, cpsStmts, s)
|
||||
|
|
@ -1169,18 +1161,18 @@ proc genPragma(p: BProc, n: PNode) =
|
|||
of wInjectStmt:
|
||||
var p = newProc(nil, p.module)
|
||||
p.options = p.options - {optLineTrace, optStackTrace}
|
||||
genStmts(p, it.sons[1])
|
||||
genStmts(p, it[1])
|
||||
p.module.injectStmt = p.s(cpsStmts)
|
||||
else: discard
|
||||
|
||||
proc fieldDiscriminantCheckNeeded(p: BProc, asgn: PNode): bool =
|
||||
if optFieldCheck in p.options:
|
||||
var le = asgn.sons[0]
|
||||
var le = asgn[0]
|
||||
if le.kind == nkCheckedFieldExpr:
|
||||
var field = le.sons[0].sons[1].sym
|
||||
var field = le[0][1].sym
|
||||
result = sfDiscriminant in field.flags
|
||||
elif le.kind == nkDotExpr:
|
||||
var field = le.sons[1].sym
|
||||
var field = le[1].sym
|
||||
result = sfDiscriminant in field.flags
|
||||
|
||||
proc genDiscriminantCheck(p: BProc, a, tmp: TLoc, objtype: PType,
|
||||
|
|
@ -1188,14 +1180,13 @@ proc genDiscriminantCheck(p: BProc, a, tmp: TLoc, objtype: PType,
|
|||
var t = skipTypes(objtype, abstractVar)
|
||||
assert t.kind == tyObject
|
||||
discard genTypeInfo(p.module, t, a.lode.info)
|
||||
var L = toInt64(lengthOrd(p.config, field.typ))
|
||||
if not containsOrIncl(p.module.declaredThings, field.id):
|
||||
appcg(p.module, cfsVars, "extern $1",
|
||||
[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),
|
||||
intLiteral(L+1)])
|
||||
intLiteral(toInt64(lengthOrd(p.config, field.typ))+1)])
|
||||
|
||||
proc genCaseObjDiscMapping(p: BProc, e: PNode, t: PType, field: PSym; d: var TLoc) =
|
||||
const ObjDiscMappingProcSlot = -5
|
||||
|
|
@ -1214,12 +1205,12 @@ proc genCaseObjDiscMapping(p: BProc, e: PNode, t: PType, field: PSym; d: var TLo
|
|||
|
||||
proc asgnFieldDiscriminant(p: BProc, e: PNode) =
|
||||
var a, tmp: TLoc
|
||||
var dotExpr = e.sons[0]
|
||||
if dotExpr.kind == nkCheckedFieldExpr: dotExpr = dotExpr.sons[0]
|
||||
initLocExpr(p, e.sons[0], a)
|
||||
var dotExpr = e[0]
|
||||
if dotExpr.kind == nkCheckedFieldExpr: dotExpr = dotExpr[0]
|
||||
initLocExpr(p, e[0], a)
|
||||
getTemp(p, a.t, tmp)
|
||||
expr(p, e.sons[1], tmp)
|
||||
let field = dotExpr.sons[1].sym
|
||||
expr(p, e[1], tmp)
|
||||
let field = dotExpr[1].sym
|
||||
if optTinyRtti in p.config.globalOptions:
|
||||
let t = dotExpr[0].typ.skipTypes(abstractInst)
|
||||
var oldVal, newVal: TLoc
|
||||
|
|
@ -1229,13 +1220,13 @@ proc asgnFieldDiscriminant(p: BProc, e: PNode) =
|
|||
"#nimFieldDiscriminantCheckV2($1, $2);$n",
|
||||
[rdLoc(oldVal), rdLoc(newVal)])
|
||||
else:
|
||||
genDiscriminantCheck(p, a, tmp, dotExpr.sons[0].typ, field)
|
||||
genDiscriminantCheck(p, a, tmp, dotExpr[0].typ, field)
|
||||
genAssignment(p, a, tmp, {})
|
||||
|
||||
proc genAsgn(p: BProc, e: PNode, fastAsgn: bool) =
|
||||
if e.sons[0].kind == nkSym and sfGoto in e.sons[0].sym.flags:
|
||||
if e[0].kind == nkSym and sfGoto in e[0].sym.flags:
|
||||
genLineDir(p, e)
|
||||
genGotoVar(p, e.sons[1])
|
||||
genGotoVar(p, e[1])
|
||||
elif not fieldDiscriminantCheckNeeded(p, e):
|
||||
let le = e[0]
|
||||
let ri = e[1]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue