fixes constant array indexing bug
This commit is contained in:
parent
33106884ec
commit
678f3d7f5b
12 changed files with 47 additions and 1523 deletions
1502
compiler/evals.nim
1502
compiler/evals.nim
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nimrod Compiler
|
# The Nimrod Compiler
|
||||||
# (c) Copyright 2012 Andreas Rumpf
|
# (c) Copyright 2014 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -537,17 +537,18 @@ proc foldArrayAccess(m: PSym, n: PNode): PNode =
|
||||||
var idx = getOrdValue(y)
|
var idx = getOrdValue(y)
|
||||||
case x.kind
|
case x.kind
|
||||||
of nkPar:
|
of nkPar:
|
||||||
if (idx >= 0) and (idx < sonsLen(x)):
|
if idx >= 0 and idx < sonsLen(x):
|
||||||
result = x.sons[int(idx)]
|
result = x.sons[int(idx)]
|
||||||
if result.kind == nkExprColonExpr: result = result.sons[1]
|
if result.kind == nkExprColonExpr: result = result.sons[1]
|
||||||
else:
|
else:
|
||||||
localError(n.info, errIndexOutOfBounds)
|
localError(n.info, errIndexOutOfBounds)
|
||||||
of nkBracket:
|
of nkBracket:
|
||||||
if (idx >= 0) and (idx < sonsLen(x)): result = x.sons[int(idx)]
|
idx = idx - x.typ.firstOrd
|
||||||
|
if idx >= 0 and idx < x.len: result = x.sons[int(idx)]
|
||||||
else: localError(n.info, errIndexOutOfBounds)
|
else: localError(n.info, errIndexOutOfBounds)
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
result = newNodeIT(nkCharLit, x.info, n.typ)
|
result = newNodeIT(nkCharLit, x.info, n.typ)
|
||||||
if (idx >= 0) and (idx < len(x.strVal)):
|
if idx >= 0 and idx < len(x.strVal):
|
||||||
result.intVal = ord(x.strVal[int(idx)])
|
result.intVal = ord(x.strVal[int(idx)])
|
||||||
elif idx == len(x.strVal):
|
elif idx == len(x.strVal):
|
||||||
discard
|
discard
|
||||||
|
|
|
||||||
|
|
@ -84,21 +84,27 @@ proc gABI(c: PCtx; n: PNode; opc: TOpcode; a, b: TRegister; imm: BiggestInt) =
|
||||||
# Takes the `b` register and the immediate `imm`, appies the operation `opc`,
|
# Takes the `b` register and the immediate `imm`, appies the operation `opc`,
|
||||||
# and stores the output value into `a`.
|
# and stores the output value into `a`.
|
||||||
# `imm` is signed and must be within [-127, 128]
|
# `imm` is signed and must be within [-127, 128]
|
||||||
assert(imm >= -127 and imm <= 128)
|
if imm >= -127 and imm <= 128:
|
||||||
let ins = (opc.uint32 or (a.uint32 shl 8'u32) or
|
let ins = (opc.uint32 or (a.uint32 shl 8'u32) or
|
||||||
(b.uint32 shl 16'u32) or
|
(b.uint32 shl 16'u32) or
|
||||||
(imm+byteExcess).uint32 shl 24'u32).TInstr
|
(imm+byteExcess).uint32 shl 24'u32).TInstr
|
||||||
c.code.add(ins)
|
c.code.add(ins)
|
||||||
c.debug.add(n.info)
|
c.debug.add(n.info)
|
||||||
|
else:
|
||||||
|
localError(n.info, errGenerated,
|
||||||
|
"VM: immediate value does not fit into an int8")
|
||||||
|
|
||||||
proc gABx(c: PCtx; n: PNode; opc: TOpcode; a: TRegister = 0; bx: int) =
|
proc gABx(c: PCtx; n: PNode; opc: TOpcode; a: TRegister = 0; bx: int) =
|
||||||
# Applies `opc` to `bx` and stores it into register `a`
|
# Applies `opc` to `bx` and stores it into register `a`
|
||||||
# `bx` must be signed and in the range [-32767, 32768]
|
# `bx` must be signed and in the range [-32767, 32768]
|
||||||
assert(bx >= -32767 and bx <= 32768)
|
if bx >= -32767 and bx <= 32768:
|
||||||
let ins = (opc.uint32 or a.uint32 shl 8'u32 or
|
let ins = (opc.uint32 or a.uint32 shl 8'u32 or
|
||||||
(bx+wordExcess).uint32 shl 16'u32).TInstr
|
(bx+wordExcess).uint32 shl 16'u32).TInstr
|
||||||
c.code.add(ins)
|
c.code.add(ins)
|
||||||
c.debug.add(n.info)
|
c.debug.add(n.info)
|
||||||
|
else:
|
||||||
|
localError(n.info, errGenerated,
|
||||||
|
"VM: immediate value does not fit into an int16")
|
||||||
|
|
||||||
proc xjmp(c: PCtx; n: PNode; opc: TOpcode; a: TRegister = 0): TPosition =
|
proc xjmp(c: PCtx; n: PNode; opc: TOpcode; a: TRegister = 0): TPosition =
|
||||||
#assert opc in {opcJmp, opcFJmp, opcTJmp}
|
#assert opc in {opcJmp, opcFJmp, opcTJmp}
|
||||||
|
|
@ -485,11 +491,22 @@ proc genField(n: PNode): TRegister =
|
||||||
"too large offset! cannot generate code for: " & s.name.s)
|
"too large offset! cannot generate code for: " & s.name.s)
|
||||||
result = s.position
|
result = s.position
|
||||||
|
|
||||||
|
proc genIndex(c: PCtx; n: PNode; arr: PType): TRegister =
|
||||||
|
if arr.skipTypes(abstractInst).kind == tyArray and (let x = firstOrd(arr);
|
||||||
|
x != 0):
|
||||||
|
let tmp = c.genx(n)
|
||||||
|
# freeing the temporary here means we can produce: regA = regA - Imm
|
||||||
|
c.freeTemp(tmp)
|
||||||
|
result = c.getTemp(n.typ)
|
||||||
|
c.gABI(n, opcSubImmInt, result, tmp, x.int)
|
||||||
|
else:
|
||||||
|
result = c.genx(n)
|
||||||
|
|
||||||
proc genAsgnPatch(c: PCtx; le: PNode, value: TRegister) =
|
proc genAsgnPatch(c: PCtx; le: PNode, value: TRegister) =
|
||||||
case le.kind
|
case le.kind
|
||||||
of nkBracketExpr:
|
of nkBracketExpr:
|
||||||
let dest = c.genx(le.sons[0], {gfAddrOf})
|
let dest = c.genx(le.sons[0], {gfAddrOf})
|
||||||
let idx = c.genx(le.sons[1])
|
let idx = c.genIndex(le.sons[1], le.sons[0].typ)
|
||||||
c.gABC(le, opcWrArr, dest, idx, value)
|
c.gABC(le, opcWrArr, dest, idx, value)
|
||||||
c.freeTemp(dest)
|
c.freeTemp(dest)
|
||||||
c.freeTemp(idx)
|
c.freeTemp(idx)
|
||||||
|
|
@ -1072,7 +1089,7 @@ proc genAsgn(c: PCtx; le, ri: PNode; requiresCopy: bool) =
|
||||||
case le.kind
|
case le.kind
|
||||||
of nkBracketExpr:
|
of nkBracketExpr:
|
||||||
let dest = c.genx(le.sons[0], {gfAddrOf})
|
let dest = c.genx(le.sons[0], {gfAddrOf})
|
||||||
let idx = c.genx(le.sons[1])
|
let idx = c.genIndex(le.sons[1], le.sons[0].typ)
|
||||||
let tmp = c.genx(ri)
|
let tmp = c.genx(ri)
|
||||||
if le.sons[0].typ.skipTypes(abstractVarRange-{tyTypeDesc}).kind in {
|
if le.sons[0].typ.skipTypes(abstractVarRange-{tyTypeDesc}).kind in {
|
||||||
tyString, tyCString}:
|
tyString, tyCString}:
|
||||||
|
|
@ -1185,7 +1202,7 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||||
proc genArrAccess2(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
|
proc genArrAccess2(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
|
||||||
flags: TGenFlags) =
|
flags: TGenFlags) =
|
||||||
let a = c.genx(n.sons[0], flags)
|
let a = c.genx(n.sons[0], flags)
|
||||||
let b = c.genx(n.sons[1], {})
|
let b = c.genIndex(n.sons[1], n.sons[0].typ)
|
||||||
if dest < 0: dest = c.getTemp(n.typ)
|
if dest < 0: dest = c.getTemp(n.typ)
|
||||||
if gfAddrOf notin flags and fitsRegister(n.typ):
|
if gfAddrOf notin flags and fitsRegister(n.typ):
|
||||||
var cc = c.getTemp(n.typ)
|
var cc = c.getTemp(n.typ)
|
||||||
|
|
|
||||||
0
examples/cross_calculator/android/scripts/jnibuild.sh
Executable file → Normal file
0
examples/cross_calculator/android/scripts/jnibuild.sh
Executable file → Normal file
0
examples/cross_calculator/android/scripts/nimbuild.sh
Executable file → Normal file
0
examples/cross_calculator/android/scripts/nimbuild.sh
Executable file → Normal file
0
examples/cross_calculator/android/scripts/tags.sh
Executable file → Normal file
0
examples/cross_calculator/android/scripts/tags.sh
Executable file → Normal file
0
examples/cross_calculator/ios/scripts/tags.sh
Executable file → Normal file
0
examples/cross_calculator/ios/scripts/tags.sh
Executable file → Normal file
0
examples/cross_calculator/ios/scripts/xcode_prebuild.sh
Executable file → Normal file
0
examples/cross_calculator/ios/scripts/xcode_prebuild.sh
Executable file → Normal file
0
lib/pure/unidecode/gen.py
Executable file → Normal file
0
lib/pure/unidecode/gen.py
Executable file → Normal file
|
|
@ -1,6 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
output: '''7
|
output: '''7
|
||||||
8 8'''
|
8 8
|
||||||
|
-2'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#bug 1063
|
#bug 1063
|
||||||
|
|
@ -21,3 +22,10 @@ type
|
||||||
internal: array[int((KeyMax + 31)/32), cuint]
|
internal: array[int((KeyMax + 31)/32), cuint]
|
||||||
|
|
||||||
echo myconst, " ", int((KeyMax + 31) / 32)
|
echo myconst, " ", int((KeyMax + 31) / 32)
|
||||||
|
|
||||||
|
#bug 1304 or something:
|
||||||
|
|
||||||
|
const constArray: array [-3..2, int] = [-3, -2, -1, 0, 1, 2]
|
||||||
|
|
||||||
|
echo constArray[-2]
|
||||||
|
|
||||||
|
|
|
||||||
0
tinyc/tests/gcctestsuite.sh
Executable file → Normal file
0
tinyc/tests/gcctestsuite.sh
Executable file → Normal file
0
tinyc/texi2pod.pl
Executable file → Normal file
0
tinyc/texi2pod.pl
Executable file → Normal file
Loading…
Add table
Add a link
Reference in a new issue