finally got rid of nkPassAsOpenArray

This commit is contained in:
Araq 2011-08-16 08:56:53 +02:00
commit b0742c5b27
12 changed files with 50 additions and 72 deletions

View file

@ -112,7 +112,6 @@ type
nkChckRange, # range check for ints nkChckRange, # range check for ints
nkStringToCString, # string to cstring nkStringToCString, # string to cstring
nkCStringToString, # cstring to string nkCStringToString, # cstring to string
nkPassAsOpenArray, # thing is passed as an open array
# end of expressions # end of expressions
nkAsgn, # a = b nkAsgn, # a = b

View file

@ -819,6 +819,29 @@ proc fixupCall(p: BProc, t: PNode, d: var TLoc, pl: PRope) =
app(p.s[cpsStmts], pl) app(p.s[cpsStmts], pl)
app(p.s[cpsStmts], ';' & tnl) app(p.s[cpsStmts], ';' & tnl)
proc openArrayLoc(a: TLoc): PRope =
case skipTypes(a.t, abstractVar).kind
of tyOpenArray:
result = ropef("$1, $1Len0", [rdLoc(a)])
of tyString, tySequence:
result = ropef("$1->data, $1->$2", [rdLoc(a), lenField()])
of tyArray, tyArrayConstr:
result = ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))])
else: InternalError("openArrayLoc: " & typeToString(a.t))
proc genArg(p: BProc, n: PNode, param: PSym): PRope =
var a: TLoc
if skipTypes(param.typ, abstractVar).kind == tyOpenArray:
var n = if n.kind != nkHiddenAddr: n else: n.sons[0]
initLocExpr(p, n, a)
result = openArrayLoc(a)
elif ccgIntroducedPtr(param):
initLocExpr(p, n, a)
result = addrLoc(a)
else:
initLocExpr(p, n, a)
result = rdLoc(a)
proc genCall(p: BProc, t: PNode, d: var TLoc) = proc genCall(p: BProc, t: PNode, d: var TLoc) =
var op, a: TLoc var op, a: TLoc
# this is a hotspot in the compiler # this is a hotspot in the compiler
@ -828,14 +851,12 @@ proc genCall(p: BProc, t: PNode, d: var TLoc) =
assert(typ.kind == tyProc) assert(typ.kind == tyProc)
var length = sonsLen(t) var length = sonsLen(t)
for i in countup(1, length - 1): for i in countup(1, length - 1):
initLocExpr(p, t.sons[i], a) # generate expression for param
assert(sonsLen(typ) == sonsLen(typ.n)) assert(sonsLen(typ) == sonsLen(typ.n))
if i < sonsLen(typ): if i < sonsLen(typ):
assert(typ.n.sons[i].kind == nkSym) assert(typ.n.sons[i].kind == nkSym)
var param = typ.n.sons[i].sym app(pl, genArg(p, t.sons[i], typ.n.sons[i].sym))
if ccgIntroducedPtr(param): app(pl, addrLoc(a))
else: app(pl, rdLoc(a))
else: else:
initLocExpr(p, t.sons[i], a) # generate expression for param
app(pl, rdLoc(a)) app(pl, rdLoc(a))
if i < length - 1: app(pl, ", ") if i < length - 1: app(pl, ", ")
fixupCall(p, t, d, pl) fixupCall(p, t, d, pl)
@ -847,26 +868,22 @@ proc genInfixCall(p: BProc, t: PNode, d: var TLoc) =
var typ = t.sons[0].typ # getUniqueType() is too expensive here! var typ = t.sons[0].typ # getUniqueType() is too expensive here!
assert(typ.kind == tyProc) assert(typ.kind == tyProc)
var length = sonsLen(t) var length = sonsLen(t)
initLocExpr(p, t.sons[1], a) # generate expression for first param
assert(sonsLen(typ) == sonsLen(typ.n)) assert(sonsLen(typ) == sonsLen(typ.n))
var param = typ.n.sons[1].sym var param = typ.n.sons[1].sym
if ccgIntroducedPtr(param): app(pl, addrLoc(a)) app(pl, genArg(p, t.sons[1], param))
else: app(pl, rdLoc(a))
if skipTypes(param.typ, {tyGenericInst}).kind == tyPtr: app(pl, "->") if skipTypes(param.typ, {tyGenericInst}).kind == tyPtr: app(pl, "->")
else: app(pl, ".") else: app(pl, ".")
app(pl, op.r) app(pl, op.r)
app(pl, "(") app(pl, "(")
for i in countup(2, length - 1): for i in countup(2, length - 1):
initLocExpr(p, t.sons[i], a) # generate expression for param
assert(sonsLen(typ) == sonsLen(typ.n)) assert(sonsLen(typ) == sonsLen(typ.n))
if i < sonsLen(typ): if i < sonsLen(typ):
assert(typ.n.sons[i].kind == nkSym) assert(typ.n.sons[i].kind == nkSym)
var param = typ.n.sons[i].sym app(pl, genArg(p, t.sons[i], typ.n.sons[i].sym))
if ccgIntroducedPtr(param): app(pl, addrLoc(a))
else: app(pl, rdLoc(a))
else: else:
initLocExpr(p, t.sons[i], a) # generate expression for param
app(pl, rdLoc(a)) app(pl, rdLoc(a))
if i < length - 1: app(pl, ", ") if i < length - 1: app(pl, ", ")
fixupCall(p, t, d, pl) fixupCall(p, t, d, pl)
@ -882,30 +899,22 @@ proc genNamedParamCall(p: BProc, t: PNode, d: var TLoc) =
assert(sonsLen(typ) == sonsLen(typ.n)) assert(sonsLen(typ) == sonsLen(typ.n))
if length > 1: if length > 1:
initLocExpr(p, t.sons[1], a) app(pl, genArg(p, t.sons[1], typ.n.sons[1].sym))
var param = typ.n.sons[1].sym
if ccgIntroducedPtr(param): app(pl, addrLoc(a))
else: app(pl, rdLoc(a))
app(pl, " ") app(pl, " ")
app(pl, op.r) app(pl, op.r)
if length > 2: if length > 2:
initLocExpr(p, t.sons[2], a)
app(pl, ": ") app(pl, ": ")
var param = typ.n.sons[2].sym app(pl, genArg(p, t.sons[2], typ.n.sons[2].sym))
if ccgIntroducedPtr(param): app(pl, addrLoc(a))
else: app(pl, rdLoc(a))
for i in countup(3, length-1): for i in countup(3, length-1):
initLocExpr(p, t.sons[i], a) # generate expression for param
assert(sonsLen(typ) == sonsLen(typ.n)) assert(sonsLen(typ) == sonsLen(typ.n))
if i >= sonsLen(typ): if i >= sonsLen(typ):
InternalError(t.info, "varargs for objective C method?") InternalError(t.info, "varargs for objective C method?")
assert(typ.n.sons[i].kind == nkSym) assert(typ.n.sons[i].kind == nkSym)
var param = typ.n.sons[i].sym var param = typ.n.sons[i].sym
app(pl, " ") app(pl, " ")
app(pl, param.name.s) app(pl, param.name.s)
app(pl, ": ") app(pl, ": ")
if ccgIntroducedPtr(param): app(pl, addrLoc(a)) app(pl, genArg(p, t.sons[i], param))
else: app(pl, rdLoc(a))
if typ.sons[0] != nil: if typ.sons[0] != nil:
if isInvalidReturnType(typ.sons[0]): if isInvalidReturnType(typ.sons[0]):
if sonsLen(t) > 1: app(pl, " ") if sonsLen(t) > 1: app(pl, " ")
@ -1174,10 +1183,11 @@ proc genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) =
genAssignment(p, d, a, {}) genAssignment(p, d, a, {})
proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) = proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
var typ = skipTypes(e.sons[1].Typ, abstractPtrs) var a = e.sons[1]
if a.kind == nkHiddenAddr: a = a.sons[0]
var typ = skipTypes(a.Typ, abstractVar)
case typ.kind case typ.kind
of tyOpenArray: of tyOpenArray:
while e.sons[1].kind == nkPassAsOpenArray: e.sons[1] = e.sons[1].sons[0]
if op == mHigh: unaryExpr(p, e, d, "($1Len0-1)") if op == mHigh: unaryExpr(p, e, d, "($1Len0-1)")
else: unaryExpr(p, e, d, "$1Len0") else: unaryExpr(p, e, d, "$1Len0")
of tyCstring: of tyCstring:
@ -1386,23 +1396,6 @@ proc genRangeChck(p: BProc, n: PNode, d: var TLoc, magic: string) =
proc genConv(p: BProc, e: PNode, d: var TLoc) = proc genConv(p: BProc, e: PNode, d: var TLoc) =
genCast(p, e, d) genCast(p, e, d)
proc passToOpenArray(p: BProc, n: PNode, d: var TLoc) =
var a: TLoc
while n.sons[0].kind == nkPassAsOpenArray:
n.sons[0] = n.sons[0].sons[0] # BUGFIX
var dest = skipTypes(n.typ, abstractVar)
case skipTypes(n.sons[0].typ, abstractVar).kind
of tyOpenArray:
initLocExpr(p, n.sons[0], a)
putIntoDest(p, d, dest, ropef("$1, $1Len0", [rdLoc(a)]))
of tyString, tySequence:
initLocExpr(p, n.sons[0], a)
putIntoDest(p, d, dest, ropef("$1->data, $1->$2", [rdLoc(a), lenField()]))
of tyArray, tyArrayConstr:
initLocExpr(p, n.sons[0], a)
putIntoDest(p, d, dest, ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))]))
else: InternalError(n.sons[0].info, "passToOpenArray: " & typeToString(a.t))
proc convStrToCStr(p: BProc, n: PNode, d: var TLoc) = proc convStrToCStr(p: BProc, n: PNode, d: var TLoc) =
var a: TLoc var a: TLoc
initLocExpr(p, n.sons[0], a) initLocExpr(p, n.sons[0], a)
@ -1827,7 +1820,6 @@ proc expr(p: BProc, e: PNode, d: var TLoc) =
of nkChckRange: genRangeChck(p, e, d, "chckRange") of nkChckRange: genRangeChck(p, e, d, "chckRange")
of nkStringToCString: convStrToCStr(p, e, d) of nkStringToCString: convStrToCStr(p, e, d)
of nkCStringToString: convCStrToStr(p, e, d) of nkCStringToString: convCStrToStr(p, e, d)
of nkPassAsOpenArray: passToOpenArray(p, e, d)
of nkLambda: of nkLambda:
var sym = e.sons[namePos].sym var sym = e.sons[namePos].sym
genProc(p.module, sym) genProc(p.module, sym)

View file

@ -1390,7 +1390,6 @@ proc gen(p: var TProc, n: PNode, r: var TCompRes) =
of nkChckRange: genRangeChck(p, n, r, "chckRange") of nkChckRange: genRangeChck(p, n, r, "chckRange")
of nkStringToCString: convStrToCStr(p, n, r) of nkStringToCString: convStrToCStr(p, n, r)
of nkCStringToString: convCStrToStr(p, n, r) of nkCStringToString: convCStrToStr(p, n, r)
of nkPassAsOpenArray: gen(p, n.sons[0], r)
of nkStmtListExpr: genStmtListExpr(p, n, r) of nkStmtListExpr: genStmtListExpr(p, n, r)
of nkEmpty: nil of nkEmpty: nil
else: InternalError(n.info, "gen: unknown node type: " & $n.kind) else: InternalError(n.info, "gen: unknown node type: " & $n.kind)

View file

@ -1083,7 +1083,6 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
of nkChckRangeF, nkChckRange64, nkChckRange: result = evalRangeChck(c, n) of nkChckRangeF, nkChckRange64, nkChckRange: result = evalRangeChck(c, n)
of nkStringToCString: result = evalConvStrToCStr(c, n) of nkStringToCString: result = evalConvStrToCStr(c, n)
of nkCStringToString: result = evalConvCStrToStr(c, n) of nkCStringToString: result = evalConvCStrToStr(c, n)
of nkPassAsOpenArray: result = evalAux(c, n.sons[0], flags)
of nkStmtListExpr, nkStmtList, nkModule: of nkStmtListExpr, nkStmtList, nkModule:
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
result = evalAux(c, n.sons[i], flags) result = evalAux(c, n.sons[i], flags)

