summary refs log tree commit diff stats
path: root/compiler/vmmarshal.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/vmmarshal.nim')
-rw-r--r--compiler/vmmarshal.nim69
1 files changed, 47 insertions, 22 deletions
diff --git a/compiler/vmmarshal.nim b/compiler/vmmarshal.nim
index ffd8e16d7..0e67ededa 100644
--- a/compiler/vmmarshal.nim
+++ b/compiler/vmmarshal.nim
@@ -9,15 +9,21 @@
 
 ## Implements marshaling for the VM.
 
-import streams, json, intsets, tables, ast, astalgo, idents, types, msgs,
+import ast, astalgo, idents, types, msgs,
   options, lineinfos
 
+import std/[streams, json, intsets, tables]
+
+when defined(nimPreviewSlimSystem):
+  import std/[assertions, formatfloat]
+
 proc ptrToInt(x: PNode): int {.inline.} =
   result = cast[int](x) # don't skip alignment
 
 proc getField(n: PNode; position: int): PSym =
   case n.kind
   of nkRecList:
+    result = nil
     for i in 0..<n.len:
       result = getField(n[i], position)
       if result != nil: return
@@ -32,7 +38,8 @@ proc getField(n: PNode; position: int): PSym =
       else: discard
   of nkSym:
     if n.sym.position == position: result = n.sym
-  else: discard
+    else: result = nil
+  else: result = nil
 
 proc storeAny(s: var string; t: PType; a: PNode; stored: var IntSet; conf: ConfigRef)
 
