summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/vm.nim5
-rw-r--r--compiler/vmgen.nim22
-rw-r--r--tests/cpp/tasync_cpp.nim11
3 files changed, 37 insertions, 1 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim
index ded66d3d0..7ba4aaeb6 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -511,7 +511,10 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       regs[ra].regAddr = addr(regs[rb])
     of opcAddrNode:
       decodeB(rkNodeAddr)
-      regs[ra].nodeAddr = addr(regs[rb].node)
+      if regs[rb].kind == rkNode:
+        regs[ra].nodeAddr = addr(regs[rb].node)
+      else:
+        stackTrace(c, tos, pc, errGenerated, "limited VM support for 'addr'")
     of opcLdDeref:
       # a = b[]
       let ra = instr.regA
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 92db0d513..97c6a5580 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -1091,10 +1091,32 @@ proc requiresCopy(n: PNode): bool =
 proc unneededIndirection(n: PNode): bool =
   n.typ.skipTypes(abstractInst-{tyTypeDesc}).kind == tyRef
 
+proc canElimAddr(n: PNode): PNode =
+  case n.sons[0].kind
+  of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
+    var m = n.sons[0].sons[0]
+    if m.kind in {nkDerefExpr, nkHiddenDeref}:
+      # addr ( nkConv ( deref ( x ) ) ) --> nkConv(x)
+      result = copyNode(n.sons[0])
+      result.add m.sons[0]
+  of nkHiddenStdConv, nkHiddenSubConv, nkConv:
+    var m = n.sons[0].sons[1]
+    if m.kind in {nkDerefExpr, nkHiddenDeref}:
+      # addr ( nkConv ( deref ( x ) ) ) --> nkConv(x)
+      result = copyNode(n.sons[0])
+      result.add m.sons[0]
+  else:
+    if n.sons[0].kind in {nkDerefExpr, nkHiddenDeref}:
+      # addr ( deref ( x )) --> x
+      result = n.sons[0].sons[0]
+
 proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
                   flags: TGenFlags) =
   # a nop for certain types
   let isAddr = opc in {opcAddrNode, opcAddrReg}
+  if isAddr and (let m = canElimAddr(n); m != nil):
+    gen(c, m, dest, flags)
+    return
   let newflags = if isAddr: flags+{gfAddrOf} else: flags
   # consider:
   # proc foo(f: var ref int) =
diff --git a/tests/cpp/tasync_cpp.nim b/tests/cpp/tasync_cpp.nim
new file mode 100644
index 000000000..792f2938b
--- /dev/null
+++ b/tests/cpp/tasync_cpp.nim
@@ -0,0 +1,11 @@
+discard """
+  cmd: "nim cpp $file"
+  output: "hello"
+"""
+
+# bug #3299
+
+import jester
+import asyncdispatch, asyncnet
+
+echo "hello"