VM produces objects.
This commit is contained in:
parent
0320c0c73b
commit
04a4f35400
6 changed files with 43 additions and 23 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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]
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue