diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2020-09-27 20:44:22 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-27 20:44:22 +0200 |
commit | f1ac01459cfecdaa26fd26128bb586236d4ba24e (patch) | |
tree | a9273ea023b88c03b2006310ac57c0f5a0f040a3 /compiler | |
parent | 0ea559611d7cd4ba907a668af01302d52fa3eab9 (diff) | |
download | Nim-f1ac01459cfecdaa26fd26128bb586236d4ba24e.tar.gz |
produce runtime type information for reified openArrays (#15415)
* produce runtime type information for reified openArrays * added a test case
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ccgcalls.nim | 7 | ||||
-rw-r--r-- | compiler/ccgexprs.nim | 22 | ||||
-rw-r--r-- | compiler/ccgtypes.nim | 24 |
3 files changed, 34 insertions, 19 deletions
diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index 31e5e5924..6f0d327d9 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -171,7 +171,7 @@ proc genOpenArraySlice(p: BProc; q: PNode; formalType, destType: PType): (Rope, lengthExpr) of tyOpenArray, tyVarargs: if reifiedOpenArray(q[1]): - result = ("($3*)($1.d)+($2)" % [rdLoc(a), rdLoc(b), dest], + result = ("($3*)($1.Field0)+($2)" % [rdLoc(a), rdLoc(b), dest], lengthExpr) else: result = ("($3*)($1)+($2)" % [rdLoc(a), rdLoc(b), dest], @@ -215,7 +215,10 @@ proc openArrayLoc(p: BProc, formalType: PType, n: PNode): Rope = case skipTypes(a.t, abstractVar).kind of tyOpenArray, tyVarargs: if reifiedOpenArray(n): - result = "$1.d, $1.l" % [rdLoc(a)] + if a.t.kind in {tyVar, tyLent}: + result = "$1->Field0, $1->Field1" % [rdLoc(a)] + else: + result = "$1.Field0, $1.Field1" % [rdLoc(a)] else: result = "$1, $1Len_0" % [rdLoc(a)] of tyString, tySequence: diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index f348a7e26..b6808a55e 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -278,23 +278,23 @@ proc genOpenArrayConv(p: BProc; d: TLoc; a: TLoc) = case a.t.skipTypes(abstractVar).kind of tyOpenArray, tyVarargs: if reifiedOpenArray(a.lode): - linefmt(p, cpsStmts, "$1.d = $2.d; $1.l = $2.l;$n", + linefmt(p, cpsStmts, "$1.Field0 = $2.Field0; $1.Field1 = $2.Field1;$n", [rdLoc(d), a.rdLoc]) else: - linefmt(p, cpsStmts, "$1.d = $2; $1.l = $2Len_0;$n", + linefmt(p, cpsStmts, "$1.Field0 = $2; $1.Field1 = $2Len_0;$n", [rdLoc(d), a.rdLoc]) of tySequence: - linefmt(p, cpsStmts, "$1.d = $2$3; $1.l = $4;$n", + linefmt(p, cpsStmts, "$1.Field0 = $2$3; $1.Field1 = $4;$n", [rdLoc(d), a.rdLoc, dataField(p), lenExpr(p, a)]) of tyArray: - linefmt(p, cpsStmts, "$1.d = $2; $1.l = $3;$n", + linefmt(p, cpsStmts, "$1.Field0 = $2; $1.Field1 = $3;$n", [rdLoc(d), rdLoc(a), rope(lengthOrd(p.config, a.t))]) of tyString: let etyp = skipTypes(a.t, abstractInst) if etyp.kind in {tyVar} and optSeqDestructors in p.config.globalOptions: linefmt(p, cpsStmts, "#nimPrepareStrMutationV2($1);$n", [byRefLoc(p, a)]) - linefmt(p, cpsStmts, "$1.d = $2$3; $1.l = $4;$n", + linefmt(p, cpsStmts, "$1.Field0 = $2$3; $1.Field1 = $4;$n", [rdLoc(d), a.rdLoc, dataField(p), lenExpr(p, a)]) else: internalError(p.config, a.lode.info, "cannot handle " & $a.t.kind) @@ -943,7 +943,7 @@ proc genBoundsCheck(p: BProc; arr, a, b: TLoc) = if reifiedOpenArray(arr.lode): linefmt(p, cpsStmts, "if ($2-$1 != -1 && " & - "((NU)($1) >= (NU)($3.l) || (NU)($2) >= (NU)($3.l))){ #raiseIndexError(); $4}$n", + "((NU)($1) >= (NU)($3.Field1) || (NU)($2) >= (NU)($3.Field1))){ #raiseIndexError(); $4}$n", [rdLoc(a), rdLoc(b), rdLoc(arr), raiseInstr(p)]) else: linefmt(p, cpsStmts, @@ -977,11 +977,11 @@ proc genOpenArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) = ropecg(p.module, "$1[$2]", [rdLoc(a), rdCharLoc(b)]), a.storage) else: if optBoundsCheck in p.options: - linefmt(p, cpsStmts, "if ((NU)($1) >= (NU)($2.l)){ #raiseIndexError2($1,$2.l-1); $3}$n", + linefmt(p, cpsStmts, "if ((NU)($1) >= (NU)($2.Field1)){ #raiseIndexError2($1,$2.Field1-1); $3}$n", [rdLoc(b), rdLoc(a), raiseInstr(p)]) # BUGFIX: ``>=`` and not ``>``! inheritLocation(d, a) putIntoDest(p, d, n, - ropecg(p.module, "$1.d[$2]", [rdLoc(a), rdCharLoc(b)]), a.storage) + ropecg(p.module, "$1.Field0[$2]", [rdLoc(a), rdCharLoc(b)]), a.storage) proc genSeqElem(p: BProc, n, x, y: PNode, d: var TLoc) = var a, b: TLoc @@ -1739,8 +1739,8 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) = if op == mHigh: unaryExpr(p, e, d, "($1Len_0-1)") else: unaryExpr(p, e, d, "$1Len_0") else: - if op == mHigh: unaryExpr(p, e, d, "($1.l-1)") - else: unaryExpr(p, e, d, "$1.l") + if op == mHigh: unaryExpr(p, e, d, "($1.Field1-1)") + else: unaryExpr(p, e, d, "$1.Field1") of tyCString: if op == mHigh: unaryExpr(p, e, d, "($1 ? (#nimCStrLen($1)-1) : -1)") else: unaryExpr(p, e, d, "($1 ? #nimCStrLen($1) : 0)") @@ -2218,7 +2218,7 @@ proc genDispose(p: BProc; n: PNode) = proc genSlice(p: BProc; e: PNode; d: var TLoc) = let (x, y) = genOpenArraySlice(p, e, e.typ, e.typ.lastSon) if d.k == locNone: getTemp(p, e.typ, d) - linefmt(p, cpsStmts, "$1.d = $2; $1.l = $3;$n", [rdLoc(d), x, y]) + linefmt(p, cpsStmts, "$1.Field0 = $2; $1.Field1 = $3;$n", [rdLoc(d), x, y]) when false: localError(p.config, e.info, "invalid context for 'toOpenArray'; " & "'toOpenArray' is only valid within a call expression") diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 771e1ede9..8dee6ee70 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -693,7 +693,7 @@ proc getOpenArrayDesc(m: BModule, t: PType, check: var IntSet; kind: TSymKind): result = getTypeName(m, t, sig) m.typeCache[sig] = result let elemType = getTypeDescWeak(m, t[0], check, kind) - m.s[cfsTypes].addf("typedef struct {$n$2* d;$nNI l;$n} $1;$n", + m.s[cfsTypes].addf("typedef struct {$n$2* Field0;$nNI Field1;$n} $1;$n", [result, elemType]) proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet; kind: TSymKind): Rope = @@ -724,7 +724,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet; kind: TSymKin compileToCpp(m): "&" else: "*" var et = origTyp.skipTypes(abstractInst).lastSon var etB = et.skipTypes(abstractInst) - if mapType(m.config, t, kind) == ctPtrToArray: + if mapType(m.config, t, kind) == ctPtrToArray and (etB.kind != tyOpenArray or kind == skParam): if etB.kind == tySet: et = getSysType(m.g.graph, unknownLineInfo, tyUInt8) else: @@ -1030,7 +1030,7 @@ proc genTypeInfoAuxBase(m: BModule; typ, origType: PType; if tfIncompleteStruct in typ.flags: size = rope"void*" else: - size = getTypeDesc(m, origType) + size = getTypeDesc(m, origType, skVar) m.s[cfsTypeInit3].addf( "$1.size = sizeof($2);$n$1.align = NIM_ALIGNOF($2);$n$1.kind = $3;$n$1.base = $4;$n", [nameHcr, size, rope(nimtypeKind), base] @@ -1128,7 +1128,7 @@ proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope; m.s[cfsTypeInit3].addf("$1.kind = 3;$n" & "$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" & "$1.name = $5;$n" & "$1.sons = &$6[0];$n" & - "$1.len = $7;$n", [expr, getTypeDesc(m, origType), field.loc.r, + "$1.len = $7;$n", [expr, getTypeDesc(m, origType, skVar), field.loc.r, genTypeInfoV1(m, field.typ, info), makeCString(field.name.s), tmp, rope(L)]) @@ -1165,7 +1165,7 @@ proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope; internalError(m.config, n.info, "genObjectFields") m.s[cfsTypeInit3].addf("$1.kind = 1;$n" & "$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" & - "$1.name = $5;$n", [expr, getTypeDesc(m, origType), + "$1.name = $5;$n", [expr, getTypeDesc(m, origType, skVar), field.loc.r, genTypeInfoV1(m, field.typ, info), makeCString(field.name.s)]) else: internalError(m.config, n.info, "genObjectFields") @@ -1201,7 +1201,7 @@ proc genTupleInfo(m: BModule, typ, origType: PType, name: Rope; info: TLineInfo) "$1.offset = offsetof($2, Field$3);$n" & "$1.typ = $4;$n" & "$1.name = \"Field$3\";$n", - [tmp2, getTypeDesc(m, origType), rope(i), genTypeInfoV1(m, a, info)]) + [tmp2, getTypeDesc(m, origType, skVar), rope(i), genTypeInfoV1(m, a, info)]) m.s[cfsTypeInit3].addf("$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n", [expr, rope(typ.len), tmp]) else: @@ -1387,6 +1387,15 @@ proc genTypeInfoV2(m: BModule, t: PType; info: TLineInfo): Rope = genTypeInfoV2Impl(m, t, origType, result, info) result = prefixTI.rope & result & ")".rope +proc openArrayToTuple(m: BModule; t: PType): PType = + result = newType(tyTuple, t.owner) + let p = newType(tyPtr, t.owner) + let a = newType(tyUncheckedArray, t.owner) + a.add t.lastSon + p.add a + result.add p + result.add getSysType(m.g.graph, t.owner.info, tyInt) + proc genTypeInfoV1(m: BModule, t: PType; info: TLineInfo): Rope = let origType = t var t = skipTypes(origType, irrelevantForBackend + tyUserTypeClasses) @@ -1461,6 +1470,9 @@ proc genTypeInfoV1(m: BModule, t: PType; info: TLineInfo): Rope = # BUGFIX: use consistently RTTI without proper field names; otherwise # results are not deterministic! genTupleInfo(m, t, origType, result, info) + of tyOpenArray: + let x = openArrayToTuple(m, t) + genTupleInfo(m, x, origType, result, info) else: internalError(m.config, "genTypeInfoV1(" & $t.kind & ')') if t.attachedOps[attachedDeepCopy] != nil: |