transf and vmgen compile again

This commit is contained in:
Andreas Rumpf 2018-05-12 09:38:41 +02:00
commit fedc136985
9 changed files with 234 additions and 223 deletions

View file

@ -120,7 +120,7 @@ proc gABI(c: PCtx; n: PNode; opc: TOpcode; a, b: TRegister; imm: BiggestInt) =
c.code.add(ins)
c.debug.add(n.info)
else:
localError(n.info, errGenerated,
localError(c.config, n.info,
"VM: immediate value does not fit into an int8")
proc gABx(c: PCtx; n: PNode; opc: TOpcode; a: TRegister = 0; bx: int) =
@ -137,7 +137,7 @@ proc gABx(c: PCtx; n: PNode; opc: TOpcode; a: TRegister = 0; bx: int) =
c.code.add(ins)
c.debug.add(n.info)
else:
localError(n.info, errGenerated,
localError(c.config, n.info,
"VM: immediate value does not fit into an int16")
proc xjmp(c: PCtx; n: PNode; opc: TOpcode; a: TRegister = 0): TPosition =
@ -151,7 +151,7 @@ proc genLabel(c: PCtx): TPosition =
proc jmpBack(c: PCtx, n: PNode, p = TPosition(0)) =
let dist = p.int - c.code.len
internalAssert(-0x7fff < dist and dist < 0x7fff)
internalAssert(c.config, -0x7fff < dist and dist < 0x7fff)
gABx(c, n, opcJmpBack, 0, dist)
proc patch(c: PCtx, p: TPosition) =
@ -159,7 +159,7 @@ proc patch(c: PCtx, p: TPosition) =
let p = p.int
let diff = c.code.len - p
#c.jumpTargets.incl(c.code.len)
internalAssert(-0x7fff < diff and diff < 0x7fff)
internalAssert(c.config, -0x7fff < diff and diff < 0x7fff)
let oldInstr = c.code[p]
# opcode and regA stay the same:
c.code[p] = ((oldInstr.uint32 and 0xffff'u32).uint32 or
@ -201,7 +201,7 @@ proc getTemp(cc: PCtx; tt: PType): TRegister =
c.slots[i] = (inUse: true, kind: k)
return TRegister(i)
if c.maxSlots >= high(TRegister):
globalError(cc.bestEffort, "VM problem: too many registers required")
globalError(cc.config, cc.bestEffort, "VM problem: too many registers required")
result = TRegister(c.maxSlots)
c.slots[c.maxSlots] = (inUse: true, kind: k)
inc c.maxSlots
@ -223,7 +223,7 @@ proc getTempRange(cc: PCtx; n: int; kind: TSlotKind): TRegister =
for k in result .. result+n-1: c.slots[k] = (inUse: true, kind: kind)
return
if c.maxSlots+n >= high(TRegister):
globalError(cc.bestEffort, "VM problem: too many registers required")
globalError(cc.config, cc.bestEffort, "VM problem: too many registers required")
result = TRegister(c.maxSlots)
inc c.maxSlots, n
for k in result .. result+n-1: c.slots[k] = (inUse: true, kind: kind)
@ -251,7 +251,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {})
proc gen(c: PCtx; n: PNode; dest: TRegister; flags: TGenFlags = {}) =
var d: TDest = dest
gen(c, n, d, flags)
#internalAssert d == dest # issue #7407
#internalAssert c.config, d == dest # issue #7407
proc gen(c: PCtx; n: PNode; flags: TGenFlags = {}) =
var tmp: TDest = -1
@ -261,7 +261,7 @@ proc gen(c: PCtx; n: PNode; flags: TGenFlags = {}) =
proc genx(c: PCtx; n: PNode; flags: TGenFlags = {}): TRegister =
var tmp: TDest = -1
gen(c, n, tmp, flags)
#internalAssert tmp >= 0 # 'nim check' does not like this internalAssert.
#internalAssert c.config, tmp >= 0 # 'nim check' does not like this internalAssert.
if tmp >= 0:
result = TRegister(tmp)
@ -320,7 +320,7 @@ proc genBreak(c: PCtx; n: PNode) =
if c.prc.blocks[i].label == n.sons[0].sym:
c.prc.blocks[i].fixups.add L1
return
globalError(n.info, errGenerated, "VM problem: cannot find 'break' target")
globalError(c.config, n.info, "VM problem: cannot find 'break' target")
else:
c.prc.blocks[c.prc.blocks.high].fixups.add L1
@ -378,7 +378,7 @@ proc rawGenLiteral(c: PCtx; n: PNode): int =
#assert(n.kind != nkCall)
n.flags.incl nfAllConst
c.constants.add n.canonValue
internalAssert result < 0x7fff
internalAssert c.config, result < 0x7fff
proc sameConstant*(a, b: PNode): bool =
result = false
@ -405,10 +405,10 @@ proc genLiteral(c: PCtx; n: PNode): int =
if sameConstant(c.constants[i], n): return i
result = rawGenLiteral(c, n)
proc unused(n: PNode; x: TDest) {.inline.} =
proc unused(c: PCtx; n: PNode; x: TDest) {.inline.} =
if x >= 0:
#debug(n)
globalError(n.info, "not unused")
globalError(c.config, n.info, "not unused")
proc genCase(c: PCtx; n: PNode; dest: var TDest) =
# if (!expr1) goto L1;
@ -424,7 +424,7 @@ proc genCase(c: PCtx; n: PNode; dest: var TDest) =
if not isEmptyType(n.typ):
if dest < 0: dest = getTemp(c, n.typ)
else:
unused(n, dest)
unused(c, n, dest)
var endings: seq[TPosition] = @[]
withTemp(tmp, n.sons[0].typ):
c.gen(n.sons[0], tmp)
@ -451,7 +451,7 @@ proc genType(c: PCtx; typ: PType): int =
if sameType(t, typ): return i
result = c.types.len
c.types.add(typ)
internalAssert(result <= 0x7fff)
internalAssert(c.config, result <= 0x7fff)
proc genTry(c: PCtx; n: PNode; dest: var TDest) =
if dest < 0 and not isEmptyType(n.typ): dest = getTemp(c, n.typ)
@ -525,7 +525,7 @@ proc genCall(c: PCtx; n: PNode; dest: var TDest) =
var r: TRegister = x+i
c.gen(n.sons[i], r)
if i >= fntyp.len:
internalAssert tfVarargs in fntyp.flags
internalAssert c.config, tfVarargs in fntyp.flags
c.gABx(n, opcSetType, r, c.genType(n.sons[i].typ))
if dest < 0:
c.gABC(n, opcIndCall, 0, x, n.len)
@ -540,12 +540,12 @@ proc needsAsgnPatch(n: PNode): bool =
n.kind in {nkBracketExpr, nkDotExpr, nkCheckedFieldExpr,
nkDerefExpr, nkHiddenDeref} or (n.kind == nkSym and n.sym.isGlobal)
proc genField(n: PNode): TRegister =
proc genField(c: PCtx; n: PNode): TRegister =
if n.kind != nkSym or n.sym.kind != skField:
globalError(n.info, "no field symbol")
globalError(c.config, n.info, "no field symbol")
let s = n.sym
if s.position > high(result):
globalError(n.info,
globalError(c.config, n.info,
"too large offset! cannot generate code for: " & s.name.s)
result = s.position
@ -572,7 +572,7 @@ proc genAsgnPatch(c: PCtx; le: PNode, value: TRegister) =
# XXX field checks here
let left = if le.kind == nkDotExpr: le else: le.sons[0]
let dest = c.genx(left.sons[0], {gfAddrOf, gfFieldAccess})
let idx = genField(left.sons[1])
let idx = genField(c, left.sons[1])
c.gABC(left, opcWrObj, dest, idx, value)
c.freeTemp(dest)
of nkDerefExpr, nkHiddenDeref:
@ -779,7 +779,7 @@ proc genIntCast(c: PCtx; n: PNode; dest: var TDest) =
let tmp3 = c.getTemp(n.sons[1].typ)
if dest < 0: dest = c.getTemp(n[0].typ)
proc mkIntLit(ival: int): int =
result = genLiteral(c, newIntTypeNode(nkIntLit, ival, getSysType(tyInt)))
result = genLiteral(c, newIntTypeNode(nkIntLit, ival, getSysType(c.graph, n.info, tyInt)))
if src.kind in unsignedIntegers and dst.kind in signedIntegers:
# cast unsigned to signed integer of same size
# signedVal = (unsignedVal xor offset) -% offset
@ -802,7 +802,7 @@ proc genIntCast(c: PCtx; n: PNode; dest: var TDest) =
c.freeTemp(tmp2)
c.freeTemp(tmp3)
else:
globalError(n.info, errGenerated, "VM is only allowed to 'cast' between integers of same size")
globalError(c.config, n.info, "VM is only allowed to 'cast' between integers of same size")
proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
case m
@ -818,7 +818,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
of mSucc, mAddI:
c.genAddSubInt(n, dest, opcAddInt)
of mInc, mDec:
unused(n, dest)
unused(c, n, dest)
let opc = if m == mInc: opcAddInt else: opcSubInt
let d = c.genx(n.sons[1])
if n.sons[2].isInt8Lit:
@ -832,10 +832,10 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
c.freeTemp(d)
of mOrd, mChr, mArrToSeq: c.gen(n.sons[1], dest)
of mNew, mNewFinalize:
unused(n, dest)
unused(c, n, dest)
c.genNew(n)
of mNewSeq:
unused(n, dest)
unused(c, n, dest)
c.genNewSeq(n)
of mNewSeqOfCap: c.genNewSeqOfCap(n, dest)
of mNewString:
@ -855,7 +855,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
of mLengthStr, mXLenStr:
genUnaryABI(c, n, dest, opcLenStr)
of mIncl, mExcl:
unused(n, dest)
unused(c, n, dest)
var d = c.genx(n.sons[1])
var tmp = c.genx(n.sons[2])
c.genSetType(n.sons[1], d)
@ -952,19 +952,19 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
of mInSet: genBinarySet(c, n, dest, opcContainsSet)
of mRepr: genUnaryABC(c, n, dest, opcRepr)
of mExit:
unused(n, dest)
unused(c, n, dest)
var tmp = c.genx(n.sons[1])
c.gABC(n, opcQuit, tmp)
c.freeTemp(tmp)
of mSetLengthStr, mSetLengthSeq:
unused(n, dest)
unused(c, n, dest)
var d = c.genx(n.sons[1])
var tmp = c.genx(n.sons[2])
c.gABC(n, if m == mSetLengthStr: opcSetLenStr else: opcSetLenSeq, d, tmp)
c.genAsgnPatch(n.sons[1], d)
c.freeTemp(tmp)
of mSwap:
unused(n, dest)
unused(c, n, dest)
c.gen(lowerSwap(n, if c.prc == nil: c.module else: c.prc.sym))
of mIsNil: genUnaryABC(c, n, dest, opcIsNil)
of mCopyStr:
@ -996,7 +996,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
# skip 'nkHiddenAddr':
let d2AsNode = n.sons[2].sons[0]
if needsAsgnPatch(d2AsNode):
d2 = c.getTemp(getSysType(tyFloat))
d2 = c.getTemp(getSysType(c.graph, n.info, tyFloat))
else:
d2 = c.genx(d2AsNode)
var
@ -1009,13 +1009,13 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
c.genAsgnPatch(d2AsNode, d2)
c.freeTemp(d2)
of mReset:
unused(n, dest)
unused(c, n, dest)
var d = c.genx(n.sons[1])
c.gABC(n, opcReset, d)
of mOf, mIs:
if dest < 0: dest = c.getTemp(n.typ)
var tmp = c.genx(n.sons[1])
var idx = c.getTemp(getSysType(tyInt))
var idx = c.getTemp(getSysType(c.graph, n.info, tyInt))
var typ = n.sons[2].typ
if m == mOf: typ = typ.skipTypes(abstractPtrs-{tyTypeDesc})
c.gABx(n, opcLdImmInt, idx, c.genType(typ))
@ -1023,7 +1023,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
c.freeTemp(tmp)
c.freeTemp(idx)
of mSizeOf:
globalError(n.info, errCannotInterpretNodeX, renderTree(n))
globalError(c.config, n.info, "cannot run in the VM: " & renderTree(n))
of mHigh:
if dest < 0: dest = c.getTemp(n.typ)
let tmp = c.genx(n.sons[1])
@ -1034,23 +1034,23 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
c.gABI(n, opcLenSeq, dest, tmp, 1)
c.freeTemp(tmp)
of mEcho:
unused(n, dest)
unused(c, n, dest)
let n = n[1].skipConv
let x = c.getTempRange(n.len, slotTempUnknown)
internalAssert n.kind == nkBracket
internalAssert c.config, n.kind == nkBracket
for i in 0..<n.len:
var r: TRegister = x+i
c.gen(n.sons[i], r)
c.gABC(n, opcEcho, x, n.len)
c.freeTempRange(x, n.len)
of mAppendStrCh:
unused(n, dest)
unused(c, n, dest)
genBinaryStmtVar(c, n, opcAddStrCh)
of mAppendStrStr:
unused(n, dest)
unused(c, n, dest)
genBinaryStmtVar(c, n, opcAddStrStr)
of mAppendSeqElem:
unused(n, dest)
unused(c, n, dest)
genBinaryStmtVar(c, n, opcAddSeqElem)
of mParseExprToAst:
genUnaryABC(c, n, dest, opcParseExprToAst)
@ -1068,7 +1068,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
of mGetImpl: genUnaryABC(c, n, dest, opcGetImpl)
of mNChild: genBinaryABC(c, n, dest, opcNChild)
of mNSetChild, mNDel:
unused(n, dest)
unused(c, n, dest)
var
tmp1 = c.genx(n.sons[1])
tmp2 = c.genx(n.sons[2])
@ -1098,22 +1098,22 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
#genUnaryABC(c, n, dest, opcNGetType)
of mNStrVal: genUnaryABC(c, n, dest, opcNStrVal)
of mNSetIntVal:
unused(n, dest)
unused(c, n, dest)
genBinaryStmt(c, n, opcNSetIntVal)
of mNSetFloatVal:
unused(n, dest)
unused(c, n, dest)
genBinaryStmt(c, n, opcNSetFloatVal)
of mNSetSymbol:
unused(n, dest)
unused(c, n, dest)
genBinaryStmt(c, n, opcNSetSymbol)
of mNSetIdent:
unused(n, dest)
unused(c, n, dest)
genBinaryStmt(c, n, opcNSetIdent)
of mNSetType:
unused(n, dest)
unused(c, n, dest)
genBinaryStmt(c, n, opcNSetType)
of mNSetStrVal:
unused(n, dest)
unused(c, n, dest)
genBinaryStmt(c, n, opcNSetStrVal)
of mNNewNimNode: genBinaryABC(c, n, dest, opcNNewNimNode)
of mNCopyNimNode: genUnaryABC(c, n, dest, opcNCopyNimNode)
@ -1124,7 +1124,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
if dest < 0: dest = c.getTemp(n.typ)
c.gABx(n, opcNBindSym, dest, idx)
else:
localError(n.info, "invalid bindSym usage")
localError(c.config, n.info, "invalid bindSym usage")
of mStrToIdent: genUnaryABC(c, n, dest, opcStrToIdent)
of mEqIdent: genBinaryABC(c, n, dest, opcEqIdent)
of mEqNimrodNode: genBinaryABC(c, n, dest, opcEqNimrodNode)
@ -1138,12 +1138,12 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
of "getColumn":
genUnaryABC(c, n, dest, opcNGetColumn)
else:
internalAssert false
internalAssert c.config, false
of mNHint:
unused(n, dest)
unused(c, n, dest)
genUnaryStmt(c, n, opcNHint)
of mNWarning:
unused(n, dest)
unused(c, n, dest)
genUnaryStmt(c, n, opcNWarning)
of mNError:
if n.len <= 1:
@ -1151,7 +1151,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
c.gABC(n, opcQueryErrorFlag, dest)
else:
# setter
unused(n, dest)
unused(c, n, dest)
genBinaryStmt(c, n, opcNError)
of mNCallSite:
if dest < 0: dest = c.getTemp(n.typ)
@ -1162,7 +1162,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
c.genCall(n, dest)
of mExpandToAst:
if n.len != 2:
globalError(n.info, errGenerated, "expandToAst requires 1 argument")
globalError(c.config, n.info, "expandToAst requires 1 argument")
let arg = n.sons[1]
if arg.kind in nkCallKinds:
#if arg[0].kind != nkSym or arg[0].sym.kind notin {skTemplate, skMacro}:
@ -1172,12 +1172,12 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
# do not call clearDest(n, dest) here as getAst has a meta-type as such
# produces a value
else:
globalError(n.info, "expandToAst requires a call expression")
globalError(c.config, n.info, "expandToAst requires a call expression")
of mRunnableExamples:
discard "just ignore any call to runnableExamples"
else:
# mGCref, mGCunref,
globalError(n.info, "cannot generate code for: " & $m)
globalError(c.config, n.info, "cannot generate code for: " & $m)
proc genMarshalLoad(c: PCtx, n: PNode, dest: var TDest) =
## Signature: proc to*[T](data: string): T
@ -1306,14 +1306,14 @@ proc setSlot(c: PCtx; v: PSym) =
if v.position == 0:
if c.prc.maxSlots == 0: c.prc.maxSlots = 1
if c.prc.maxSlots >= high(TRegister):
globalError(v.info, "cannot generate code; too many registers required")
globalError(c.config, v.info, "cannot generate code; too many registers required")
v.position = c.prc.maxSlots
c.prc.slots[v.position] = (inUse: true,
kind: if v.kind == skLet: slotFixedLet else: slotFixedVar)
inc c.prc.maxSlots
proc cannotEval(n: PNode) {.noinline.} =
globalError(n.info, errGenerated, "cannot evaluate at compile time: " &
proc cannotEval(c: PCtx; n: PNode) {.noinline.} =
globalError(c.config, n.info, "cannot evaluate at compile time: " &
n.renderTree)
proc isOwnedBy(a, b: PSym): bool =
@ -1333,10 +1333,10 @@ proc checkCanEval(c: PCtx; n: PNode) =
if {sfCompileTime, sfGlobal} <= s.flags: return
if s.kind in {skVar, skTemp, skLet, skParam, skResult} and
not s.isOwnedBy(c.prc.sym) and s.owner != c.module and c.mode != emRepl:
cannotEval(n)
cannotEval(c, n)
elif s.kind in {skProc, skFunc, skConverter, skMethod,
skIterator} and sfForward in s.flags:
cannotEval(n)
cannotEval(c, n)
proc isTemp(c: PCtx; dest: TDest): bool =
result = dest >= 0 and c.prc.slots[dest].kind >= slotTempUnknown
@ -1378,7 +1378,7 @@ proc genAsgn(c: PCtx; le, ri: PNode; requiresCopy: bool) =
# XXX field checks here
let left = if le.kind == nkDotExpr: le else: le.sons[0]
let dest = c.genx(left.sons[0], {gfAddrOf, gfFieldAccess})
let idx = genField(left.sons[1])
let idx = genField(c, left.sons[1])
let tmp = c.genx(ri)
c.preventFalseAlias(left, opcWrObj, dest, idx, tmp)
c.freeTemp(tmp)
@ -1398,7 +1398,7 @@ proc genAsgn(c: PCtx; le, ri: PNode; requiresCopy: bool) =
c.freeTemp(val)
else:
if s.kind == skForVar: c.setSlot s
internalAssert s.position > 0 or (s.position == 0 and
internalAssert c.config, s.position > 0 or (s.position == 0 and
s.kind in {skParam,skResult})
var dest: TRegister = s.position + ord(s.kind == skParam)
assert le.typ != nil
@ -1424,15 +1424,15 @@ proc importcSym(c: PCtx; info: TLineInfo; s: PSym) =
c.globals.add(importcSymbol(s))
s.position = c.globals.len
else:
localError(info, errGenerated, "VM is not allowed to 'importc'")
localError(c.config, info, "VM is not allowed to 'importc'")
else:
localError(info, errGenerated,
localError(c.config, info,
"cannot 'importc' variable at compile time")
proc getNullValue*(typ: PType, info: TLineInfo): PNode
proc getNullValue*(typ: PType, info: TLineInfo; conf: ConfigRef): PNode
proc genGlobalInit(c: PCtx; n: PNode; s: PSym) =
c.globals.add(getNullValue(s.typ, n.info))
c.globals.add(getNullValue(s.typ, n.info, c.config))
s.position = c.globals.len
# This is rather hard to support, due to the laziness of the VM code
# generator. See tests/compile/tmacro2 for why this is necessary:
@ -1451,7 +1451,7 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
if sfCompileTime in s.flags or c.mode == emRepl:
discard
elif s.position == 0:
cannotEval(n)
cannotEval(c, n)
if s.position == 0:
if sfImportc in s.flags: c.importcSym(n.info, s)
else: genGlobalInit(c, n, s)
@ -1472,13 +1472,13 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
s.kind in {skParam,skResult}):
if dest < 0:
dest = s.position + ord(s.kind == skParam)
internalAssert(c.prc.slots[dest].kind < slotSomeTemp)
internalAssert(c.config, c.prc.slots[dest].kind < slotSomeTemp)
else:
# we need to generate an assignment:
genAsgn(c, dest, n, c.prc.slots[dest].kind >= slotSomeTemp)
else:
# see tests/t99bott for an example that triggers it:
cannotEval(n)
cannotEval(c, n)
template needsRegLoad(): untyped =
gfAddrOf notin flags and fitsRegister(n.typ.skipTypes({tyVar, tyLent}))
@ -1502,7 +1502,7 @@ proc genArrAccess2(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
proc genObjAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
let a = c.genx(n.sons[0], flags)
let b = genField(n.sons[1])
let b = genField(c, n.sons[1])
if dest < 0: dest = c.getTemp(n.typ)
if needsRegLoad():
var cc = c.getTemp(n.typ)
@ -1526,22 +1526,22 @@ proc genArrAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
else:
genArrAccess2(c, n, dest, opcLdArr, flags)
proc getNullValueAux(obj: PNode, result: PNode) =
proc getNullValueAux(obj: PNode, result: PNode; conf: ConfigRef) =
case obj.kind
of nkRecList:
for i in countup(0, sonsLen(obj) - 1): getNullValueAux(obj.sons[i], result)
for i in countup(0, sonsLen(obj) - 1): getNullValueAux(obj.sons[i], result, conf)
of nkRecCase:
getNullValueAux(obj.sons[0], result)
getNullValueAux(obj.sons[0], result, conf)
for i in countup(1, sonsLen(obj) - 1):
getNullValueAux(lastSon(obj.sons[i]), result)
getNullValueAux(lastSon(obj.sons[i]), result, conf)
of nkSym:
let field = newNodeI(nkExprColonExpr, result.info)
field.add(obj)
field.add(getNullValue(obj.sym.typ, result.info))
field.add(getNullValue(obj.sym.typ, result.info, conf))
addSon(result, field)
else: globalError(result.info, "cannot create null element for: " & $obj)
else: globalError(conf, result.info, "cannot create null element for: " & $obj)
proc getNullValue(typ: PType, info: TLineInfo): PNode =
proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode =
var t = skipTypes(typ, abstractRange-{tyTypeDesc})
result = emptyNode
case t.kind
@ -1570,17 +1570,17 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
# initialize inherited fields:
var base = t.sons[0]
while base != nil:
getNullValueAux(skipTypes(base, skipPtrs).n, result)
getNullValueAux(skipTypes(base, skipPtrs).n, result, conf)
base = base.sons[0]
getNullValueAux(t.n, result)
getNullValueAux(t.n, result, conf)
of tyArray:
result = newNodeIT(nkBracket, info, t)
for i in countup(0, int(lengthOrd(t)) - 1):
addSon(result, getNullValue(elemType(t), info))
addSon(result, getNullValue(elemType(t), info, conf))
of tyTuple:
result = newNodeIT(nkTupleConstr, info, t)
for i in countup(0, sonsLen(t) - 1):
addSon(result, getNullValue(t.sons[i], info))
addSon(result, getNullValue(t.sons[i], info, conf))
of tySet:
result = newNodeIT(nkCurly, info, t)
of tyOpt:
@ -1588,7 +1588,7 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
of tySequence:
result = newNodeIT(nkBracket, info, t)
else:
globalError(info, "cannot create null element for: " & $t.kind)
globalError(conf, info, "cannot create null element for: " & $t.kind)
proc ldNullOpcode(t: PType): TOpcode =
assert t != nil
@ -1602,7 +1602,7 @@ proc genVarSection(c: PCtx; n: PNode) =
for i in 0 .. a.len-3:
if not a[i].sym.isGlobal: setSlot(c, a[i].sym)
checkCanEval(c, a[i])
c.gen(lowerTupleUnpacking(a, c.getOwner))
c.gen(lowerTupleUnpacking(c.graph, a, c.getOwner))
elif a.sons[0].kind == nkSym:
let s = a.sons[0].sym
checkCanEval(c, a.sons[0])
@ -1610,7 +1610,7 @@ proc genVarSection(c: PCtx; n: PNode) =
if s.position == 0:
if sfImportc in s.flags: c.importcSym(a.info, s)
else:
let sa = getNullValue(s.typ, a.info)
let sa = getNullValue(s.typ, a.info, c.config)
#if s.ast.isNil: getNullValue(s.typ, a.info)
#else: canonValue(s.ast)
assert sa.kind != nkCall
@ -1652,7 +1652,7 @@ proc genArrayConstr(c: PCtx, n: PNode, dest: var TDest) =
if dest < 0: dest = c.getTemp(n.typ)
c.gABx(n, opcLdNull, dest, c.genType(n.typ))
let intType = getSysType(tyInt)
let intType = getSysType(c.graph, n.info, tyInt)
let seqType = n.typ.skipTypes(abstractVar-{tyTypeDesc})
if seqType.kind == tySequence:
var tmp = c.getTemp(intType)
@ -1696,13 +1696,13 @@ proc genObjConstr(c: PCtx, n: PNode, dest: var TDest) =
for i in 1..<n.len:
let it = n.sons[i]
if it.kind == nkExprColonExpr and it.sons[0].kind == nkSym:
let idx = genField(it.sons[0])
let idx = genField(c, it.sons[0])
let tmp = c.genx(it.sons[1])
c.preventFalseAlias(it.sons[1], whichAsgnOpc(it.sons[1], opcWrObj),
dest, idx, tmp)
c.freeTemp(tmp)
else:
globalError(n.info, "invalid object constructor")
globalError(c.config, n.info, "invalid object constructor")
proc genTupleConstr(c: PCtx, n: PNode, dest: var TDest) =
if dest < 0: dest = c.getTemp(n.typ)
@ -1711,7 +1711,7 @@ proc genTupleConstr(c: PCtx, n: PNode, dest: var TDest) =
for i in 0..<n.len:
let it = n.sons[i]
if it.kind == nkExprColonExpr:
let idx = genField(it.sons[0])
let idx = genField(c, it.sons[0])
let tmp = c.genx(it.sons[1])
c.preventFalseAlias(it.sons[1], whichAsgnOpc(it.sons[1], opcWrObj),
dest, idx, tmp)
@ -1786,9 +1786,9 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
if c.prc.sym != nil and c.prc.sym.kind == skMacro:
genRdVar(c, n, dest, flags)
else:
globalError(n.info, errGenerated, "cannot generate code for: " & s.name.s)
globalError(c.config, n.info, "cannot generate code for: " & s.name.s)
else:
globalError(n.info, errGenerated, "cannot generate code for: " & s.name.s)
globalError(c.config, n.info, "cannot generate code for: " & s.name.s)
of nkCallKinds:
if n.sons[0].kind == nkSym:
let s = n.sons[0].sym
@ -1812,10 +1812,10 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
genLit(c, n, dest)
of nkUIntLit..pred(nkNilLit): genLit(c, n, dest)
of nkNilLit:
if not n.typ.isEmptyType: genLit(c, getNullValue(n.typ, n.info), dest)
else: unused(n, dest)
if not n.typ.isEmptyType: genLit(c, getNullValue(n.typ, n.info, c.config), dest)
else: unused(c, n, dest)
of nkAsgn, nkFastAsgn:
unused(n, dest)
unused(c, n, dest)
genAsgn(c, n.sons[0], n.sons[1], n.kind == nkAsgn)
of nkDotExpr: genObjAccess(c, n, dest, flags)
of nkCheckedFieldExpr: genCheckedObjAccess(c, n, dest, flags)
@ -1828,20 +1828,20 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
gen(c, n.sons[0].sons[1], dest)
of nkCaseStmt: genCase(c, n, dest)
of nkWhileStmt:
unused(n, dest)
unused(c, n, dest)
genWhile(c, n)
of nkBlockExpr, nkBlockStmt: genBlock(c, n, dest)
of nkReturnStmt:
unused(n, dest)
unused(c, n, dest)
genReturn(c, n)
of nkRaiseStmt:
genRaise(c, n)
of nkBreakStmt:
unused(n, dest)
unused(c, n, dest)
genBreak(c, n)
of nkTryStmt: genTry(c, n, dest)
of nkStmtList:
#unused(n, dest)
#unused(c, n, dest)
# XXX Fix this bug properly, lexim triggers it
for x in n: gen(c, x)
of nkStmtListExpr:
@ -1851,17 +1851,17 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
of nkPragmaBlock:
gen(c, n.lastSon, dest, flags)
of nkDiscardStmt:
unused(n, dest)
unused(c, n, dest)
gen(c, n.sons[0])
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
genConv(c, n, n.sons[1], dest)
of nkObjDownConv:
genConv(c, n, n.sons[0], dest)
of nkVarSection, nkLetSection:
unused(n, dest)
unused(c, n, dest)
genVarSection(c, n)
of declarativeDefs, nkMacroDef:
unused(n, dest)
unused(c, n, dest)
of nkLambdaKinds:
#let s = n.sons[namePos].sym
#discard genProc(c, s)
@ -1881,7 +1881,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
dest = tmp0
of nkEmpty, nkCommentStmt, nkTypeSection, nkConstSection, nkPragma,
nkTemplateDef, nkIncludeStmt, nkImportStmt, nkFromStmt:
unused(n, dest)
unused(c, n, dest)
of nkStringToCString, nkCStringToString:
gen(c, n.sons[0], dest)
of nkBracket: genArrayConstr(c, n, dest)
@ -1898,7 +1898,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
of nkComesFrom:
discard "XXX to implement for better stack traces"
else:
globalError(n.info, errGenerated, "cannot generate VM code for " & $n)
globalError(c.config, n.info, "cannot generate VM code for " & $n)
proc removeLastEof(c: PCtx) =
let last = c.code.len-1
@ -1915,7 +1915,7 @@ proc genStmt*(c: PCtx; n: PNode): int =
c.gen(n, d)
c.gABC(n, opcEof)
if d >= 0:
globalError(n.info, errGenerated, "VM problem: dest register is set")
globalError(c.config, n.info, "VM problem: dest register is set")
proc genExpr*(c: PCtx; n: PNode, requiresValue = true): int =
c.removeLastEof
@ -1924,7 +1924,7 @@ proc genExpr*(c: PCtx; n: PNode, requiresValue = true): int =
c.gen(n, d)
if d < 0:
if requiresValue:
globalError(n.info, errGenerated, "VM problem: dest register is not set")
globalError(c.config, n.info, "VM problem: dest register is not set")
d = 0
c.gABC(n, opcEof, d)
@ -1939,7 +1939,7 @@ proc genParams(c: PCtx; params: PNode) =
c.prc.maxSlots = max(params.len, 1)
proc finalJumpTarget(c: PCtx; pc, diff: int) =
internalAssert(-0x7fff < diff and diff < 0x7fff)
internalAssert(c.config, -0x7fff < diff and diff < 0x7fff)
let oldInstr = c.code[pc]
# opcode and regA stay the same:
c.code[pc] = ((oldInstr.uint32 and 0xffff'u32).uint32 or