View file

@ -355,8 +355,7 @@ proc lsub(n: PNode): int =
of nkChckRangeF: result = len("chckRangeF") + 2 + lcomma(n) of nkChckRangeF: result = len("chckRangeF") + 2 + lcomma(n)
of nkChckRange64: result = len("chckRange64") + 2 + lcomma(n) of nkChckRange64: result = len("chckRange64") + 2 + lcomma(n)
of nkChckRange: result = len("chckRange") + 2 + lcomma(n) of nkChckRange: result = len("chckRange") + 2 + lcomma(n)
of nkObjDownConv, nkObjUpConv, nkStringToCString, nkCStringToString, of nkObjDownConv, nkObjUpConv, nkStringToCString, nkCStringToString:
nkPassAsOpenArray:
result = 2 result = 2
if sonsLen(n) >= 1: result = result + lsub(n.sons[0]) if sonsLen(n) >= 1: result = result + lsub(n.sons[0])
result = result + lcomma(n, 1) result = result + lcomma(n, 1)
@ -730,8 +729,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
put(g, tkParLe, "(") put(g, tkParLe, "(")
gcomma(g, n) gcomma(g, n)
put(g, tkParRi, ")") put(g, tkParRi, ")")
of nkObjDownConv, nkObjUpConv, nkStringToCString, nkCStringToString, of nkObjDownConv, nkObjUpConv, nkStringToCString, nkCStringToString:
nkPassAsOpenArray:
if sonsLen(n) >= 1: gsub(g, n.sons[0]) if sonsLen(n) >= 1: gsub(g, n.sons[0])
put(g, tkParLe, "(") put(g, tkParLe, "(")
gcomma(g, n, 1) gcomma(g, n, 1)

