summary refs log tree commit diff stats
path: root/compiler/vmgen.nim
diff options
context:
space:
mode:
authorDominik Picheta <dominikpicheta@googlemail.com>2014-02-18 00:19:01 +0000
committerDominik Picheta <dominikpicheta@googlemail.com>2014-02-18 00:19:01 +0000
commit4ef62584da0d0f30f9db03a76201dec8742bb4a1 (patch)
tree004e5a4ee79b91542021ae0f07d7d2b5af6039ca /compiler/vmgen.nim
parent866205cba4c9ac9a5831afe5ffd997eec5c9bebf (diff)
parentc41687237d78c99e3216f83086e71d59252fa775 (diff)
downloadNim-4ef62584da0d0f30f9db03a76201dec8742bb4a1.tar.gz
Merge branch 'devel' of github.com:Araq/Nimrod into devel
Diffstat (limited to 'compiler/vmgen.nim')
-rw-r--r--compiler/vmgen.nim35
1 files changed, 26 insertions, 9 deletions
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index a6d044e24..206cca0d7 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -321,9 +321,18 @@ proc genAndOr(c: PCtx; n: PNode; opc: TOpcode; dest: var TDest) =
   c.gen(n.sons[2], dest)
   c.patch(L1)
 
+proc nilLiteral(n: PNode): PNode =
+  if n.kind == nkNilLit and n.typ.sym != nil and
+       n.typ.sym.magic == mPNimrodNode:
+    let nilo = newNodeIT(nkNilLit, n.info, n.typ)
+    result = newNodeIT(nkMetaNode, n.info, n.typ)
+    result.add nilo
+  else:
+    result = n
+
 proc rawGenLiteral(c: PCtx; n: PNode): int =
   result = c.constants.len
-  c.constants.add n
+  c.constants.add n.nilLiteral
   internalAssert result < 0x7fff
 
 proc sameConstant*(a, b: PNode): bool =
@@ -907,17 +916,20 @@ proc requiresCopy(n: PNode): bool =
 proc unneededIndirection(n: PNode): bool =
   n.typ.skipTypes(abstractInst-{tyTypeDesc}).kind == tyRef
 
-proc skipDeref(n: PNode): PNode =
-  if n.kind in {nkDerefExpr, nkHiddenDeref} and unneededIndirection(n.sons[0]):
-    result = n.sons[0]
-  else:
-    result = n
-
 proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
                   flags: TGenFlags) = 
   # a nop for certain types
   let flags = if opc == opcAddr: flags+{gfAddrOf} else: flags
-  if unneededIndirection(n.sons[0]):
+  # consider:
+  # proc foo(f: var ref int) =
+  #   f = new(int)
+  # proc blah() =
+  #   var x: ref int
+  #   foo x
+  #
+  # The type of 'f' is 'var ref int' and of 'x' is 'ref int'. Hence for
+  # nkAddr we must not use 'unneededIndirection', but for deref we use it.
+  if opc != opcAddr and unneededIndirection(n.sons[0]):
     gen(c, n.sons[0], dest, flags)
   else:
     let tmp = c.genx(n.sons[0], flags)
@@ -1109,7 +1121,12 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
     result = newNodeIT(nkFloatLit, info, t)
   of tyVar, tyPointer, tyPtr, tyCString, tySequence, tyString, tyExpr,
      tyStmt, tyTypeDesc, tyStatic, tyRef:
-    result = newNodeIT(nkNilLit, info, t)
+    if t.sym != nil and t.sym.magic == mPNimrodNode:
+      let nilo = newNodeIT(nkNilLit, info, t)
+      result = newNodeIT(nkMetaNode, info, t)
+      result.add nilo
+    else:
+      result = newNodeIT(nkNilLit, info, t)
   of tyProc:
     if t.callConv != ccClosure:
       result = newNodeIT(nkNilLit, info, t)