Skip to content

Commit b795aba

Browse files
timotheecourmildred
authored andcommitted
fix nim-lang#14339, nim-lang#13511, nim-lang#14420: fixes limited VM support for addr (nim-lang#16002)
* fix nim-lang#14339: fixes limited VM support for addr * strengthen test * reference bug nim-lang#16003 * also fixes nim-lang#13511 * also fixes nim-lang#14420
1 parent 4338f2d commit b795aba

File tree

4 files changed

+160
-44
lines changed

4 files changed

+160
-44
lines changed

compiler/vm.nim

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -746,10 +746,13 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
746746
regs[ra].regAddr = addr(regs[rb])
747747
of opcAddrNode:
748748
decodeB(rkNodeAddr)
749-
if regs[rb].kind == rkNode:
749+
case regs[rb].kind
750+
of rkNode:
750751
regs[ra].nodeAddr = addr(regs[rb].node)
752+
of rkNodeAddr: # bug #14339
753+
regs[ra].nodeAddr = regs[rb].nodeAddr
751754
else:
752-
stackTrace(c, tos, pc, "limited VM support for 'addr'")
755+
stackTrace(c, tos, pc, "limited VM support for 'addr', got kind: " & $regs[rb].kind)
753756
of opcLdDeref:
754757
# a = b[]
755758
let ra = instr.regA

tests/macros/tmacros_various.nim

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,3 +245,28 @@ xbenchmark:
245245
discard inputtest
246246
fastSHA("hey")
247247

248+
249+
block: # bug #13511
250+
type
251+
Builder = ref object
252+
components: seq[Component]
253+
Component = object
254+
255+
proc add(builder: var Builder, component: Component) {.compileTime.} =
256+
builder.components.add(component)
257+
258+
macro debugAst(arg: typed): untyped =
259+
## just for debugging purpose.
260+
discard arg.treeRepr
261+
return arg
262+
263+
static:
264+
var component = Component()
265+
var builder = Builder()
266+
267+
template foo(): untyped =
268+
## WAS: this doc comment causes compilation failure.
269+
builder
270+
271+
debugAst:
272+
add(foo(), component)

tests/misc/taddr.nim

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,83 @@ block:
123123
block: # pending bug #15959
124124
when false:
125125
proc byLent2[T](a: T): lent type(a[0]) = a[0]
126+
127+
proc test14420() = # bug #14420
128+
# s/proc/template/ would hit bug #16005
129+
block:
130+
type Foo = object
131+
x: float
132+
133+
proc fn(a: var Foo): var float =
134+
## WAS: discard <- turn this into a comment (or a `discard`) and error disappears
135+
# result = a.x # this works
136+
a.x # WAS: Error: limited VM support for 'addr'
137+
138+
proc fn2(a: var Foo): var float =
139+
result = a.x # this works
140+
a.x # WAS: Error: limited VM support for 'addr'
141+
142+
var a = Foo()
143+
discard fn(a)
144+
discard fn2(a)
145+
146+
block:
147+
proc byLent2[T](a: T): lent T =
148+
runnableExamples: discard
149+
a
150+
proc byLent3[T](a: T): lent T =
151+
runnableExamples: discard
152+
result = a
153+
var a = 10
154+
let x3 = byLent3(a) # works
155+
let x2 = byLent2(a) # WAS: Error: internal error: genAddr: nkStmtListExpr
156+
157+
block:
158+
type MyOption[T] = object
159+
case has: bool
160+
of true:
161+
value: T
162+
of false:
163+
discard
164+
func some[T](val: T): MyOption[T] =
165+
result = MyOption[T](has: true, value: val)
166+
func get[T](opt: MyOption[T]): lent T =
167+
doAssert opt.has
168+
# result = opt.value # this was ok
169+
opt.value # this had the bug
170+
let x = some(10)
171+
doAssert x.get() == 10
172+
173+
template test14339() = # bug #14339
174+
block:
175+
type
176+
Node = ref object
177+
val: int
178+
proc bar(c: Node): var int =
179+
var n = c # was: Error: limited VM support for 'addr'
180+
c.val
181+
var a = Node()
182+
discard a.bar()
183+
block:
184+
type
185+
Node = ref object
186+
val: int
187+
proc bar(c: Node): var int =
188+
var n = c
189+
doAssert n.val == n[].val
190+
n.val
191+
var a = Node(val: 3)
192+
a.bar() = 5
193+
when nimvm:
194+
doAssert a.val == 5
195+
else:
196+
when not defined(js): # pending bug #16003
197+
doAssert a.val == 5
198+
199+
template main =
200+
# xxx wrap all other tests here like that so they're also tested in VM
201+
test14420()
202+
test14339()
203+
204+
static: main()
205+
main()

tests/stdlib/tcritbits.nim

Lines changed: 50 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,69 @@
1-
import sequtils, critbits
1+
import std/[sequtils,critbits]
22

3+
template main =
4+
var r: CritBitTree[void]
5+
r.incl "abc"
6+
r.incl "xyz"
7+
r.incl "def"
8+
r.incl "definition"
9+
r.incl "prefix"
10+
r.incl "foo"
311

4-
var r: CritBitTree[void]
5-
r.incl "abc"
6-
r.incl "xyz"
7-
r.incl "def"
8-
r.incl "definition"
9-
r.incl "prefix"
10-
r.incl "foo"
12+
doAssert r.contains"def"
1113

12-
doAssert r.contains"def"
14+
r.excl "def"
15+
assert r.missingOrExcl("foo") == false
16+
assert "foo" notin toSeq(r.items)
1317

14-
r.excl "def"
15-
assert r.missingOrExcl("foo") == false
16-
assert "foo" notin toSeq(r.items)
18+
assert r.missingOrExcl("foo") == true
1719

18-
assert r.missingOrExcl("foo") == true
20+
assert toSeq(r.items) == @["abc", "definition", "prefix", "xyz"]
1921

20-
assert toSeq(r.items) == @["abc", "definition", "prefix", "xyz"]
22+
assert toSeq(r.itemsWithPrefix("de")) == @["definition"]
23+
var c = CritBitTree[int]()
2124

22-
assert toSeq(r.itemsWithPrefix("de")) == @["definition"]
23-
var c = CritBitTree[int]()
25+
c.inc("a")
26+
assert c["a"] == 1
2427

25-
c.inc("a")
26-
assert c["a"] == 1
28+
c.inc("a", 4)
29+
assert c["a"] == 5
2730

28-
c.inc("a", 4)
29-
assert c["a"] == 5
31+
c.inc("a", -5)
32+
assert c["a"] == 0
3033

31-
c.inc("a", -5)
32-
assert c["a"] == 0
34+
c.inc("b", 2)
35+
assert c["b"] == 2
3336

34-
c.inc("b", 2)
35-
assert c["b"] == 2
37+
c.inc("c", 3)
38+
assert c["c"] == 3
3639

37-
c.inc("c", 3)
38-
assert c["c"] == 3
40+
c.inc("a", 1)
41+
assert c["a"] == 1
3942

40-
c.inc("a", 1)
41-
assert c["a"] == 1
43+
var cf = CritBitTree[float]()
4244

43-
var cf = CritBitTree[float]()
45+
cf.incl("a", 1.0)
46+
assert cf["a"] == 1.0
4447

45-
cf.incl("a", 1.0)
46-
assert cf["a"] == 1.0
48+
cf.incl("b", 2.0)
49+
assert cf["b"] == 2.0
4750

48-
cf.incl("b", 2.0)
49-
assert cf["b"] == 2.0
51+
cf.incl("c", 3.0)
52+
assert cf["c"] == 3.0
5053

51-
cf.incl("c", 3.0)
52-
assert cf["c"] == 3.0
54+
assert cf.len == 3
55+
cf.excl("c")
56+
assert cf.len == 2
5357

54-
assert cf.len == 3
55-
cf.excl("c")
56-
assert cf.len == 2
58+
var cb: CritBitTree[string]
59+
cb.incl("help", "help")
60+
for k in cb.keysWithPrefix("helpp"):
61+
doAssert false, "there is no prefix helpp"
5762

58-
var cb: CritBitTree[string]
59-
cb.incl("help", "help")
60-
for k in cb.keysWithPrefix("helpp"):
61-
doAssert false, "there is no prefix helpp"
63+
block: # bug #14339
64+
var strings: CritBitTree[int]
65+
discard strings.containsOrIncl("foo", 3)
66+
doAssert strings["foo"] == 3
67+
68+
main()
69+
static: main()

0 commit comments

Comments
 (0)