fixes #1744
This commit is contained in:
parent
73dda8a81d
commit
bd88e526cf
4 changed files with 70 additions and 12 deletions
|
|
@ -454,8 +454,11 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
of opcLdStrIdx:
|
of opcLdStrIdx:
|
||||||
decodeBC(rkInt)
|
decodeBC(rkInt)
|
||||||
let idx = regs[rc].intVal.int
|
let idx = regs[rc].intVal.int
|
||||||
if idx <=% regs[rb].node.strVal.len:
|
let s = regs[rb].node.strVal
|
||||||
regs[ra].intVal = regs[rb].node.strVal[idx].ord
|
if s.isNil:
|
||||||
|
stackTrace(c, tos, pc, errNilAccess)
|
||||||
|
elif idx <=% s.len:
|
||||||
|
regs[ra].intVal = s[idx].ord
|
||||||
else:
|
else:
|
||||||
stackTrace(c, tos, pc, errIndexOutOfBounds)
|
stackTrace(c, tos, pc, errIndexOutOfBounds)
|
||||||
of opcWrArr:
|
of opcWrArr:
|
||||||
|
|
@ -1058,7 +1061,9 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
regs[ra].intVal = regs[ra].intVal and ((1'i64 shl rb)-1)
|
regs[ra].intVal = regs[ra].intVal and ((1'i64 shl rb)-1)
|
||||||
of opcIsNil:
|
of opcIsNil:
|
||||||
decodeB(rkInt)
|
decodeB(rkInt)
|
||||||
regs[ra].intVal = ord(regs[rb].node.kind == nkNilLit)
|
let node = regs[rb].node
|
||||||
|
regs[ra].intVal = ord(node.kind == nkNilLit or
|
||||||
|
(node.kind in {nkStrLit..nkTripleStrLit} and node.strVal.isNil))
|
||||||
of opcNBindSym:
|
of opcNBindSym:
|
||||||
decodeBx(rkNode)
|
decodeBx(rkNode)
|
||||||
regs[ra].node = copyTree(c.constants.sons[rbx])
|
regs[ra].node = copyTree(c.constants.sons[rbx])
|
||||||
|
|
|
||||||
|
|
@ -370,8 +370,8 @@ proc sameConstant*(a, b: PNode): bool =
|
||||||
of nkCharLit..nkInt64Lit: result = a.intVal == b.intVal
|
of nkCharLit..nkInt64Lit: result = a.intVal == b.intVal
|
||||||
of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
|
of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
|
||||||
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
|
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
|
||||||
of nkType: result = a.typ == b.typ
|
of nkType, nkNilLit: result = a.typ == b.typ
|
||||||
of nkEmpty, nkNilLit: result = true
|
of nkEmpty: result = true
|
||||||
else:
|
else:
|
||||||
if sonsLen(a) == sonsLen(b):
|
if sonsLen(a) == sonsLen(b):
|
||||||
for i in countup(0, sonsLen(a) - 1):
|
for i in countup(0, sonsLen(a) - 1):
|
||||||
|
|
@ -1350,7 +1350,9 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
||||||
result = newNodeIT(nkUIntLit, info, t)
|
result = newNodeIT(nkUIntLit, info, t)
|
||||||
of tyFloat..tyFloat128:
|
of tyFloat..tyFloat128:
|
||||||
result = newNodeIT(nkFloatLit, info, t)
|
result = newNodeIT(nkFloatLit, info, t)
|
||||||
of tyVar, tyPointer, tyPtr, tyCString, tySequence, tyString, tyExpr,
|
of tyCString, tyString:
|
||||||
|
result = newNodeIT(nkStrLit, info, t)
|
||||||
|
of tyVar, tyPointer, tyPtr, tySequence, tyExpr,
|
||||||
tyStmt, tyTypeDesc, tyStatic, tyRef:
|
tyStmt, tyTypeDesc, tyStatic, tyRef:
|
||||||
result = newNodeIT(nkNilLit, info, t)
|
result = newNodeIT(nkNilLit, info, t)
|
||||||
of tyProc:
|
of tyProc:
|
||||||
|
|
@ -1570,7 +1572,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
|
||||||
genLit(c, n, dest)
|
genLit(c, n, dest)
|
||||||
of nkUIntLit..pred(nkNilLit): genLit(c, n, dest)
|
of nkUIntLit..pred(nkNilLit): genLit(c, n, dest)
|
||||||
of nkNilLit:
|
of nkNilLit:
|
||||||
if not n.typ.isEmptyType: genLit(c, n, dest)
|
if not n.typ.isEmptyType: genLit(c, getNullValue(n.typ, n.info), dest)
|
||||||
else: unused(n, dest)
|
else: unused(n, dest)
|
||||||
of nkAsgn, nkFastAsgn:
|
of nkAsgn, nkFastAsgn:
|
||||||
unused(n, dest)
|
unused(n, dest)
|
||||||
|
|
@ -1647,7 +1649,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
|
||||||
if allowCast in c.features:
|
if allowCast in c.features:
|
||||||
genConv(c, n, n.sons[1], dest, opcCast)
|
genConv(c, n, n.sons[1], dest, opcCast)
|
||||||
else:
|
else:
|
||||||
localError(n.info, errGenerated, "VM is not allowed to 'cast'")
|
globalError(n.info, errGenerated, "VM is not allowed to 'cast'")
|
||||||
else:
|
else:
|
||||||
internalError n.info, "cannot generate VM code for " & n.renderTree
|
internalError n.info, "cannot generate VM code for " & n.renderTree
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,11 @@ type
|
||||||
|
|
||||||
C_JmpBuf {.importc: "jmp_buf", header: "<setjmp.h>".} = object
|
C_JmpBuf {.importc: "jmp_buf", header: "<setjmp.h>".} = object
|
||||||
|
|
||||||
var
|
when not defined(vm):
|
||||||
c_stdin {.importc: "stdin", nodecl.}: C_TextFileStar
|
var
|
||||||
c_stdout {.importc: "stdout", nodecl.}: C_TextFileStar
|
c_stdin {.importc: "stdin", nodecl.}: C_TextFileStar
|
||||||
c_stderr {.importc: "stderr", nodecl.}: C_TextFileStar
|
c_stdout {.importc: "stdout", nodecl.}: C_TextFileStar
|
||||||
|
c_stderr {.importc: "stderr", nodecl.}: C_TextFileStar
|
||||||
|
|
||||||
# constants faked as variables:
|
# constants faked as variables:
|
||||||
when not declared(SIGINT):
|
when not declared(SIGINT):
|
||||||
|
|
|
||||||
50
tests/vm/tstringnil.nim
Normal file
50
tests/vm/tstringnil.nim
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
# bug #1744
|
||||||
|
|
||||||
|
import macros
|
||||||
|
|
||||||
|
type
|
||||||
|
SuiteTest = object
|
||||||
|
suiteName: string
|
||||||
|
suiteDesc: string
|
||||||
|
testName: string
|
||||||
|
testDesc: string
|
||||||
|
testBlock: PNimrodNode
|
||||||
|
|
||||||
|
proc buildSuiteContents(suiteName, suiteDesc, suiteBloc: PNimrodNode): tuple[tests: seq[SuiteTest]] {.compileTime.} =
|
||||||
|
var
|
||||||
|
tests:seq[SuiteTest] = @[]
|
||||||
|
|
||||||
|
for child in suiteBloc.children():
|
||||||
|
case $child[0].ident:
|
||||||
|
of "test":
|
||||||
|
|
||||||
|
var testObj = SuiteTest()
|
||||||
|
if suiteName.kind == nnkNilLit:
|
||||||
|
testObj.suiteName = nil
|
||||||
|
else:
|
||||||
|
testObj.suiteName = $suiteName
|
||||||
|
if suiteDesc.kind == nnkNilLit:
|
||||||
|
testObj.suiteDesc = nil
|
||||||
|
else:
|
||||||
|
testObj.suiteDesc = suiteDesc.strVal
|
||||||
|
testObj.testName = $child[1] # should not ever be nil
|
||||||
|
if child[2].kind == nnkNilLit:
|
||||||
|
testObj.testDesc = nil
|
||||||
|
else:
|
||||||
|
testObj.testDesc = child[2].strVal
|
||||||
|
testObj.testBlock = child[3][6]
|
||||||
|
|
||||||
|
tests.add(testObj)
|
||||||
|
|
||||||
|
else:
|
||||||
|
discard
|
||||||
|
|
||||||
|
return (tests: tests)
|
||||||
|
|
||||||
|
macro suite(suiteName, suiteDesc: expr, suiteBloc: stmt): stmt {.immediate.} =
|
||||||
|
let contents = buildSuiteContents(suiteName, suiteDesc, suiteBloc)
|
||||||
|
|
||||||
|
# Test above
|
||||||
|
suite basics, "Description of such":
|
||||||
|
test(t5, nil):
|
||||||
|
assert false
|
||||||
Loading…
Add table
Add a link
Reference in a new issue