* revert #12217 since the root problem seems to have been fixed; fix #15974;fix #12551; fix #19464 * fix #16020; fix #16780 * fix tests and #16613 * fix #14553 * fix #19909; skip skipRegisterAddr * fix #18641
This commit is contained in:
parent
a65db5e2e9
commit
3cb2d7af05
4 changed files with 263 additions and 14 deletions
|
|
@ -523,8 +523,7 @@ when not defined(nimHasSinkInference):
|
||||||
|
|
||||||
template takeAddress(reg, source) =
|
template takeAddress(reg, source) =
|
||||||
reg.nodeAddr = addr source
|
reg.nodeAddr = addr source
|
||||||
when defined(gcDestructors):
|
GC_ref source
|
||||||
GC_ref source
|
|
||||||
|
|
||||||
proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
var pc = start
|
var pc = start
|
||||||
|
|
@ -1011,6 +1010,12 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
decodeBC(rkInt)
|
decodeBC(rkInt)
|
||||||
template getTyp(n): untyped =
|
template getTyp(n): untyped =
|
||||||
n.typ.skipTypes(abstractInst)
|
n.typ.skipTypes(abstractInst)
|
||||||
|
template skipRegisterAddr(n: TFullReg): TFullReg =
|
||||||
|
var tmp = n
|
||||||
|
while tmp.kind == rkRegisterAddr:
|
||||||
|
tmp = tmp.regAddr[]
|
||||||
|
tmp
|
||||||
|
|
||||||
proc ptrEquality(n1: ptr PNode, n2: PNode): bool =
|
proc ptrEquality(n1: ptr PNode, n2: PNode): bool =
|
||||||
## true if n2.intVal represents a ptr equal to n1
|
## true if n2.intVal represents a ptr equal to n1
|
||||||
let p1 = cast[int](n1)
|
let p1 = cast[int](n1)
|
||||||
|
|
@ -1024,16 +1029,19 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
return t2.kind in PtrLikeKinds and n2.intVal == p1
|
return t2.kind in PtrLikeKinds and n2.intVal == p1
|
||||||
else: return false
|
else: return false
|
||||||
|
|
||||||
if regs[rb].kind == rkNodeAddr:
|
let rbReg = skipRegisterAddr(regs[rb])
|
||||||
if regs[rc].kind == rkNodeAddr:
|
let rcReg = skipRegisterAddr(regs[rc])
|
||||||
ret = regs[rb].nodeAddr == regs[rc].nodeAddr
|
|
||||||
|
if rbReg.kind == rkNodeAddr:
|
||||||
|
if rcReg.kind == rkNodeAddr:
|
||||||
|
ret = rbReg.nodeAddr == rcReg.nodeAddr
|
||||||
else:
|
else:
|
||||||
ret = ptrEquality(regs[rb].nodeAddr, regs[rc].node)
|
ret = ptrEquality(rbReg.nodeAddr, rcReg.node)
|
||||||
elif regs[rc].kind == rkNodeAddr:
|
elif rcReg.kind == rkNodeAddr:
|
||||||
ret = ptrEquality(regs[rc].nodeAddr, regs[rb].node)
|
ret = ptrEquality(rcReg.nodeAddr, rbReg.node)
|
||||||
else:
|
else:
|
||||||
let nb = regs[rb].node
|
let nb = rbReg.node
|
||||||
let nc = regs[rc].node
|
let nc = rcReg.node
|
||||||
if nb.kind != nc.kind: discard
|
if nb.kind != nc.kind: discard
|
||||||
elif (nb == nc) or (nb.kind == nkNilLit): ret = true # intentional
|
elif (nb == nc) or (nb.kind == nkNilLit): ret = true # intentional
|
||||||
elif nb.kind in {nkSym, nkTupleConstr, nkClosure} and nb.typ != nil and nb.typ.kind == tyProc and sameConstant(nb, nc):
|
elif nb.kind in {nkSym, nkTupleConstr, nkClosure} and nb.typ != nil and nb.typ.kind == tyProc and sameConstant(nb, nc):
|
||||||
|
|
|
||||||
|
|
@ -1382,9 +1382,6 @@ proc unneededIndirection(n: PNode): bool =
|
||||||
n.typ.skipTypes(abstractInstOwned-{tyTypeDesc}).kind == tyRef
|
n.typ.skipTypes(abstractInstOwned-{tyTypeDesc}).kind == tyRef
|
||||||
|
|
||||||
proc canElimAddr(n: PNode): PNode =
|
proc canElimAddr(n: PNode): PNode =
|
||||||
if n[0].typ.skipTypes(abstractInst).kind in {tyObject, tyTuple, tyArray}:
|
|
||||||
# objects are reference types in the VM
|
|
||||||
return n[0]
|
|
||||||
case n[0].kind
|
case n[0].kind
|
||||||
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
|
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
|
||||||
var m = n[0][0]
|
var m = n[0][0]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import macros
|
import macros
|
||||||
|
|
||||||
block t9043: # issue #9043
|
block t9043: # bug #9043
|
||||||
proc foo[N: static[int]](dims: array[N, int]): string =
|
proc foo[N: static[int]](dims: array[N, int]): string =
|
||||||
const N1 = N
|
const N1 = N
|
||||||
const N2 = dims.len
|
const N2 = dims.len
|
||||||
|
|
@ -26,3 +26,51 @@ block t4952:
|
||||||
let tree = newTree(nnkExprColonExpr)
|
let tree = newTree(nnkExprColonExpr)
|
||||||
let t = (n: tree)
|
let t = (n: tree)
|
||||||
doAssert: t.n.kind == tree.kind
|
doAssert: t.n.kind == tree.kind
|
||||||
|
|
||||||
|
|
||||||
|
# bug #19909
|
||||||
|
type
|
||||||
|
SinglyLinkedList[T] = ref object
|
||||||
|
SinglyLinkedListObj[T] = ref object
|
||||||
|
|
||||||
|
|
||||||
|
proc addMoved[T](a, b: var SinglyLinkedList[T]) =
|
||||||
|
if a.addr != b.addr: discard
|
||||||
|
|
||||||
|
proc addMoved[T](a, b: var SinglyLinkedListObj[T]) =
|
||||||
|
if a.addr != b.addr: discard
|
||||||
|
|
||||||
|
proc main =
|
||||||
|
var a: SinglyLinkedList[int]; new a
|
||||||
|
var b: SinglyLinkedList[int]; new b
|
||||||
|
a.addMoved b
|
||||||
|
|
||||||
|
var a0: SinglyLinkedListObj[int]
|
||||||
|
var b0: SinglyLinkedListObj[int]
|
||||||
|
a0.addMoved b0
|
||||||
|
|
||||||
|
static: main()
|
||||||
|
|
||||||
|
|
||||||
|
# bug #18641
|
||||||
|
|
||||||
|
type A = object
|
||||||
|
ha1: int
|
||||||
|
static:
|
||||||
|
var a = A()
|
||||||
|
var a2 = a.addr
|
||||||
|
a2.ha1 = 11
|
||||||
|
doAssert a2.ha1 == 11
|
||||||
|
a.ha1 = 12
|
||||||
|
doAssert a.ha1 == 12
|
||||||
|
doAssert a2.ha1 == 12 # ok
|
||||||
|
static:
|
||||||
|
proc fn() =
|
||||||
|
var a = A()
|
||||||
|
var a2 = a.addr
|
||||||
|
a2.ha1 = 11
|
||||||
|
doAssert a2.ha1 == 11
|
||||||
|
a.ha1 = 12
|
||||||
|
doAssert a.ha1 == 12
|
||||||
|
doAssert a2.ha1 == 12 # fails
|
||||||
|
fn()
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,12 @@
|
||||||
discard """
|
discard """
|
||||||
|
targets: "c js"
|
||||||
output: '''
|
output: '''
|
||||||
[127, 127, 0, 255][127, 127, 0, 255]
|
[127, 127, 0, 255][127, 127, 0, 255]
|
||||||
(data: 1)
|
(data: 1)
|
||||||
|
(2, 1)
|
||||||
|
(2, 1)
|
||||||
|
(2, 1)
|
||||||
|
(f0: 5)
|
||||||
'''
|
'''
|
||||||
|
|
||||||
nimout: '''caught Exception
|
nimout: '''caught Exception
|
||||||
|
|
@ -17,6 +22,19 @@ foo4
|
||||||
(a: 0, b: 0)
|
(a: 0, b: 0)
|
||||||
(a: 0, b: 0)
|
(a: 0, b: 0)
|
||||||
(a: 0, b: 0)
|
(a: 0, b: 0)
|
||||||
|
z1 m: (lo: 12)
|
||||||
|
z2 a: (lo: 3)
|
||||||
|
x1 a: (lo: 3)
|
||||||
|
x2 a: (lo: 6)
|
||||||
|
x3 a: (lo: 0)
|
||||||
|
z3 a: (lo: 3)
|
||||||
|
x1 a: (lo: 3)
|
||||||
|
x2 a: (lo: 6)
|
||||||
|
x3 a: (lo: 0)
|
||||||
|
(2, 1)
|
||||||
|
(2, 1)
|
||||||
|
(2, 1)
|
||||||
|
(f0: 5)
|
||||||
'''
|
'''
|
||||||
"""
|
"""
|
||||||
import std/sets
|
import std/sets
|
||||||
|
|
@ -249,3 +267,181 @@ static:
|
||||||
echo x2[]
|
echo x2[]
|
||||||
let x3 = new(ref MyObject) # cannot generate VM code for ref MyObject
|
let x3 = new(ref MyObject) # cannot generate VM code for ref MyObject
|
||||||
echo x3[]
|
echo x3[]
|
||||||
|
|
||||||
|
# bug #19464
|
||||||
|
type
|
||||||
|
Wrapper = object
|
||||||
|
inner: int
|
||||||
|
|
||||||
|
proc assign(r: var Wrapper, a: Wrapper) =
|
||||||
|
r = a
|
||||||
|
|
||||||
|
proc myEcho(a: Wrapper) =
|
||||||
|
var tmp = a
|
||||||
|
assign(tmp, Wrapper(inner: 0)) # this shouldn't modify `a`
|
||||||
|
doAssert a.inner == 1
|
||||||
|
|
||||||
|
static:
|
||||||
|
var result: Wrapper
|
||||||
|
assign(result, Wrapper(inner: 1))
|
||||||
|
myEcho(result)
|
||||||
|
|
||||||
|
when true:
|
||||||
|
# bug #15974
|
||||||
|
type Foo = object
|
||||||
|
f0: int
|
||||||
|
|
||||||
|
proc fn(a: var Foo) =
|
||||||
|
var s: Foo
|
||||||
|
a = Foo(f0: 2)
|
||||||
|
s = a
|
||||||
|
doAssert s.f0 == 2
|
||||||
|
a = Foo(f0: 3)
|
||||||
|
doAssert s.f0 == 2
|
||||||
|
|
||||||
|
proc test2()=
|
||||||
|
var a = Foo(f0: 1)
|
||||||
|
fn(a)
|
||||||
|
|
||||||
|
static: test2()
|
||||||
|
test2()
|
||||||
|
|
||||||
|
# bug #12551
|
||||||
|
type
|
||||||
|
StUint = object
|
||||||
|
lo: uint64
|
||||||
|
|
||||||
|
func `+=`(x: var Stuint, y: Stuint) =
|
||||||
|
x.lo += y.lo
|
||||||
|
|
||||||
|
func `-`(x, y: Stuint): Stuint =
|
||||||
|
result.lo = x.lo - y.lo
|
||||||
|
|
||||||
|
func `+`(x, y: Stuint): Stuint =
|
||||||
|
result.lo = x.lo + y.lo
|
||||||
|
|
||||||
|
func `-=`(x: var Stuint, y: Stuint) =
|
||||||
|
x = x - y
|
||||||
|
|
||||||
|
func `<`(x, y: Stuint): bool=
|
||||||
|
x.lo < y.lo
|
||||||
|
|
||||||
|
func `==`(x, y: Stuint): bool =
|
||||||
|
x.lo == y.lo
|
||||||
|
|
||||||
|
func `<=`(x, y: Stuint): bool =
|
||||||
|
x.lo <= y.lo
|
||||||
|
|
||||||
|
proc div3n2n(r: var Stuint, b: Stuint) =
|
||||||
|
var d: Stuint
|
||||||
|
r = d
|
||||||
|
r += b
|
||||||
|
|
||||||
|
func div2n1n(r: var Stuint, b: Stuint) =
|
||||||
|
div3n2n(r, b)
|
||||||
|
|
||||||
|
func divmodBZ(x, y: Stuint, r: var Stuint)=
|
||||||
|
div2n1n(r, y)
|
||||||
|
r.lo = 3
|
||||||
|
|
||||||
|
func `mod`(x, y: Stuint): Stuint =
|
||||||
|
divmodBZ(x, y, result)
|
||||||
|
|
||||||
|
func doublemod_internal(a, m: Stuint): Stuint =
|
||||||
|
result = a
|
||||||
|
if a >= m - a:
|
||||||
|
result -= m
|
||||||
|
result += a
|
||||||
|
|
||||||
|
func mulmod_internal(a, b, m: Stuint): Stuint =
|
||||||
|
var (a, b) = (a, b)
|
||||||
|
swap(a, b)
|
||||||
|
debugEcho "x1 a: ", a
|
||||||
|
a = doublemod_internal(a, m)
|
||||||
|
debugEcho "x2 a: ", a
|
||||||
|
a = doublemod_internal(a, m)
|
||||||
|
debugEcho "x3 a: ", a
|
||||||
|
|
||||||
|
func powmod_internal(a, m: Stuint): Stuint =
|
||||||
|
var a = a
|
||||||
|
debugEcho "z1 m: ", m
|
||||||
|
debugEcho "z2 a: ", a
|
||||||
|
result = mulmod_internal(result, a, m)
|
||||||
|
debugEcho "z3 a: ", a
|
||||||
|
a = mulmod_internal(a, a, m)
|
||||||
|
|
||||||
|
func powmod*(a, m: Stuint) =
|
||||||
|
discard powmod_internal(a mod m, m)
|
||||||
|
|
||||||
|
static:
|
||||||
|
var x = Stuint(lo: high(uint64))
|
||||||
|
var y = Stuint(lo: 12)
|
||||||
|
|
||||||
|
powmod(x, y)
|
||||||
|
|
||||||
|
# bug #16780
|
||||||
|
when true:
|
||||||
|
template swap*[T](a, b: var T) =
|
||||||
|
var a2 = addr(a)
|
||||||
|
var b2 = addr(b)
|
||||||
|
var aOld = a2[]
|
||||||
|
a2[] = b2[]
|
||||||
|
b2[] = aOld
|
||||||
|
|
||||||
|
proc rather =
|
||||||
|
block:
|
||||||
|
var a = 1
|
||||||
|
var b = 2
|
||||||
|
swap(a, b)
|
||||||
|
echo (a,b)
|
||||||
|
|
||||||
|
block:
|
||||||
|
type Foo = ref object
|
||||||
|
x: int
|
||||||
|
var a = Foo(x:1)
|
||||||
|
var b = Foo(x:2)
|
||||||
|
swap(a, b)
|
||||||
|
echo (a.x, b.x)
|
||||||
|
|
||||||
|
block:
|
||||||
|
type Foo = object
|
||||||
|
x: int
|
||||||
|
var a = Foo(x:1)
|
||||||
|
var b = Foo(x:2)
|
||||||
|
swap(a, b)
|
||||||
|
echo (a.x,b.x)
|
||||||
|
|
||||||
|
static: rather()
|
||||||
|
rather()
|
||||||
|
|
||||||
|
# bug #16020
|
||||||
|
when true:
|
||||||
|
block:
|
||||||
|
type Foo = object
|
||||||
|
f0: int
|
||||||
|
proc main=
|
||||||
|
var f = Foo(f0: 3)
|
||||||
|
var f2 = f.addr
|
||||||
|
f2[].f0 += 1
|
||||||
|
f2.f0 += 1
|
||||||
|
echo f
|
||||||
|
static: main()
|
||||||
|
main()
|
||||||
|
|
||||||
|
import tables, strutils
|
||||||
|
|
||||||
|
# bug #14553
|
||||||
|
const PpcPatterns = @[("aaaa", "bbbb"), ("aaaaa", "bbbbb"), ("aaaaaa", "bbbbbb"), ("aaaaaaa", "bbbbbbb"), ("aaaaaaaa", "bbbbb")]
|
||||||
|
|
||||||
|
static:
|
||||||
|
var
|
||||||
|
needSecondIdentifier = initTable[uint32, seq[(string, string)]]()
|
||||||
|
|
||||||
|
for (name, pattern) in PpcPatterns:
|
||||||
|
let
|
||||||
|
firstPart = 0'u32
|
||||||
|
lastPart = "test"
|
||||||
|
|
||||||
|
needSecondIdentifier.mgetOrPut(firstPart, @[]).add((name, pattern))
|
||||||
|
|
||||||
|
doAssert needSecondIdentifier[0] == @[("aaaa", "bbbb"), ("aaaaa", "bbbbb"), ("aaaaaa", "bbbbbb"), ("aaaaaaa", "bbbbbbb"), ("aaaaaaaa", "bbbbb")]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue