From 57b7841c184e9f185d6d2404a1320e5d089e0e0f Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Sun, 27 Sep 2020 09:20:10 +0200 Subject: [PATCH] better support for slices as views (#15414) * moved view tests to tests/views * refactoring * more refactorings * better support for system.toOpenArray for first class view types --- compiler/ccgcalls.nim | 85 ++++++++++++--------- compiler/ccgexprs.nim | 12 ++- compiler/semexprs.nim | 10 ++- tests/{effects => views}/tcannot_borrow.nim | 0 tests/views/tsplit_into_openarray.nim | 37 +++++++++ tests/{ccgbugs => views}/tviews1.nim | 0 6 files changed, 100 insertions(+), 44 deletions(-) rename tests/{effects => views}/tcannot_borrow.nim (100%) create mode 100644 tests/views/tsplit_into_openarray.nim rename tests/{ccgbugs => views}/tviews1.nim (100%) 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..