Implemented mSlice on the VM allowing toOpenArray to work at compile time. (#20586)
* Implemented opcSlice to make 'toOpenArray' work on the VM * Added nkOpenArray for VM to reduce bodgeness * Fixed range issues and erraneous comments * Range check correctly for openArrays in opcLdArr * Inverted logic for ldArr checking * vm now supports slicing strings * Added string tests * Removed usage of 'nkOpenArray' and redundant operations * Refactored vmSlice implementation, removing redundant and incorrect code * Made tuples go throw opcWrObj for field assignment * All strkinds should be considered for openarrays
This commit is contained in:
parent
ff2cb113ad
commit
4aa67ad7fd
4 changed files with 204 additions and 30 deletions
|
|
@ -640,9 +640,19 @@ proc genCheckedObjAccessAux(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags
|
|||
proc genAsgnPatch(c: PCtx; le: PNode, value: TRegister) =
|
||||
case le.kind
|
||||
of nkBracketExpr:
|
||||
let dest = c.genx(le[0], {gfNode})
|
||||
let idx = c.genIndex(le[1], le[0].typ)
|
||||
c.gABC(le, opcWrArr, dest, idx, value)
|
||||
let
|
||||
dest = c.genx(le[0], {gfNode})
|
||||
idx = c.genIndex(le[1], le[0].typ)
|
||||
collTyp = le[0].typ.skipTypes(abstractVarRange-{tyTypeDesc})
|
||||
|
||||
case collTyp.kind
|
||||
of tyString, tyCstring:
|
||||
c.gABC(le, opcWrStrIdx, dest, idx, value)
|
||||
of tyTuple:
|
||||
c.gABC(le, opcWrObj, dest, int le[1].intVal, value)
|
||||
else:
|
||||
c.gABC(le, opcWrArr, dest, idx, value)
|
||||
|
||||
c.freeTemp(dest)
|
||||
c.freeTemp(idx)
|
||||
of nkCheckedFieldExpr:
|
||||
|
|
@ -1054,6 +1064,18 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
|
|||
of tyString: genUnaryABI(c, n, dest, opcLenStr)
|
||||
of tyCstring: genUnaryABI(c, n, dest, opcLenCstring)
|
||||
else: doAssert false, $n[1].typ.kind
|
||||
of mSlice:
|
||||
var
|
||||
d = c.genx(n[1])
|
||||
left = c.genIndex(n[2], n[1].typ)
|
||||
right = c.genIndex(n[3], n[1].typ)
|
||||
if dest < 0: dest = c.getTemp(n.typ)
|
||||
c.gABC(n, opcNodeToReg, dest, d)
|
||||
c.gABC(n, opcSlice, dest, left, right)
|
||||
c.freeTemp(left)
|
||||
c.freeTemp(right)
|
||||
c.freeTemp(d)
|
||||
|
||||
of mIncl, mExcl:
|
||||
unused(c, n, dest)
|
||||
var d = c.genx(n[1])
|
||||
|
|
@ -1179,7 +1201,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
|
|||
var d = c.genx(n[1])
|
||||
# XXX use ldNullOpcode() here?
|
||||
c.gABx(n, opcLdNull, d, c.genType(n[1].typ))
|
||||
c.gABx(n, opcNodeToReg, d, d)
|
||||
c.gABC(n, opcNodeToReg, d, d)
|
||||
c.genAsgnPatch(n[1], d)
|
||||
of mDefault, mZeroDefault:
|
||||
if dest < 0: dest = c.getTemp(n.typ)
|
||||
|
|
@ -1507,12 +1529,16 @@ proc preventFalseAlias(c: PCtx; n: PNode; opc: TOpcode;
|
|||
proc genAsgn(c: PCtx; le, ri: PNode; requiresCopy: bool) =
|
||||
case le.kind
|
||||
of nkBracketExpr:
|
||||
let dest = c.genx(le[0], {gfNode})
|
||||
let idx = c.genIndex(le[1], le[0].typ)
|
||||
let tmp = c.genx(ri)
|
||||
if le[0].typ.skipTypes(abstractVarRange-{tyTypeDesc}).kind in {
|
||||
tyString, tyCstring}:
|
||||
let
|
||||
dest = c.genx(le[0], {gfNode})
|
||||
idx = c.genIndex(le[1], le[0].typ)
|
||||
tmp = c.genx(ri)
|
||||
collTyp = le[0].typ.skipTypes(abstractVarRange-{tyTypeDesc})
|
||||
case collTyp.kind
|
||||
of tyString, tyCstring:
|
||||
c.preventFalseAlias(le, opcWrStrIdx, dest, idx, tmp)
|
||||
of tyTuple:
|
||||
c.preventFalseAlias(le, opcWrObj, dest, int le[1].intVal, tmp)
|
||||
else:
|
||||
c.preventFalseAlias(le, opcWrArr, dest, idx, tmp)
|
||||
c.freeTemp(tmp)
|
||||
|
|
@ -1676,9 +1702,7 @@ proc genArrAccessOpcode(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
|
|||
c.freeTemp(a)
|
||||
c.freeTemp(b)
|
||||
|
||||
proc genObjAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||
let a = c.genx(n[0], flags)
|
||||
let b = genField(c, n[1])
|
||||
proc genObjAccessAux(c: PCtx; n: PNode; a, b: int, dest: var TDest; flags: TGenFlags) =
|
||||
if dest < 0: dest = c.getTemp(n.typ)
|
||||
if {gfNodeAddr} * flags != {}:
|
||||
c.gABC(n, opcLdObjAddr, dest, a, b)
|
||||
|
|
@ -1691,6 +1715,11 @@ proc genObjAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
|||
c.gABC(n, opcLdObj, dest, a, b)
|
||||
c.freeTemp(a)
|
||||
|
||||
proc genObjAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||
genObjAccessAux(c, n, c.genx(n[0], flags), genField(c, n[1]), dest, flags)
|
||||
|
||||
|
||||
|
||||
proc genCheckedObjAccessAux(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||
internalAssert c.config, n.kind == nkCheckedFieldExpr
|
||||
# nkDotExpr to access the requested field
|
||||
|
|
@ -1758,10 +1787,13 @@ proc genCheckedObjAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
|||
|
||||
proc genArrAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||
let arrayType = n[0].typ.skipTypes(abstractVarRange-{tyTypeDesc}).kind
|
||||
if arrayType in {tyString, tyCstring}:
|
||||
case arrayType
|
||||
of tyString, tyCstring:
|
||||
let opc = if gfNodeAddr in flags: opcLdStrIdxAddr else: opcLdStrIdx
|
||||
genArrAccessOpcode(c, n, dest, opc, flags)
|
||||
elif arrayType == tyTypeDesc:
|
||||
of tyTuple:
|
||||
c.genObjAccessAux(n, c.genx(n[0], flags), int n[1].intVal, dest, flags)
|
||||
of tyTypeDesc:
|
||||
c.genTypeLit(n.typ, dest)
|
||||
else:
|
||||
let opc = if gfNodeAddr in flags: opcLdArrAddr else: opcLdArr
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue