Merge pull request #3283 from yglukhov/vm-fix

VM produces objects.
This commit is contained in:
Andreas Rumpf 2015-09-05 13:32:30 +02:00
commit 30b1baf1af
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' # Note: x can be unequal to t and we need to be careful to use 't'
# to not to skip tyGenericInst # to not to skip tyGenericInst
case n.kind case n.kind
of nkPar: of nkObjConstr:
if x.kind == tyObject:
n.typ = t n.typ = t
for i in 0 .. <n.len: for i in 1 .. <n.len:
let field = x.n.ithField(i) let field = x.n.ithField(i - 1)
if field.isNil: globalError n.info, "invalid field at index " & $i if field.isNil: globalError n.info, "invalid field at index " & $i
else: annotateType(n.sons[i], field.typ) else:
elif x.kind == tyTuple: internalAssert(n.sons[i].kind == nkExprColonExpr)
annotateType(n.sons[i].sons[1], field.typ)
of nkPar:
if x.kind == tyTuple:
n.typ = t n.typ = t
for i in 0 .. <n.len: for i in 0 .. <n.len:
if i >= x.len: globalError n.info, "invalid field at index " & $i 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: elif x.kind == tyProc and x.callConv == ccClosure:
n.typ = t n.typ = t
else: else:
globalError(n.info, "() must have an object or tuple type") globalError(n.info, "() must have a tuple type")
of nkBracket: of nkBracket:
if x.kind in {tyArrayConstr, tyArray, tySequence, tyOpenArray}: if x.kind in {tyArrayConstr, tyArray, tySequence, tyOpenArray}:
n.typ = t n.typ = t

View file

@ -83,7 +83,7 @@ proc stackTrace(c: PCtx, tos: PStackFrame, pc: int,
proc bailOut(c: PCtx; tos: PStackFrame) = proc bailOut(c: PCtx; tos: PStackFrame) =
stackTrace(c, tos, c.exceptionInstr, errUnhandledExceptionX, stackTrace(c, tos, c.exceptionInstr, errUnhandledExceptionX,
c.currentExceptionA.sons[2].strVal) c.currentExceptionA.sons[3].skipColon.strVal)
when not defined(nimComputedGoto): when not defined(nimComputedGoto):
{.pragma: computedGoto.} {.pragma: computedGoto.}
@ -383,7 +383,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
let instr = c.code[pc] let instr = c.code[pc]
let ra = instr.regA let ra = instr.regA
#if c.traceActive: #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") # message(c.debug[pc], warnUser, "Trace")
case instr.opcode case instr.opcode
@ -475,14 +475,19 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
decodeBC(rkNode) decodeBC(rkNode)
let src = regs[rb].node let src = regs[rb].node
if src.kind notin {nkEmpty..nkNilLit}: 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 regs[ra].node = n
else: else:
stackTrace(c, tos, pc, errNilAccess) stackTrace(c, tos, pc, errNilAccess)
of opcWrObj: of opcWrObj:
# a.b = c # a.b = c
decodeBC(rkNode) 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: of opcWrStrIdx:
decodeBC(rkNode) decodeBC(rkNode)
let idx = regs[rb].intVal.int 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): for i in countup(1, sonsLen(obj) - 1):
getNullValueAux(lastSon(obj.sons[i]), result) getNullValueAux(lastSon(obj.sons[i]), result)
of nkSym: 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) else: globalError(result.info, "cannot create null element for: " & $obj)
proc getNullValue(typ: PType, info: TLineInfo): PNode = 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))
result.add(newNodeIT(nkNilLit, info, t)) result.add(newNodeIT(nkNilLit, info, t))
of tyObject: of tyObject:
result = newNodeIT(nkPar, info, t) result = newNodeIT(nkObjConstr, info, t)
result.add(newNodeIT(nkEmpty, info, t))
getNullValueAux(t.n, result) getNullValueAux(t.n, result)
# initialize inherited fields: # initialize inherited fields:
var base = t.sons[0] 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 storeAny(s: var string; t: PType; a: PNode; stored: var IntSet)
proc storeObj(s: var string; typ: PType; x: PNode; stored: var IntSet) = proc storeObj(s: var string; typ: PType; x: PNode; stored: var IntSet) =
internalAssert x.kind in {nkObjConstr, nkPar} internalAssert x.kind == nkObjConstr
let start = ord(x.kind == nkObjConstr) let start = 1
for i in countup(start, sonsLen(x) - 1): for i in countup(start, sonsLen(x) - 1):
if i > start: s.add(", ") if i > start: s.add(", ")
var it = x.sons[i] var it = x.sons[i]
@ -205,18 +205,23 @@ proc loadAny(p: var JsonParser, t: PType,
of tyObject: of tyObject:
if p.kind != jsonObjectStart: raiseParseErr(p, "'{' expected for an object") if p.kind != jsonObjectStart: raiseParseErr(p, "'{' expected for an object")
next(p) next(p)
result = newNode(nkPar) result = newNode(nkObjConstr)
result.sons = @[] result.sons = @[newNode(nkEmpty)]
while p.kind != jsonObjectEnd and p.kind != jsonEof: while p.kind != jsonObjectEnd and p.kind != jsonEof:
if p.kind != jsonString: if p.kind != jsonString:
raiseParseErr(p, "string expected for a field name") 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: if field.isNil:
raiseParseErr(p, "unknown field for object of type " & typeToString(t)) raiseParseErr(p, "unknown field for object of type " & typeToString(t))
next(p) next(p)
if field.position >= result.sons.len: let pos = field.position + 1
setLen(result.sons, field.position+1) if pos >= result.sons.len:
result.sons[field.position] = loadAny(p, field.typ, tab) 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) if p.kind == jsonObjectEnd: next(p)
else: raiseParseErr(p, "'}' end of object expected") else: raiseParseErr(p, "'}' end of object expected")
of tySet: of tySet:

View file

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

View file

@ -62,6 +62,10 @@ News
* ``libeay32.dll``: Split into ``libeay32.dll`` and ``libeay64.dll``. * ``libeay32.dll``: Split into ``libeay32.dll`` and ``libeay64.dll``.
Compile with ``-d:nimOldDLLs`` to make the stdlib use the old DLL names. 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 Library additions