View file

@ -1224,8 +1224,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
of nkBlockExpr: result = semBlockExpr(c, n) of nkBlockExpr: result = semBlockExpr(c, n)
of nkHiddenStdConv, nkHiddenSubConv, nkConv, nkHiddenCallConv: of nkHiddenStdConv, nkHiddenSubConv, nkConv, nkHiddenCallConv:
checkSonsLen(n, 2) checkSonsLen(n, 2)
of nkStringToCString, nkCStringToString, nkPassAsOpenArray, nkObjDownConv, of nkStringToCString, nkCStringToString, nkObjDownConv, nkObjUpConv:
nkObjUpConv:
checkSonsLen(n, 1) checkSonsLen(n, 1)
of nkChckRangeF, nkChckRange64, nkChckRange: of nkChckRangeF, nkChckRange64, nkChckRange:
checkSonsLen(n, 3) checkSonsLen(n, 3)

View file

@ -375,7 +375,6 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
n) n)
of mLengthOpenArray: of mLengthOpenArray:
var a = n.sons[1] var a = n.sons[1]
if a.kind == nkPassAsOpenArray: a = a.sons[0]
if a.kind == nkBracket: if a.kind == nkBracket:
# we can optimize it away! This fixes the bug ``len(134)``. # we can optimize it away! This fixes the bug ``len(134)``.
result = newIntNodeT(sonsLen(a), n) result = newIntNodeT(sonsLen(a), n)

View file

@ -12,7 +12,7 @@ proc isExpr(n: PNode): bool =
case n.kind case n.kind
of nkIdent..nkNilLit: of nkIdent..nkNilLit:
result = true result = true
of nkCall..nkPassAsOpenArray: of nkCall..pred(nkAsgn):
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
if not isExpr(n.sons[i]): if not isExpr(n.sons[i]):
return false return false

View file

@ -341,7 +341,7 @@ proc analyse(c: PProcCtx, n: PNode): TThreadOwner =
of nkHiddenStdConv, nkHiddenSubConv, nkConv, nkCast: of nkHiddenStdConv, nkHiddenSubConv, nkConv, nkCast:
result = analyse(c, n.sons[1]) result = analyse(c, n.sons[1])
of nkStringToCString, nkCStringToString, nkChckRangeF, nkChckRange64, of nkStringToCString, nkCStringToString, nkChckRangeF, nkChckRange64,
nkChckRange, nkCheckedFieldExpr, nkPassAsOpenArray, nkObjDownConv, nkChckRange, nkCheckedFieldExpr, nkObjDownConv,
nkObjUpConv: nkObjUpConv:
result = analyse(c, n.sons[0]) result = analyse(c, n.sons[0])
of nkRaiseStmt: of nkRaiseStmt:

View file

@ -499,13 +499,13 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
result = copyTree(arg) result = copyTree(arg)
result.typ = getInstantiatedType(c, arg, m, f) result.typ = getInstantiatedType(c, arg, m, f)
# BUG: f may not be the right key! # BUG: f may not be the right key!
if (skipTypes(result.typ, abstractVar).kind in {tyTuple, tyOpenArray}): if (skipTypes(result.typ, abstractVar).kind in {tyTuple}):
result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c) result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
# BUGFIX: use ``result.typ`` and not `f` here # BUGFIX: use ``result.typ`` and not `f` here
of isEqual: of isEqual:
inc(m.exactMatches) inc(m.exactMatches)
result = copyTree(arg) result = copyTree(arg)
if (skipTypes(f, abstractVar).kind in {tyTuple, tyOpenArray}): if (skipTypes(f, abstractVar).kind in {tyTuple}):
result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c) result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
of isNone: of isNone:
result = userConvMatch(c, m, f, a, arg) result = userConvMatch(c, m, f, a, arg)

View file

