fix https://github.com/timotheecour/Nim/issues/88 (#13865) [backport:1.2]
This commit is contained in:
parent
87847150bf
commit
f1fd3ef7f4
2 changed files with 33 additions and 31 deletions
|
|
@ -510,6 +510,23 @@ const
|
||||||
"if you are sure this is not a bug in your code, compile with `--maxLoopIterationsVM:number` (current value: $1)"
|
"if you are sure this is not a bug in your code, compile with `--maxLoopIterationsVM:number` (current value: $1)"
|
||||||
errFieldXNotFound = "node lacks field: "
|
errFieldXNotFound = "node lacks field: "
|
||||||
|
|
||||||
|
|
||||||
|
template maybeHandlePtr(node2: PNode, reg: TFullReg, isAssign2: bool): bool =
|
||||||
|
let node = node2 # prevent double evaluation
|
||||||
|
if node.kind == nkNilLit:
|
||||||
|
stackTrace(c, tos, pc, errNilAccess)
|
||||||
|
let typ = node.typ
|
||||||
|
if nfIsPtr in node.flags or (typ != nil and typ.kind == tyPtr):
|
||||||
|
assert node.kind == nkIntLit, $(node.kind)
|
||||||
|
assert typ != nil
|
||||||
|
let typ2 = if typ.kind == tyPtr: typ[0] else: typ
|
||||||
|
if not derefPtrToReg(node.intVal, typ2, reg, isAssign = isAssign2):
|
||||||
|
# tyObject not supported in this context
|
||||||
|
stackTrace(c, tos, pc, "deref unsupported ptr type: " & $(typeToString(typ), typ.kind))
|
||||||
|
true
|
||||||
|
else:
|
||||||
|
false
|
||||||
|
|
||||||
proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
var pc = start
|
var pc = start
|
||||||
var tos = tos
|
var tos = tos
|
||||||
|
|
@ -755,26 +772,12 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
ensureKind(regs[rb].regAddr.kind)
|
ensureKind(regs[rb].regAddr.kind)
|
||||||
regs[ra] = regs[rb].regAddr[]
|
regs[ra] = regs[rb].regAddr[]
|
||||||
of rkNode:
|
of rkNode:
|
||||||
if regs[rb].node.kind == nkNilLit:
|
|
||||||
stackTrace(c, tos, pc, errNilAccess)
|
|
||||||
if regs[rb].node.kind == nkRefTy:
|
if regs[rb].node.kind == nkRefTy:
|
||||||
regs[ra].node = regs[rb].node[0]
|
regs[ra].node = regs[rb].node[0]
|
||||||
else:
|
elif not maybeHandlePtr(regs[rb].node, regs[ra], false):
|
||||||
let node = regs[rb].node
|
## eg: typ.kind = tyObject
|
||||||
let typ = node.typ
|
ensureKind(rkNode)
|
||||||
# see also `nfIsPtr`
|
regs[ra].node = regs[rb].node
|
||||||
if node.kind == nkIntLit:
|
|
||||||
var typ2 = typ
|
|
||||||
doAssert typ != nil
|
|
||||||
if typ.kind == tyPtr:
|
|
||||||
typ2 = typ2[0]
|
|
||||||
if not derefPtrToReg(node.intVal, typ2, regs[ra], isAssign = false):
|
|
||||||
# tyObject not supported in this context
|
|
||||||
stackTrace(c, tos, pc, "opcLdDeref unsupported ptr type: " & $(typeToString(typ), typ.kind))
|
|
||||||
else:
|
|
||||||
## eg: typ.kind = tyObject
|
|
||||||
ensureKind(rkNode)
|
|
||||||
regs[ra].node = regs[rb].node
|
|
||||||
else:
|
else:
|
||||||
stackTrace(c, tos, pc, errNilAccess & " kind: " & $regs[rb].kind)
|
stackTrace(c, tos, pc, errNilAccess & " kind: " & $regs[rb].kind)
|
||||||
of opcWrDeref:
|
of opcWrDeref:
|
||||||
|
|
@ -795,18 +798,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
regs[ra].nodeAddr[] = n
|
regs[ra].nodeAddr[] = n
|
||||||
of rkRegisterAddr: regs[ra].regAddr[] = regs[rc]
|
of rkRegisterAddr: regs[ra].regAddr[] = regs[rc]
|
||||||
of rkNode:
|
of rkNode:
|
||||||
if regs[ra].node.kind == nkNilLit:
|
# xxx: also check for nkRefTy as in opcLdDeref?
|
||||||
stackTrace(c, tos, pc, errNilAccess)
|
if not maybeHandlePtr(regs[ra].node, regs[rc], true):
|
||||||
let node = regs[ra].node
|
|
||||||
let typ = node.typ
|
|
||||||
if nfIsPtr in node.flags or (typ != nil and typ.kind == tyPtr):
|
|
||||||
assert node.kind == nkIntLit, $(node.kind)
|
|
||||||
var typ2 = typ
|
|
||||||
if typ.kind == tyPtr:
|
|
||||||
typ2 = typ2[0]
|
|
||||||
if not derefPtrToReg(node.intVal, typ2, regs[rc], isAssign = true):
|
|
||||||
stackTrace(c, tos, pc, "opcWrDeref unsupported ptr type: " & $(typeToString(typ), typ.kind))
|
|
||||||
else:
|
|
||||||
regs[ra].node[] = regs[rc].regToNode[]
|
regs[ra].node[] = regs[rc].regToNode[]
|
||||||
regs[ra].node.flags.incl nfIsRef
|
regs[ra].node.flags.incl nfIsRef
|
||||||
else: stackTrace(c, tos, pc, errNilAccess)
|
else: stackTrace(c, tos, pc, errNilAccess)
|
||||||
|
|
|
||||||
|
|
@ -60,3 +60,12 @@ static: # bug #8402
|
||||||
type R = ref object
|
type R = ref object
|
||||||
var empty: R
|
var empty: R
|
||||||
let otherEmpty = empty
|
let otherEmpty = empty
|
||||||
|
|
||||||
|
block:
|
||||||
|
# fix https://github.com/timotheecour/Nim/issues/88
|
||||||
|
template fun() =
|
||||||
|
var s = @[10,11,12]
|
||||||
|
var a = s[0].addr
|
||||||
|
a[] += 100 # was giving SIGSEGV
|
||||||
|
doAssert a[] == 110
|
||||||
|
static: fun()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue