From d960390d98c1320651bcd099610b5fd8425d5cb5 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 16 Nov 2020 10:56:23 -0800 Subject: [PATCH 1/5] fix #14339: fixes limited VM support for addr --- compiler/vm.nim | 7 ++- tests/misc/taddr.nim | 13 ++++++ tests/stdlib/tcritbits.nim | 92 +++++++++++++++++++++----------------- 3 files changed, 68 insertions(+), 44 deletions(-) diff --git a/compiler/vm.nim b/compiler/vm.nim index a6478f3f06fc..17bbe65fc984 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -746,10 +746,13 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = regs[ra].regAddr = addr(regs[rb]) of opcAddrNode: decodeB(rkNodeAddr) - if regs[rb].kind == rkNode: + case regs[rb].kind + of rkNode: regs[ra].nodeAddr = addr(regs[rb].node) + of rkNodeAddr: # bug #14339 + regs[ra].nodeAddr = regs[rb].nodeAddr else: - stackTrace(c, tos, pc, "limited VM support for 'addr'") + stackTrace(c, tos, pc, "limited VM support for 'addr', got kind: " & $regs[rb].kind) of opcLdDeref: # a = b[] let ra = instr.regA diff --git a/tests/misc/taddr.nim b/tests/misc/taddr.nim index 49a577798664..6b152ed55ac2 100644 --- a/tests/misc/taddr.nim +++ b/tests/misc/taddr.nim @@ -123,3 +123,16 @@ block: block: # pending bug #15959 when false: proc byLent2[T](a: T): lent type(a[0]) = a[0] + +block: # bug #14339 + type + Node = ref object + val: int + proc bar(c: Node): var int = + var n = c # was: Error: limited VM support for 'addr' + c.val + proc main = + var a = Node() + discard a.bar() + static: main() + main() diff --git a/tests/stdlib/tcritbits.nim b/tests/stdlib/tcritbits.nim index 51cbb7bf21ef..4b05cd95034b 100644 --- a/tests/stdlib/tcritbits.nim +++ b/tests/stdlib/tcritbits.nim @@ -1,61 +1,69 @@ -import sequtils, critbits +import std/[sequtils,critbits] +template main = + var r: CritBitTree[void] + r.incl "abc" + r.incl "xyz" + r.incl "def" + r.incl "definition" + r.incl "prefix" + r.incl "foo" -var r: CritBitTree[void] -r.incl "abc" -r.incl "xyz" -r.incl "def" -r.incl "definition" -r.incl "prefix" -r.incl "foo" + doAssert r.contains"def" -doAssert r.contains"def" + r.excl "def" + assert r.missingOrExcl("foo") == false + assert "foo" notin toSeq(r.items) -r.excl "def" -assert r.missingOrExcl("foo") == false -assert "foo" notin toSeq(r.items) + assert r.missingOrExcl("foo") == true -assert r.missingOrExcl("foo") == true + assert toSeq(r.items) == @["abc", "definition", "prefix", "xyz"] -assert toSeq(r.items) == @["abc", "definition", "prefix", "xyz"] + assert toSeq(r.itemsWithPrefix("de")) == @["definition"] + var c = CritBitTree[int]() -assert toSeq(r.itemsWithPrefix("de")) == @["definition"] -var c = CritBitTree[int]() + c.inc("a") + assert c["a"] == 1 -c.inc("a") -assert c["a"] == 1 + c.inc("a", 4) + assert c["a"] == 5 -c.inc("a", 4) -assert c["a"] == 5 + c.inc("a", -5) + assert c["a"] == 0 -c.inc("a", -5) -assert c["a"] == 0 + c.inc("b", 2) + assert c["b"] == 2 -c.inc("b", 2) -assert c["b"] == 2 + c.inc("c", 3) + assert c["c"] == 3 -c.inc("c", 3) -assert c["c"] == 3 + c.inc("a", 1) + assert c["a"] == 1 -c.inc("a", 1) -assert c["a"] == 1 + var cf = CritBitTree[float]() -var cf = CritBitTree[float]() + cf.incl("a", 1.0) + assert cf["a"] == 1.0 -cf.incl("a", 1.0) -assert cf["a"] == 1.0 + cf.incl("b", 2.0) + assert cf["b"] == 2.0 -cf.incl("b", 2.0) -assert cf["b"] == 2.0 + cf.incl("c", 3.0) + assert cf["c"] == 3.0 -cf.incl("c", 3.0) -assert cf["c"] == 3.0 + assert cf.len == 3 + cf.excl("c") + assert cf.len == 2 -assert cf.len == 3 -cf.excl("c") -assert cf.len == 2 + var cb: CritBitTree[string] + cb.incl("help", "help") + for k in cb.keysWithPrefix("helpp"): + doAssert false, "there is no prefix helpp" -var cb: CritBitTree[string] -cb.incl("help", "help") -for k in cb.keysWithPrefix("helpp"): - doAssert false, "there is no prefix helpp" + block: # bug #14339 + var strings: CritBitTree[int] + discard strings.containsOrIncl("foo", 3) + doAssert strings["foo"] == 3 + +main() +static: main() From bacf4aa4cc48b163da04e4795dfdce7fd106a019 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 16 Nov 2020 11:48:14 -0800 Subject: [PATCH 2/5] strengthen test --- tests/misc/taddr.nim | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/tests/misc/taddr.nim b/tests/misc/taddr.nim index 6b152ed55ac2..a202bb58604e 100644 --- a/tests/misc/taddr.nim +++ b/tests/misc/taddr.nim @@ -124,15 +124,27 @@ block: when false: proc byLent2[T](a: T): lent type(a[0]) = a[0] -block: # bug #14339 - type - Node = ref object - val: int - proc bar(c: Node): var int = - var n = c # was: Error: limited VM support for 'addr' - c.val - proc main = +template test14339() = # bug #14339 + block: + type + Node = ref object + val: int + proc bar(c: Node): var int = + var n = c # was: Error: limited VM support for 'addr' + c.val var a = Node() discard a.bar() - static: main() - main() + block: + type + Node = ref object + val: int + proc bar(c: Node): var int = + var n = c + doAssert n.val == n[].val + n.val + var a = Node(val: 3) + a.bar() = 5 + doAssert a.val == 5 + +test14339() +static: test14339() From dffafdb37fe7f7d9a358df4af50f341da2c0141c Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 16 Nov 2020 11:56:48 -0800 Subject: [PATCH 3/5] reference bug #16003 --- tests/misc/taddr.nim | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/misc/taddr.nim b/tests/misc/taddr.nim index a202bb58604e..020b4807f67c 100644 --- a/tests/misc/taddr.nim +++ b/tests/misc/taddr.nim @@ -144,7 +144,11 @@ template test14339() = # bug #14339 n.val var a = Node(val: 3) a.bar() = 5 - doAssert a.val == 5 + when nimvm: + doAssert a.val == 5 + else: + when not defined(js): # pending bug #16003 + doAssert a.val == 5 test14339() static: test14339() From e022e67ff4a8e79f61e34de69b1302b091a81c32 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 16 Nov 2020 12:16:18 -0800 Subject: [PATCH 4/5] also fixes #13511 --- tests/macros/tmacros_various.nim | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/macros/tmacros_various.nim b/tests/macros/tmacros_various.nim index 05683083753c..00d74cb5c97a 100644 --- a/tests/macros/tmacros_various.nim +++ b/tests/macros/tmacros_various.nim @@ -245,3 +245,28 @@ xbenchmark: discard inputtest fastSHA("hey") + +block: # bug #13511 + type + Builder = ref object + components: seq[Component] + Component = object + + proc add(builder: var Builder, component: Component) {.compileTime.} = + builder.components.add(component) + + macro debugAst(arg: typed): untyped = + ## just for debugging purpose. + discard arg.treeRepr + return arg + + static: + var component = Component() + var builder = Builder() + + template foo(): untyped = + ## WAS: this doc comment causes compilation failure. + builder + + debugAst: + add(foo(), component) From a7bb1f29fc6f2cc956bd56225c14b034691f482c Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 16 Nov 2020 14:05:52 -0800 Subject: [PATCH 5/5] also fixes #14420 --- tests/misc/taddr.nim | 55 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/tests/misc/taddr.nim b/tests/misc/taddr.nim index 020b4807f67c..d743d4b4a4d9 100644 --- a/tests/misc/taddr.nim +++ b/tests/misc/taddr.nim @@ -124,6 +124,52 @@ block: when false: proc byLent2[T](a: T): lent type(a[0]) = a[0] +proc test14420() = # bug #14420 + # s/proc/template/ would hit bug #16005 + block: + type Foo = object + x: float + + proc fn(a: var Foo): var float = + ## WAS: discard <- turn this into a comment (or a `discard`) and error disappears + # result = a.x # this works + a.x # WAS: Error: limited VM support for 'addr' + + proc fn2(a: var Foo): var float = + result = a.x # this works + a.x # WAS: Error: limited VM support for 'addr' + + var a = Foo() + discard fn(a) + discard fn2(a) + + block: + proc byLent2[T](a: T): lent T = + runnableExamples: discard + a + proc byLent3[T](a: T): lent T = + runnableExamples: discard + result = a + var a = 10 + let x3 = byLent3(a) # works + let x2 = byLent2(a) # WAS: Error: internal error: genAddr: nkStmtListExpr + + block: + type MyOption[T] = object + case has: bool + of true: + value: T + of false: + discard + func some[T](val: T): MyOption[T] = + result = MyOption[T](has: true, value: val) + func get[T](opt: MyOption[T]): lent T = + doAssert opt.has + # result = opt.value # this was ok + opt.value # this had the bug + let x = some(10) + doAssert x.get() == 10 + template test14339() = # bug #14339 block: type @@ -150,5 +196,10 @@ template test14339() = # bug #14339 when not defined(js): # pending bug #16003 doAssert a.val == 5 -test14339() -static: test14339() +template main = + # xxx wrap all other tests here like that so they're also tested in VM + test14420() + test14339() + +static: main() +main()