diff options
Diffstat (limited to 'compiler/vmmarshal.nim')
-rw-r--r-- | compiler/vmmarshal.nim | 69 |
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) |