Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
krux02 authored and narimiran committed Oct 31, 2018
1 parent bede32b commit 68a3198
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 34 deletions.
Empty file modified bin/nim-gdb 100644 → 100755
Empty file.
83 changes: 52 additions & 31 deletions compiler/ccgstmts.nim
Expand Up @@ -400,6 +400,16 @@ proc genGotoForCase(p: BProc; caseStmt: PNode) =
genStmts(p, it.lastSon)
endBlock(p)


iterator fieldValuePairs(n: PNode): tuple[memberSym, valueSym: PNode] =
assert(n.kind in {nkLetSection, nkVarSection})
for identDefs in n:
if identDefs.kind == nkIdentDefs:
let valueSym = identDefs[^1]
for i in 0 ..< identDefs.len-2:
let memberSym = identDefs[i]
yield((memberSym: memberSym, valueSym: valueSym))

proc genComputedGoto(p: BProc; n: PNode) =
# first pass: Generate array of computed labels:
var casePos = -1
Expand Down Expand Up @@ -429,22 +439,12 @@ proc genComputedGoto(p: BProc; n: PNode) =
let tmp = "TMP$1_" % [id.rope]
var gotoArray = "static void* $#[$#] = {" % [tmp, arraySize.rope]
for i in 1..arraySize-1:
gotoArray.addf("&&TMP$#_, ", [(id+i).rope])
gotoArray.addf("&&TMP$#_};$n", [(id+arraySize).rope])
gotoArray.addf("&&TMP$#_, ", [rope(id+i)])
gotoArray.addf("&&TMP$#_};$n", [rope(id+arraySize)])
line(p, cpsLocals, gotoArray)

let topBlock = p.blocks.len-1
let oldBody = p.blocks[topBlock].sections[cpsStmts]
p.blocks[topBlock].sections[cpsStmts] = nil

for j in casePos+1 ..< n.len: genStmts(p, n.sons[j])
let tailB = p.blocks[topBlock].sections[cpsStmts]

p.blocks[topBlock].sections[cpsStmts] = nil
for j in 0 .. casePos-1: genStmts(p, n.sons[j])
let tailA = p.blocks[topBlock].sections[cpsStmts]

p.blocks[topBlock].sections[cpsStmts] = oldBody & tailA
for j in 0 ..< casePos:
genStmts(p, n.sons[j])

let caseStmt = n.sons[casePos]
var a: TLoc
Expand All @@ -459,19 +459,40 @@ proc genComputedGoto(p: BProc; n: PNode) =
if it.sons[j].kind == nkRange:
localError(p.config, it.info, "range notation not available for computed goto")
return

let val = getOrdValue(it.sons[j])
lineF(p, cpsStmts, "TMP$#_:$n", [intLiteral(val+id+1)])

genStmts(p, it.lastSon)
#for j in casePos+1 ..< n.len: genStmts(p, n.sons[j]) # tailB
#for j in 0 .. casePos-1: genStmts(p, n.sons[j]) # tailA
add(p.s(cpsStmts), tailB)
add(p.s(cpsStmts), tailA)

for j in casePos+1 ..< n.sons.len:
genStmts(p, n.sons[j])

for j in 0 ..< casePos:
# prevent new local declarations
# compile declarations as assignments
let it = n.sons[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
genStmts(p, asgn)
else:
genStmts(p, it)

var a: TLoc
initLocExpr(p, caseStmt.sons[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])


proc genWhileStmt(p: BProc, t: PNode) =
# we don't generate labels here as for example GCC would produce
# significantly worse code
Expand All @@ -482,26 +503,26 @@ proc genWhileStmt(p: BProc, t: PNode) =
genLineDir(p, t)

preserveBreakIdx:
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):
let label = assignLabel(p.blocks[p.breakIdx])
lineF(p, cpsStmts, "if (!$1) goto $2;$n", [rdLoc(a), label])
var loopBody = t.sons[1]
if loopBody.stmtsContainPragma(wComputedGoto) and
hasComputedGoto in CC[p.config.cCompiler].props:
# for closure support weird loop bodies are generated:
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]
genComputedGoto(p, loopBody)
genComputedGoto(p, loopBody) # TODO foobar
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):
let label = assignLabel(p.blocks[p.breakIdx])
lineF(p, cpsStmts, "if (!$1) goto $2;$n", [rdLoc(a), label])
genStmts(p, loopBody)

if optProfiler in p.options:
# invoke at loop body exit:
linefmt(p, cpsStmts, "#nimProfile();$n")
endBlock(p)
if optProfiler in p.options:
# invoke at loop body exit:
linefmt(p, cpsStmts, "#nimProfile();$n")
endBlock(p)

dec(p.withinLoop)

Expand Down
7 changes: 4 additions & 3 deletions koch.nim
Expand Up @@ -407,13 +407,14 @@ proc temp(args: string) =
result[1].add " " & quoteShell(args[i])
inc i

var output = "compiler" / "nim".exe
var finalDest = "bin" / "nim_temp".exe
let d = getAppDir()
var output = d / "compiler" / "nim".exe
var finalDest = d / "bin" / "nim_temp".exe
# 125 is the magic number to tell git bisect to skip the current
# commit.
let (bootArgs, programArgs) = splitArgs(args)
let nimexec = findNim()
exec(nimexec & " c -d:debug --debugger:native " & bootArgs & " compiler" / "nim", 125)
exec(nimexec & " c -d:debug --debugger:native " & bootArgs & " " & (d / "compiler" / "nim"), 125)
copyExe(output, finalDest)
if programArgs.len > 0: exec(finalDest & " " & programArgs)

Expand Down
9 changes: 9 additions & 0 deletions tests/casestmt/tcomputedgoto.nim
@@ -1,16 +1,22 @@
discard """
output: '''
yeah A enumB
uneven
yeah A enumB
yeah CD enumD
uneven
yeah CD enumE
yeah A enumB
uneven
yeah CD enumE
yeah CD enumD
uneven
yeah A enumB
yeah B enumC
uneven
yeah A enumB
yeah A enumB
uneven
yeah A enumB
'''
"""
Expand Down Expand Up @@ -47,4 +53,7 @@ proc vm() =
of enumLast: discard
inc(pc)

if pc mod 2 == 1:
echo "uneven"

vm()
19 changes: 19 additions & 0 deletions tools/nim-gdb.py
Expand Up @@ -209,6 +209,25 @@ def to_string(self):
else:
return ""

class NimRopePrinter:
pattern = re.compile(r'^tyObject_RopeObj_OFzf0kSiPTcNreUIeJgWVA \*$')

def __init__(self, val):
self.val = val

def display_hint(self):
return 'string'

def to_string(self):
if self.val:
left = NimRopePrinter(self.val["left"]).to_string()
data = NimStringPrinter(self.val["data"]).to_string()
right = NimRopePrinter(self.val["right"]).to_string()
return left + data + right
else:
return ""


################################################################################

# proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} =
Expand Down

0 comments on commit 68a3198

Please sign in to comment.