diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index 6d254ca6f..31e5e5924 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -148,9 +148,52 @@ proc reifiedOpenArray(n: PNode): bool {.inline.} = else: result = true -proc openArrayLoc(p: BProc, formalType: PType, n: PNode): Rope = - var a: TLoc +proc genOpenArraySlice(p: BProc; q: PNode; formalType, destType: PType): (Rope, Rope) = + var a, b, c: TLoc + initLocExpr(p, q[1], a) + initLocExpr(p, q[2], b) + initLocExpr(p, q[3], c) + # but first produce the required index checks: + if optBoundsCheck in p.options: + genBoundsCheck(p, a, b, c) + let ty = skipTypes(a.t, abstractVar+{tyPtr}) + let dest = getTypeDesc(p.module, destType) + let lengthExpr = "($1)-($2)+1" % [rdLoc(c), rdLoc(b)] + case ty.kind + of tyArray: + let first = toInt64(firstOrd(p.config, ty)) + if first == 0: + result = ("($3*)(($1)+($2))" % [rdLoc(a), rdLoc(b), dest], + lengthExpr) + else: + result = ("($4*)($1)+(($2)-($3))" % + [rdLoc(a), rdLoc(b), intLiteral(first), dest], + lengthExpr) + of tyOpenArray, tyVarargs: + if reifiedOpenArray(q[1]): + result = ("($3*)($1.d)+($2)" % [rdLoc(a), rdLoc(b), dest], + lengthExpr) + else: + result = ("($3*)($1)+($2)" % [rdLoc(a), rdLoc(b), dest], + lengthExpr) + of tyUncheckedArray, tyCString: + result = ("($3*)($1)+($2)" % [rdLoc(a), rdLoc(b), dest], + lengthExpr) + of tyString, tySequence: + let atyp = skipTypes(a.t, abstractInst) + if formalType.skipTypes(abstractInst).kind in {tyVar} and atyp.kind == tyString and + optSeqDestructors in p.config.globalOptions: + linefmt(p, cpsStmts, "#nimPrepareStrMutationV2($1);$n", [byRefLoc(p, a)]) + if atyp.kind in {tyVar} and not compileToCpp(p.module): + result = ("($4*)(*$1)$3+($2)" % [rdLoc(a), rdLoc(b), dataField(p), dest], + lengthExpr) + else: + result = ("($4*)$1$3+($2)" % [rdLoc(a), rdLoc(b), dataField(p), dest], + lengthExpr) + else: + internalError(p.config, "openArrayLoc: " & typeToString(a.t)) +proc openArrayLoc(p: BProc, formalType: PType, n: PNode): Rope = var q = skipConv(n) var skipped = false while q.kind == nkStmtListExpr and q.len > 0: @@ -164,42 +207,10 @@ proc openArrayLoc(p: BProc, formalType: PType, n: PNode): Rope = for i in 0..