@ -268,10 +268,9 @@ proc transformLoopBody(c: PTransf, n: PNode): PTransNode =
proc skipConv(n: PNode): PNode = proc skipConv(n: PNode): PNode =
case n.kind case n.kind
of nkObjUpConv, nkObjDownConv, nkPassAsOpenArray, nkChckRange, nkChckRangeF, of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
nkChckRange64:
result = n.sons[0] result = n.sons[0]
of nkHiddenStdConv, nkHiddenSubConv, nkConv: of nkHiddenStdConv, nkHiddenSubConv, nkConv:
result = n.sons[1] result = n.sons[1]
else: result = n else: result = n
@ -337,11 +336,10 @@ proc addVar(father, v: PNode) =
proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode = proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode =
case n.sons[0].kind case n.sons[0].kind
of nkObjUpConv, nkObjDownConv, nkPassAsOpenArray, nkChckRange, nkChckRangeF, of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
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 ( nkPassAsOpenArray ( deref ( x ) ) ) --> nkPassAsOpenArray(x) # addr ( nkConv ( deref ( x ) ) ) --> nkConv(x)
var x = copyTree(n) var x = copyTree(n)
x.sons[0].sons[0] = m.sons[0] x.sons[0].sons[0] = m.sons[0]
result = transform(c, x.sons[0]) result = transform(c, x.sons[0])
@ -362,7 +360,7 @@ proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode =
result = transform(c, n.sons[0].sons[0]) result = transform(c, n.sons[0].sons[0])
else: else:
result = transformSons(c, n) 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:
var dest = skipTypes(n.typ, abstractVarRange) var dest = skipTypes(n.typ, abstractVarRange)
@ -397,8 +395,7 @@ proc transformConv(c: PTransf, n: PNode): PTransNode =
else: else:
result = transformSons(c, n) result = transformSons(c, n)
of tyOpenArray: of tyOpenArray:
result = newTransNode(nkPassAsOpenArray, n, 1) result = transform(c, n.sons[1])
result[0] = transform(c, n.sons[1])
of tyCString: of tyCString:
if source.kind == tyString: if source.kind == tyString:
result = newTransNode(nkStringToCString, n, 1) result = newTransNode(nkStringToCString, n, 1)
@ -441,10 +438,6 @@ proc transformConv(c: PTransf, n: PNode): PTransNode =
# happens sometimes for generated assignments, etc. # happens sometimes for generated assignments, etc.
else: else:
result = transformSons(c, n) result = transformSons(c, n)
proc skipPassAsOpenArray(n: PNode): PNode =
result = n
while result.kind == nkPassAsOpenArray: result = result.sons[0]
type type
TPutArgInto = enum TPutArgInto = enum
@ -491,7 +484,7 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
# generate access statements for the parameters (unless they are constant) # generate access statements for the parameters (unless they are constant)
pushTransCon(c, newC) pushTransCon(c, newC)
for i in countup(1, sonsLen(call) - 1): for i in countup(1, sonsLen(call) - 1):
var arg = skipPassAsOpenArray(transform(c, call.sons[i]).pnode) var arg = transform(c, call.sons[i]).pnode
var formal = skipTypes(newC.owner.typ, abstractInst).n.sons[i].sym var formal = skipTypes(newC.owner.typ, abstractInst).n.sons[i].sym
case putArgInto(arg, formal.typ) case putArgInto(arg, formal.typ)
of paDirectMapping: of paDirectMapping:

View file

@ -30,7 +30,7 @@ type
nnkHiddenSubConv, nnkHiddenCallConv, nnkConv, nnkCast, nnkHiddenSubConv, nnkHiddenCallConv, nnkConv, nnkCast,
nnkAddr, nnkHiddenAddr, nnkHiddenDeref, nnkObjDownConv, nnkAddr, nnkHiddenAddr, nnkHiddenDeref, nnkObjDownConv,
nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange, nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange,
nnkStringToCString, nnkCStringToString, nnkPassAsOpenArray, nnkAsgn, nnkStringToCString, nnkCStringToString, nnkAsgn,
nnkFastAsgn, nnkGenericParams, nnkFormalParams, nnkOfInherit, nnkFastAsgn, nnkGenericParams, nnkFormalParams, nnkOfInherit,
nnkModule, nnkProcDef, nnkMethodDef, nnkConverterDef, nnkModule, nnkProcDef, nnkMethodDef, nnkConverterDef,
nnkMacroDef, nnkTemplateDef, nnkIteratorDef, nnkOfBranch, nnkMacroDef, nnkTemplateDef, nnkIteratorDef, nnkOfBranch,