diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/lambdalifting.nim | 9 | ||||
-rw-r--r-- | compiler/lowerings.nim | 52 | ||||
-rw-r--r-- | compiler/transf.nim | 12 | ||||
-rw-r--r-- | compiler/vm.nim | 2 | ||||
-rw-r--r-- | compiler/vmgen.nim | 31 |
5 files changed, 73 insertions, 33 deletions
diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index 4bc8eff86..6f6942096 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -11,7 +11,7 @@ import intsets, strutils, lists, options, ast, astalgo, trees, treetab, msgs, os, - idents, renderer, types, magicsys, rodread + idents, renderer, types, magicsys, rodread, lowerings discard """ The basic approach is that captured vars need to be put on the heap and @@ -536,13 +536,6 @@ proc newAsgnStmt(le, ri: PNode, info: TLineInfo): PNode = result.sons[0] = le result.sons[1] = ri -proc addVar*(father, v: PNode) = - var vpart = newNodeI(nkIdentDefs, v.info) - addSon(vpart, v) - addSon(vpart, ast.emptyNode) - addSon(vpart, ast.emptyNode) - addSon(father, vpart) - proc newClosureCreationVar(o: POuterContext; e: PEnv): PSym = result = newSym(skVar, getIdent(envName), o.fn, e.attachedNode.info) incl(result.flags, sfShadowed) diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim new file mode 100644 index 000000000..2cf641d93 --- /dev/null +++ b/compiler/lowerings.nim @@ -0,0 +1,52 @@ +# +# +# The Nimrod Compiler +# (c) Copyright 2014 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module implements common simple lowerings. + +const + genPrefix* = ":tmp" # prefix for generated names + +import ast, types, idents, magicsys + +proc newTupleAccess*(tup: PNode, i: int): PNode = + result = newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes( + abstractInst).sons[i]) + addSon(result, copyTree(tup)) + var lit = newNodeIT(nkIntLit, tup.info, getSysType(tyInt)) + lit.intVal = i + addSon(result, lit) + +proc addVar*(father, v: PNode) = + var vpart = newNodeI(nkIdentDefs, v.info, 3) + vpart.sons[0] = v + vpart.sons[1] = ast.emptyNode + vpart.sons[2] = ast.emptyNode + addSon(father, vpart) + +proc newAsgnStmt(le, ri: PNode): PNode = + result = newNodeI(nkAsgn, le.info, 2) + result.sons[0] = le + result.sons[1] = ri + +proc lowerTupleUnpacking*(n: PNode; owner: PSym): PNode = + assert n.kind == nkVarTuple + let value = n.lastSon + result = newNodeI(nkStmtList, n.info) + + var temp = newSym(skTemp, getIdent(genPrefix), owner, value.info) + temp.typ = skipTypes(value.typ, abstractInst) + incl(temp.flags, sfFromGeneric) + + var v = newNodeI(nkVarSection, value.info) + v.addVar(newSymNode(temp)) + result.add(v) + + result.add newAsgnStmt(newSymNode(temp), value) + for i in 0 .. n.len-3: + result.add newAsgnStmt(n.sons[i], newTupleAccess(value, i)) diff --git a/compiler/transf.nim b/compiler/transf.nim index 9586398c9..7922acbe9 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -20,10 +20,7 @@ import intsets, strutils, lists, options, ast, astalgo, trees, treetab, msgs, os, idents, renderer, types, passes, semfold, magicsys, cgmeth, rodread, - lambdalifting, sempass2 - -const - genPrefix* = ":tmp" # prefix for generated names + lambdalifting, sempass2, lowerings # implementation @@ -240,13 +237,6 @@ proc transformLoopBody(c: PTransf, n: PNode): PTransNode = discard c.contSyms.pop() else: result = transform(c, n) - -proc newTupleAccess(tup: PNode, i: int): PNode = - result = newNodeIT(nkBracketExpr, tup.info, tup.typ.sons[i]) - addSon(result, copyTree(tup)) - var lit = newNodeIT(nkIntLit, tup.info, getSysType(tyInt)) - lit.intVal = i - addSon(result, lit) proc unpackTuple(c: PTransf, n: PNode, father: PTransNode) = # XXX: BUG: what if `n` is an expression with side-effects? diff --git a/compiler/vm.nim b/compiler/vm.nim index f093527f8..70eb6f828 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -486,6 +486,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = regs[ra].intVal = regs[rb].intVal + regs[rc].intVal of opcAddImmInt: decodeBImm(rkInt) + #message(c.debug[pc], warnUser, "came here") + #debug regs[rb].node regs[ra].intVal = regs[rb].intVal + imm of opcSubInt: decodeBC(rkInt) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 80c07f39e..82d1e9ab8 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -11,7 +11,7 @@ import unsigned, strutils, ast, astalgo, types, msgs, renderer, vmdef, - trees, intsets, rodread, magicsys, options + trees, intsets, rodread, magicsys, options, lowerings from os import splitFile @@ -636,11 +636,16 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = c.genAddSubInt(n, dest, opcAddInt) of mInc, mDec: unused(n, dest) - # XXX generates inefficient code for globals - var d = c.genx(n.sons[1]).TDest - c.genAddSubInt(n, d, if m == mInc: opcAddInt else: opcSubInt) + let opc = if m == mInc: opcAddInt else: opcSubInt + let d = c.genx(n.sons[1]) + if n.sons[2].isInt8Lit: + c.gABI(n, succ(opc), d, d, n.sons[2].intVal) + else: + let tmp = c.genx(n.sons[2]) + c.gABC(n, opc, d, d, tmp) + c.freeTemp(tmp) c.genAsgnPatch(n.sons[1], d) - c.freeTemp(d.TRegister) + c.freeTemp(d) of mOrd, mChr, mArrToSeq: c.gen(n.sons[1], dest) of mNew, mNewFinalize: unused(n, dest) @@ -1006,6 +1011,10 @@ proc isOwnedBy(a, b: PSym): bool = if a == b: return true a = a.owner +proc getOwner(c: PCtx): PSym = + result = c.prc.sym + if result.isNil: result = c.module + proc checkCanEval(c: PCtx; n: PNode) = # we need to ensure that we don't evaluate 'x' here: # proc foo() = var x ... @@ -1148,7 +1157,7 @@ proc genObjAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) = let a = c.genx(n.sons[0], flags) let b = genField(n.sons[1]) if dest < 0: dest = c.getTemp(n.typ) - if gfAddrOf notin flags and fitsRegister(n.typ): + if gfAddrOf notin flags and fitsRegister(n.typ.skipTypes({tyVar})): var cc = c.getTemp(n.typ) c.gABC(n, opcLdObj, cc, a, b) c.gABC(n, opcNodeToReg, dest, cc) @@ -1228,16 +1237,10 @@ proc genVarSection(c: PCtx; n: PNode) = if a.kind == nkCommentStmt: continue #assert(a.sons[0].kind == nkSym) can happen for transformed vars if a.kind == nkVarTuple: - let tmp = c.genx(a.lastSon) for i in 0 .. a.len-3: setSlot(c, a[i].sym) - # v = t[i] - var v: TDest = -1 checkCanEval(c, a[i]) - genRdVar(c, a[i], v, {gfAddrOf}) - c.gABC(n, opcWrObj, v, tmp, i) - # XXX globals? - c.freeTemp(tmp) + c.gen(lowerTupleUnpacking(a, c.getOwner)) elif a.sons[0].kind == nkSym: let s = a.sons[0].sym checkCanEval(c, a.sons[0]) @@ -1581,7 +1584,7 @@ proc genProc(c: PCtx; s: PSym): int = c.gABC(body, opcEof, eofInstr.regA) c.optimizeJumps(result) s.offset = c.prc.maxSlots - #if s.name.s == "foo": + #if s.name.s == "tupleUnpack": # echo renderTree(body) # c.echoCode(result) c.prc = oldPrc |