summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2020-09-27 20:44:22 +0200
committerGitHub <noreply@github.com>2020-09-27 20:44:22 +0200
commitf1ac01459cfecdaa26fd26128bb586236d4ba24e (patch)
treea9273ea023b88c03b2006310ac57c0f5a0f040a3 /compiler
parent0ea559611d7cd4ba907a668af01302d52fa3eab9 (diff)
downloadNim-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.nim7
-rw-r--r--compiler/ccgexprs.nim22
-rw-r--r--compiler/ccgtypes.nim24
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: