Skip to content

Commit

Permalink
fixes #12195
Browse files Browse the repository at this point in the history
  • Loading branch information
Araq committed Sep 17, 2019
1 parent 62aa1a3 commit fd56a00
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 25 deletions.
20 changes: 14 additions & 6 deletions compiler/vm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,18 @@ proc asgnComplex(x: var TFullReg, y: TFullReg) =
of rkRegisterAddr: x.regAddr = y.regAddr
of rkNodeAddr: x.nodeAddr = y.nodeAddr

proc fastAsgnComplex(x: var TFullReg, y: TFullReg) =
if x.kind != y.kind:
myreset(x)
x.kind = y.kind
case x.kind
of rkNone: discard
of rkInt: x.intVal = y.intVal
of rkFloat: x.floatVal = y.floatVal
of rkNode: x.node = y.node
of rkRegisterAddr: x.regAddr = y.regAddr
of rkNodeAddr: x.nodeAddr = y.nodeAddr

proc writeField(n: var PNode, x: TFullReg) =
case x.kind
of rkNone: discard
Expand Down Expand Up @@ -535,10 +547,6 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
of opcAsgnInt:
decodeB(rkInt)
regs[ra].intVal = regs[rb].intVal
of opcAsgnStr:
decodeBC(rkNode)
createStrKeepNode regs[ra], rc != 0
regs[ra].node.strVal = regs[rb].node.strVal
of opcAsgnFloat:
decodeB(rkFloat)
regs[ra].floatVal = regs[rb].floatVal
Expand All @@ -560,6 +568,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
regs[ra].floatVal = cast[float64](int64(regs[rb].intVal))
of opcAsgnComplex:
asgnComplex(regs[ra], regs[instr.regB])
of opcFastAsgnComplex:
fastAsgnComplex(regs[ra], regs[instr.regB])
of opcAsgnRef:
asgnRef(regs[ra], regs[instr.regB])
of opcNodeToReg:
Expand Down Expand Up @@ -976,11 +986,9 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
regs[ra].node.strVal.add getstr(regs[i])
of opcAddStrCh:
decodeB(rkNode)
#createStrKeepNode regs[ra]
regs[ra].node.strVal.add(regs[rb].intVal.chr)
of opcAddStrStr:
decodeB(rkNode)
#createStrKeepNode regs[ra]
regs[ra].node.strVal.add(regs[rb].node.strVal)
of opcAddSeqElem:
decodeB(rkNode)
Expand Down
2 changes: 1 addition & 1 deletion compiler/vmdef.nim
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ type
opcYldVal, # yield with a value

opcAsgnInt,
opcAsgnStr,
opcAsgnFloat,
opcAsgnRef,
opcAsgnIntFromFloat32, # int and float must be of the same byte size
opcAsgnIntFromFloat64, # int and float must be of the same byte size
opcAsgnFloat32FromInt, # int and float must be of the same byte size
opcAsgnFloat64FromInt, # int and float must be of the same byte size
opcAsgnComplex,
opcFastAsgnComplex,
opcNodeToReg,

opcLdArr, # a = b[c]
Expand Down
35 changes: 17 additions & 18 deletions compiler/vmgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type
TGenFlag = enum
gfNode # Affects how variables are loaded - always loads as rkNode
gfNodeAddr # Affects how variables are loaded - always loads as rkNodeAddr
gfIsParam # do not deepcopy parameters, they are immutable
TGenFlags = set[TGenFlag]

proc debugInfo(c: PCtx; info: TLineInfo): string =
Expand Down Expand Up @@ -568,7 +569,7 @@ proc genCall(c: PCtx; n: PNode; dest: var TDest) =
# let paramType = fntyp.n.sons[i]
# if paramType.typ.isCompileTimeOnly: continue
var r: TRegister = x+i
c.gen(n.sons[i], r)
c.gen(n.sons[i], r, {gfIsParam})
if i >= fntyp.len:
internalAssert c.config, tfVarargs in fntyp.flags
c.gABx(n, opcSetType, r, c.genType(n.sons[i].typ))
Expand Down Expand Up @@ -917,20 +918,16 @@ proc ldNullOpcode(t: PType): TOpcode =
assert t != nil
if fitsRegister(t): opcLdNullReg else: opcLdNull

proc whichAsgnOpc(n: PNode): TOpcode =
proc whichAsgnOpc(n: PNode; requiresCopy = true): TOpcode =
case n.typ.skipTypes(abstractRange+{tyOwned}-{tyTypeDesc}).kind
of tyBool, tyChar, tyEnum, tyOrdinal, tyInt..tyInt64, tyUInt..tyUInt64:
opcAsgnInt
of tyString, tyCString:
opcAsgnStr
of tyFloat..tyFloat128:
opcAsgnFloat
of tyRef, tyNil, tyVar, tyLent, tyPtr:
opcAsgnRef
else:
opcAsgnComplex

proc whichAsgnOpc(n: PNode; opc: TOpcode): TOpcode = opc
(if requiresCopy: opcAsgnComplex else: opcFastAsgnComplex)

proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
case m
Expand Down Expand Up @@ -1317,7 +1314,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
let a = c.genx(arg)
assert dest >= 0
if dest < 0: dest = c.getTemp(arg.typ)
gABC(c, arg, whichAsgnOpc(arg), dest, a, 1)
gABC(c, arg, whichAsgnOpc(arg, requiresCopy=false), dest, a)
# XXX use ldNullOpcode() here?
c.gABx(n, opcLdNull, a, c.genType(arg.typ))
c.gABx(n, opcNodeToReg, a, a)
Expand Down Expand Up @@ -1419,7 +1416,7 @@ proc genDeref(c: PCtx, n: PNode, dest: var TDest, flags: TGenFlags) =
proc genAsgn(c: PCtx; dest: TDest; ri: PNode; requiresCopy: bool) =
let tmp = c.genx(ri)
assert dest >= 0
gABC(c, ri, whichAsgnOpc(ri), dest, tmp, 1-ord(requiresCopy))
gABC(c, ri, whichAsgnOpc(ri, requiresCopy), dest, tmp)
c.freeTemp(tmp)

proc setSlot(c: PCtx; v: PSym) =
Expand Down Expand Up @@ -1465,7 +1462,7 @@ template needsAdditionalCopy(n): untyped =
proc genAdditionalCopy(c: PCtx; n: PNode; opc: TOpcode;
dest, idx, value: TRegister) =
var cc = c.getTemp(n.typ)
c.gABC(n, whichAsgnOpc(n), cc, value, 0)
c.gABC(n, whichAsgnOpc(n), cc, value)
c.gABC(n, opc, dest, idx, cc)
c.freeTemp(cc)

Expand Down Expand Up @@ -1529,7 +1526,7 @@ proc genAsgn(c: PCtx; le, ri: PNode; requiresCopy: bool) =
if needsAdditionalCopy(le) and s.kind in {skResult, skVar, skParam}:
var cc = c.getTemp(le.typ)
gen(c, ri, cc)
c.gABC(le, whichAsgnOpc(le), dest, cc, 1)
c.gABC(le, whichAsgnOpc(le), dest, cc)
c.freeTemp(cc)
else:
gen(c, ri, dest)
Expand Down Expand Up @@ -1608,7 +1605,9 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
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)
let requiresCopy = c.prc.slots[dest].kind >= slotSomeTemp and
gfIsParam notin flags
genAsgn(c, dest, n, requiresCopy)
else:
# see tests/t99bott for an example that triggers it:
cannotEval(c, n)
Expand Down Expand Up @@ -1818,7 +1817,7 @@ proc genVarSection(c: PCtx; n: PNode) =
if not fitsRegister(le.typ) and s.kind in {skResult, skVar, skParam}:
var cc = c.getTemp(le.typ)
gen(c, a.sons[2], cc)
c.gABC(le, whichAsgnOpc(le), s.position.TRegister, cc, 1)
c.gABC(le, whichAsgnOpc(le), s.position.TRegister, cc)
c.freeTemp(cc)
else:
gen(c, a.sons[2], s.position.TRegister)
Expand Down Expand Up @@ -1849,7 +1848,7 @@ proc genArrayConstr(c: PCtx, n: PNode, dest: var TDest) =
c.gABx(n, opcLdNullReg, tmp, c.genType(intType))
for x in n:
let a = c.genx(x)
c.preventFalseAlias(n, whichAsgnOpc(x, opcWrArr), dest, tmp, a)
c.preventFalseAlias(n, opcWrArr, dest, tmp, a)
c.gABI(n, opcAddImmInt, tmp, tmp, 1)
c.freeTemp(a)
c.freeTemp(tmp)
Expand Down Expand Up @@ -1881,7 +1880,7 @@ proc genObjConstr(c: PCtx, n: PNode, dest: var TDest) =
if it.kind == nkExprColonExpr and it.sons[0].kind == nkSym:
let idx = genField(c, it.sons[0])
let tmp = c.genx(it.sons[1])
c.preventFalseAlias(it.sons[1], whichAsgnOpc(it.sons[1], opcWrObj),
c.preventFalseAlias(it.sons[1], opcWrObj,
dest, idx, tmp)
c.freeTemp(tmp)
else:
Expand All @@ -1896,12 +1895,12 @@ proc genTupleConstr(c: PCtx, n: PNode, dest: var TDest) =
if it.kind == nkExprColonExpr:
let idx = genField(c, it.sons[0])
let tmp = c.genx(it.sons[1])
c.preventFalseAlias(it.sons[1], whichAsgnOpc(it.sons[1], opcWrObj),
c.preventFalseAlias(it.sons[1], opcWrObj,
dest, idx, tmp)
c.freeTemp(tmp)
else:
let tmp = c.genx(it)
c.preventFalseAlias(it, whichAsgnOpc(it, opcWrObj), dest, i.TRegister, tmp)
c.preventFalseAlias(it, opcWrObj, dest, i.TRegister, tmp)
c.freeTemp(tmp)

proc genProc*(c: PCtx; s: PSym): int
Expand Down Expand Up @@ -2065,7 +2064,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
c.freeTemp(tmp1)
c.freeTemp(tmp2)
if dest >= 0:
gABC(c, n, whichAsgnOpc(n), dest, tmp0, 1)
gABC(c, n, whichAsgnOpc(n), dest, tmp0)
c.freeTemp(tmp0)
else:
dest = tmp0
Expand Down

0 comments on commit fd56a00

Please sign in to comment.