inlining of 'var openarray' iterators now work

This commit is contained in:
Araq 2011-08-18 18:52:05 +02:00
commit 257b16ca34
3 changed files with 49 additions and 26 deletions

View file

@ -668,7 +668,7 @@ proc genOpenArrayElem(p: BProc, e: PNode, d: var TLoc) =
var a, b: TLoc var a, b: TLoc
initLocExpr(p, e.sons[0], a) initLocExpr(p, e.sons[0], a)
initLocExpr(p, e.sons[1], b) # emit range check: initLocExpr(p, e.sons[1], b) # emit range check:
if (optBoundsCheck in p.options): if optBoundsCheck in p.options:
appcg(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len0)) #raiseIndexError();$n", appcg(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len0)) #raiseIndexError();$n",
[rdLoc(b), rdLoc(a)]) # BUGFIX: ``>=`` and not ``>``! [rdLoc(b), rdLoc(a)]) # BUGFIX: ``>=`` and not ``>``!
if d.k == locNone: d.s = a.s if d.k == locNone: d.s = a.s

View file

@ -290,7 +290,7 @@ proc unpackTuple(c: PTransf, n: PNode, father: PTransNode) =
proc introduceNewLocalVars(c: PTransf, n: PNode): PTransNode = proc introduceNewLocalVars(c: PTransf, n: PNode): PTransNode =
case n.kind case n.kind
of nkSym: of nkSym:
return transformSym(c, n) result = transformSym(c, n)
of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit: of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit:
# nothing to be done for leaves: # nothing to be done for leaves:
result = PTransNode(n) result = PTransNode(n)
@ -334,32 +334,54 @@ proc addVar(father, v: PNode) =
addSon(vpart, ast.emptyNode) addSon(vpart, ast.emptyNode)
addSon(father, vpart) addSon(father, vpart)
proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode = when false:
proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode =
case n.sons[0].kind
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
var m = n.sons[0].sons[0]
if m.kind == a or m.kind == b:
# addr ( nkConv ( deref ( x ) ) ) --> nkConv(x)
var x = copyTree(n)
x.sons[0].sons[0] = m.sons[0]
result = transform(c, x.sons[0])
else:
result = transformSons(c, n)
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
var m = n.sons[0].sons[1]
if m.kind == a or m.kind == b:
# addr ( nkConv ( deref ( x ) ) ) --> nkConv(x)
var x = copyTree(n)
x.sons[0].sons[1] = m.sons[0]
result = transform(c, x.sons[0])
else:
result = transformSons(c, n)
else:
if n.sons[0].kind == a or n.sons[0].kind == b:
# addr ( deref ( x )) --> x
result = transform(c, n.sons[0].sons[0])
else:
result = transformSons(c, n)
proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode =
result = transformSons(c, n)
var n = result.pnode
case n.sons[0].kind case n.sons[0].kind
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64: of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
var m = n.sons[0].sons[0] var m = n.sons[0].sons[0]
if (m.kind == a) or (m.kind == b): if m.kind == a or m.kind == b:
# addr ( nkConv ( deref ( x ) ) ) --> nkConv(x) # addr ( nkConv ( deref ( x ) ) ) --> nkConv(x)
var x = copyTree(n) n.sons[0].sons[0] = m.sons[0]
x.sons[0].sons[0] = m.sons[0] result = PTransNode(n.sons[0])
result = transform(c, x.sons[0]) of nkHiddenStdConv, nkHiddenSubConv, nkConv:
else:
result = transformSons(c, n)
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
var m = n.sons[0].sons[1] var m = n.sons[0].sons[1]
if (m.kind == a) or (m.kind == b): if m.kind == a or m.kind == b:
# addr ( nkConv ( deref ( x ) ) ) --> nkConv(x) # addr ( nkConv ( deref ( x ) ) ) --> nkConv(x)
var x = copyTree(n) n.sons[0].sons[1] = m.sons[0]
x.sons[0].sons[1] = m.sons[0] result = PTransNode(n.sons[0])
result = transform(c, x.sons[0]) else:
else: if n.sons[0].kind == a or n.sons[0].kind == b:
result = transformSons(c, n)
else:
if (n.sons[0].kind == a) or (n.sons[0].kind == b):
# addr ( deref ( x )) --> x # addr ( deref ( x )) --> x
result = transform(c, n.sons[0].sons[0]) result = PTransNode(n.sons[0].sons[0])
else:
result = transformSons(c, n)
proc transformConv(c: PTransf, n: PNode): PTransNode = proc transformConv(c: PTransf, n: PNode): PTransNode =
# numeric types need range checks: # numeric types need range checks:
@ -498,9 +520,10 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
of paVarAsgn: of paVarAsgn:
assert(skipTypes(formal.typ, abstractInst).kind == tyVar) assert(skipTypes(formal.typ, abstractInst).kind == tyVar)
# XXX why is this even necessary? # XXX why is this even necessary?
var b = newNodeIT(nkHiddenAddr, arg.info, formal.typ) when false:
b.add(arg) var b = newNodeIT(nkHiddenAddr, arg.info, formal.typ)
arg = b b.add(arg)
arg = b
IdNodeTablePut(newC.mapping, formal, arg) IdNodeTablePut(newC.mapping, formal, arg)
# XXX BUG still not correct if the arg has a side effect! # XXX BUG still not correct if the arg has a side effect!
#InternalError(arg.info, "not implemented: pass to var parameter") #InternalError(arg.info, "not implemented: pass to var parameter")

View file

@ -1,6 +1,6 @@
discard """ discard """
file: "titer2.nim" file: "titer2.nim"
msg: "internal error: not implemented: pass to var parameter" output: "123"
""" """
# Try to break the transformation pass: # Try to break the transformation pass:
iterator iterAndZero(a: var openArray[int]): int = iterator iterAndZero(a: var openArray[int]): int =