VM produces objects.

This commit is contained in:
Yuriy Glukhov
2015-09-03 12:51:21 +03:00
parent 0320c0c73b
commit 04a4f35400
6 changed files with 43 additions and 23 deletions

View File

@@ -38,14 +38,16 @@ proc annotateType*(n: PNode, t: PType) =
# Note: x can be unequal to t and we need to be careful to use 't'
# to not to skip tyGenericInst
case n.kind
of nkObjConstr:
n.typ = t
for i in 1 .. <n.len:
let field = x.n.ithField(i - 1)
if field.isNil: globalError n.info, "invalid field at index " & $i
else:
internalAssert(n.sons[i].kind == nkExprColonExpr)
annotateType(n.sons[i].sons[1], field.typ)
of nkPar:
if x.kind == tyObject:
n.typ = t
for i in 0 .. <n.len:
let field = x.n.ithField(i)
if field.isNil: globalError n.info, "invalid field at index " & $i
else: annotateType(n.sons[i], field.typ)
elif x.kind == tyTuple:
if x.kind == tyTuple:
n.typ = t
for i in 0 .. <n.len:
if i >= x.len: globalError n.info, "invalid field at index " & $i
@@ -53,7 +55,7 @@ proc annotateType*(n: PNode, t: PType) =
elif x.kind == tyProc and x.callConv == ccClosure:
n.typ = t
else:
globalError(n.info, "() must have an object or tuple type")
globalError(n.info, "() must have a tuple type")
of nkBracket:
if x.kind in {tyArrayConstr, tyArray, tySequence, tyOpenArray}:
n.typ = t

View File

@@ -83,7 +83,7 @@ proc stackTrace(c: PCtx, tos: PStackFrame, pc: int,
proc bailOut(c: PCtx; tos: PStackFrame) =
stackTrace(c, tos, c.exceptionInstr, errUnhandledExceptionX,
c.currentExceptionA.sons[2].strVal)
c.currentExceptionA.sons[3].skipColon.strVal)
when not defined(nimComputedGoto):
{.pragma: computedGoto.}
@@ -383,7 +383,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
let instr = c.code[pc]
let ra = instr.regA
#if c.traceActive:
# echo "PC ", pc, " ", c.code[pc].opcode, " ra ", ra
#echo "PC ", pc, " ", c.code[pc].opcode, " ra ", ra, " rb ", instr.regB, " rc ", instr.regC
# message(c.debug[pc], warnUser, "Trace")
case instr.opcode
@@ -475,14 +475,19 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
decodeBC(rkNode)
let src = regs[rb].node
if src.kind notin {nkEmpty..nkNilLit}:
let n = src.sons[rc].skipColon
let n = src.sons[rc + ord(src.kind == nkObjConstr)].skipColon
regs[ra].node = n
else:
stackTrace(c, tos, pc, errNilAccess)
of opcWrObj:
# a.b = c
decodeBC(rkNode)
putIntoNode(regs[ra].node.sons[rb], regs[rc])
let shiftedRb = rb + ord(regs[ra].node.kind == nkObjConstr)
let dest = regs[ra].node
if dest.sons[shiftedRb].kind == nkExprColonExpr:
putIntoNode(dest.sons[shiftedRb].sons[1], regs[rc])
else:
putIntoNode(dest.sons[shiftedRb], regs[rc])
of opcWrStrIdx:
decodeBC(rkNode)
let idx = regs[rb].intVal.int

View File

@@ -1392,7 +1392,10 @@ proc getNullValueAux(obj: PNode, result: PNode) =
for i in countup(1, sonsLen(obj) - 1):
getNullValueAux(lastSon(obj.sons[i]), result)
of nkSym:
addSon(result, getNullValue(obj.sym.typ, result.info))
let field = newNodeI(nkExprColonExpr, result.info)
field.add(obj)
field.add(getNullValue(obj.sym.typ, result.info))
addSon(result, field)
else: globalError(result.info, "cannot create null element for: " & $obj)
proc getNullValue(typ: PType, info: TLineInfo): PNode =
@@ -1418,7 +1421,8 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
result.add(newNodeIT(nkNilLit, info, t))
result.add(newNodeIT(nkNilLit, info, t))
of tyObject:
result = newNodeIT(nkPar, info, t)
result = newNodeIT(nkObjConstr, info, t)
result.add(newNodeIT(nkEmpty, info, t))
getNullValueAux(t.n, result)
# initialize inherited fields:
var base = t.sons[0]

View File

@@ -36,8 +36,8 @@ proc getField(n: PNode; position: int): PSym =
proc storeAny(s: var string; t: PType; a: PNode; stored: var IntSet)
proc storeObj(s: var string; typ: PType; x: PNode; stored: var IntSet) =
internalAssert x.kind in {nkObjConstr, nkPar}
let start = ord(x.kind == nkObjConstr)
internalAssert x.kind == nkObjConstr
let start = 1
for i in countup(start, sonsLen(x) - 1):
if i > start: s.add(", ")
var it = x.sons[i]
@@ -205,18 +205,23 @@ proc loadAny(p: var JsonParser, t: PType,
of tyObject:
if p.kind != jsonObjectStart: raiseParseErr(p, "'{' expected for an object")
next(p)
result = newNode(nkPar)
result.sons = @[]
result = newNode(nkObjConstr)
result.sons = @[newNode(nkEmpty)]
while p.kind != jsonObjectEnd and p.kind != jsonEof:
if p.kind != jsonString:
raiseParseErr(p, "string expected for a field name")
let field = lookupInRecord(t.n, getIdent(p.str))
let ident = getIdent(p.str)
let field = lookupInRecord(t.n, ident)
if field.isNil:
raiseParseErr(p, "unknown field for object of type " & typeToString(t))
next(p)
if field.position >= result.sons.len:
setLen(result.sons, field.position+1)
result.sons[field.position] = loadAny(p, field.typ, tab)
let pos = field.position + 1
if pos >= result.sons.len:
setLen(result.sons, pos + 1)
let fieldNode = newNode(nkExprColonExpr)
fieldNode.addSon(newSymNode(newSym(skField, ident, nil, unknownLineInfo())))
fieldNode.addSon(loadAny(p, field.typ, tab))
result.sons[pos] = fieldNode
if p.kind == jsonObjectEnd: next(p)
else: raiseParseErr(p, "'}' end of object expected")
of tySet:

View File

@@ -46,7 +46,7 @@ template wrap2svoid(op) {.immediate, dirty.} =
proc getCurrentExceptionMsgWrapper(a: VmArgs) {.nimcall.} =
setResult(a, if a.currentException.isNil: ""
else: a.currentException.sons[2].strVal)
else: a.currentException.sons[3].skipColon.strVal)
proc registerAdditionalOps*(c: PCtx) =
wrap1f(sqrt)

View File

@@ -62,6 +62,10 @@ News
* ``libeay32.dll``: Split into ``libeay32.dll`` and ``libeay64.dll``.
Compile with ``-d:nimOldDLLs`` to make the stdlib use the old DLL names.
- Nim VM now treats objects as nkObjConstr nodes, and not nkPar nodes as it
was previously. Macros that generate nkPar nodes when object is expected are
likely to break. Macros that expect nkPar nodes to which objects are passed
are likely to break as well.
Library additions