@@ -75,11 +82,11 @@ proc storeAny(s: var string; t: PType; a: PNode; stored: var IntSet;
       s.add("]")
   of tyTuple:
     s.add("{")
-    for i in 0..<t.len:
+    for i, ti in t.ikids:
       if i > 0: s.add(", ")
       s.add("\"Field" & $i)
       s.add("\": ")
-      storeAny(s, t[i], a[i].skipColon, stored, conf)
+      storeAny(s, ti, a[i].skipColon, stored, conf)
     s.add("}")
   of tyObject:
     s.add("{")
@@ -91,16 +98,17 @@ proc storeAny(s: var string; t: PType; a: PNode; stored: var IntSet;
       if i > 0: s.add(", ")
       if a[i].kind == nkRange:
         var x = copyNode(a[i][0])
-        storeAny(s, t.lastSon, x, stored, conf)
-        while x.intVal+1 <= a[i][1].intVal:
+        storeAny(s, t.elementType, x, stored, conf)
+        inc x.intVal
+        while x.intVal <= a[i][1].intVal:
           s.add(", ")
-          storeAny(s, t.lastSon, x, stored, conf)
+          storeAny(s, t.elementType, x, stored, conf)
           inc x.intVal
       else:
-        storeAny(s, t.lastSon, a[i], stored, conf)
+        storeAny(s, t.elementType, a[i], stored, conf)
     s.add("]")
   of tyRange, tyGenericInst, tyAlias, tySink:
-    storeAny(s, t.lastSon, a, stored, conf)
+    storeAny(s, t.skipModifier, a, stored, conf)
   of tyEnum:
     # we need a slow linear search because of enums with holes:
     for e in items(t.n):
@@ -119,9 +127,9 @@ proc storeAny(s: var string; t: PType; a: PNode; stored: var IntSet;
       s.add("[")
       s.add($x.ptrToInt)
       s.add(", ")
-      storeAny(s, t.lastSon, a, stored, conf)
+      storeAny(s, t.elementType, a, stored, conf)
       s.add("]")
-  of tyString, tyCString:
+  of tyString, tyCstring:
     if a.kind == nkNilLit: s.add("null")
     else: s.add(escapeJson(a.strVal))
   of tyInt..tyInt64, tyUInt..tyUInt64: s.add($a.intVal)
@@ -139,7 +147,9 @@ proc loadAny(p: var JsonParser, t: PType,
              conf: ConfigRef;
              idgen: IdGenerator): PNode =
   case t.kind
-  of tyNone: assert false
+  of tyNone:
+    result = nil
+    assert false
   of tyBool:
     case p.kind
     of jsonFalse: result = newIntNode(nkIntLit, 0)
@@ -149,6 +159,7 @@ proc loadAny(p: var JsonParser, t: PType,
   of tyChar:
     if p.kind == jsonString:
       var x = p.str
+      result = nil
       if x.len == 1:
         result = newIntNode(nkIntLit, ord(x[0]))
         next(p)
@@ -157,8 +168,11 @@ proc loadAny(p: var JsonParser, t: PType,
       result = newIntNode(nkIntLit, getInt(p))
       next(p)
       return
+    else:
+      result = nil
     raiseParseErr(p, "string of length 1 expected for a char")
   of tyEnum:
+    result = nil
     if p.kind == jsonString:
       for e in items(t.n):
         if e.sym.name.s == p.str:
@@ -187,17 +201,19 @@ proc loadAny(p: var JsonParser, t: PType,
       if p.kind == jsonArrayEnd: next(p)
       else: raiseParseErr(p, "")
     else:
+      result = nil
       raiseParseErr(p, "'[' expected for a seq")
   of tyTuple:
     if p.kind != jsonObjectStart: raiseParseErr(p, "'{' expected for an object")
     next(p)
     result = newNode(nkTupleConstr)
     var i = 0
+    let tupleLen = t.kidsLen
     while p.kind != jsonObjectEnd and p.kind != jsonEof:
       if p.kind != jsonString:
         raiseParseErr(p, "string expected for a field name")
       next(p)
-      if i >= t.len:
+      if i >= tupleLen:
         raiseParseErr(p, "too many fields to tuple type " & typeToString(t))
       result.add loadAny(p, t[i], tab, cache, conf, idgen)
       inc i
@@ -220,7 +236,7 @@ proc loadAny(p: var JsonParser, t: PType,
       if pos >= result.len:
         setLen(result.sons, pos + 1)
       let fieldNode = newNode(nkExprColonExpr)
-      fieldNode.add newSymNode(newSym(skField, ident, nextSymId(idgen), nil, unknownLineInfo))
+      fieldNode.add newSymNode(newSym(skField, ident, idgen, nil, unknownLineInfo))
       fieldNode.add loadAny(p, field.typ, tab, cache, conf, idgen)
       result[pos] = fieldNode
     if p.kind == jsonObjectEnd: next(p)
@@ -230,8 +246,7 @@ proc loadAny(p: var JsonParser, t: PType,
     next(p)
     result = newNode(nkCurly)
     while p.kind != jsonArrayEnd and p.kind != jsonEof:
-      result.add loadAny(p, t.lastSon, tab, cache, conf, idgen)
-      next(p)
+      result.add loadAny(p, t.elementType, tab, cache, conf, idgen)
     if p.kind == jsonArrayEnd: next(p)
     else: raiseParseErr(p, "']' end of array expected")
   of tyPtr, tyRef:
@@ -245,17 +260,20 @@ proc loadAny(p: var JsonParser, t: PType,
         raiseParseErr(p, "cannot load object with address " & $p.getInt)
       next(p)
     of jsonArrayStart:
+      result = nil
       next(p)
       if p.kind == jsonInt:
         let idx = p.getInt
         next(p)
-        result = loadAny(p, t.lastSon, tab, cache, conf, idgen)
+        result = loadAny(p, t.elementType, tab, cache, conf, idgen)
         tab[idx] = result
       else: raiseParseErr(p, "index for ref type expected")
       if p.kind == jsonArrayEnd: next(p)
       else: raiseParseErr(p, "']' end of ref-address pair expected")
-    else: raiseParseErr(p, "int for pointer type expected")
-  of tyString, tyCString:
+    else:
+      result = nil
+      raiseParseErr(p, "int for pointer type expected")
+  of tyString, tyCstring:
     case p.kind
     of jsonNull:
       result = newNode(nkNilLit)
@@ -263,27 +281,34 @@ proc loadAny(p: var JsonParser, t: PType,
     of jsonString:
       result = newStrNode(nkStrLit, p.str)
       next(p)
-    else: raiseParseErr(p, "string expected")
+    else:
+      result = nil
+      raiseParseErr(p, "string expected")
   of tyInt..tyInt64, tyUInt..tyUInt64:
     if p.kind == jsonInt:
       result = newIntNode(nkIntLit, getInt(p))
       next(p)
       return
+    else:
+      result = nil
     raiseParseErr(p, "int expected")
   of tyFloat..tyFloat128:
     if p.kind == jsonFloat:
       result = newFloatNode(nkFloatLit, getFloat(p))
       next(p)
       return
+    else:
+      result = nil
     raiseParseErr(p, "float expected")
   of tyRange, tyGenericInst, tyAlias, tySink:
-    result = loadAny(p, t.lastSon, tab, cache, conf, idgen)
+    result = loadAny(p, t.skipModifier, tab, cache, conf, idgen)
   else:
+    result = nil
     internalError conf, "cannot marshal at compile-time " & t.typeToString
 
 proc loadAny*(s: string; t: PType; cache: IdentCache; conf: ConfigRef; idgen: IdGenerator): PNode =
   var tab = initTable[BiggestInt, PNode]()
-  var p: JsonParser
+  var p: JsonParser = default(JsonParser)
   open(p, newStringStream(s), "unknown file")
   next(p)
   result = loadAny(p, t, tab, cache, conf, idgen)