summary refs log tree commit diff stats
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
parent866205cba4c9ac9a5831afe5ffd997eec5c9bebf (diff)
parentc41687237d78c99e3216f83086e71d59252fa775 (diff)
downloadNim-4ef62584da0d0f30f9db03a76201dec8742bb4a1.tar.gz
Merge branch 'devel' of github.com:Araq/Nimrod into devel
-rw-r--r--compiler/vm.nim2
-rw-r--r--compiler/vmgen.nim35
-rw-r--r--lib/pure/dynlib.nim10
-rw-r--r--tests/macros/tvarnimnode.nim19
-rw-r--r--tests/manyloc/argument_parser/argument_parser.nim4
-rw-r--r--todo.txt4
6 files changed, 58 insertions, 16 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 81e712047..0929e072b 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -1025,7 +1025,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
       regs[ra].sons[0].flags.incl nfIsRef
     of opcNCopyNimNode:
       decodeB(nkMetaNode)
-      setMeta(regs[ra], copyNode(regs[rb]))
+      setMeta(regs[ra], copyNode(regs[rb].skipMeta))
     of opcNCopyNimTree:
       decodeB(nkMetaNode)
       setMeta(regs[ra], copyTree(regs[rb]))
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)
diff --git a/lib/pure/dynlib.nim b/lib/pure/dynlib.nim
index 3ed00fdb2..889912052 100644
--- a/lib/pure/dynlib.nim
+++ b/lib/pure/dynlib.nim
@@ -14,7 +14,7 @@
 type
   TLibHandle* = pointer ## a handle to a dynamically loaded library
 
-proc loadLib*(path: string): TLibHandle
+proc loadLib*(path: string, global_symbols=false): TLibHandle
   ## loads a library from `path`. Returns nil if the library could not 
   ## be loaded.
 
@@ -53,6 +53,7 @@ when defined(posix):
   #
   var
     RTLD_NOW {.importc: "RTLD_NOW", header: "<dlfcn.h>".}: int
+    RTLD_GLOBAL {.importc: "RTLD_GLOBAL", header: "<dlfcn.h>".}: int
 
   proc dlclose(lib: TLibHandle) {.importc, header: "<dlfcn.h>".}
   proc dlopen(path: CString, mode: int): TLibHandle {.
@@ -60,7 +61,10 @@ when defined(posix):
   proc dlsym(lib: TLibHandle, name: cstring): pointer {.
       importc, header: "<dlfcn.h>".}
 
-  proc loadLib(path: string): TLibHandle = return dlopen(path, RTLD_NOW)
+  proc loadLib(path: string, global_symbols=false): TLibHandle = 
+    var flags = RTLD_NOW
+    if global_symbols: flags = flags or RTLD_GLOBAL
+    return dlopen(path, flags)
   proc loadLib(): TLibHandle = return dlopen(nil, RTLD_NOW)
   proc unloadLib(lib: TLibHandle) = dlclose(lib)
   proc symAddr(lib: TLibHandle, name: cstring): pointer = 
@@ -81,7 +85,7 @@ elif defined(windows) or defined(dos):
   proc getProcAddress(lib: THINSTANCE, name: cstring): pointer {.
       importc: "GetProcAddress", header: "<windows.h>", stdcall.}
 
-  proc loadLib(path: string): TLibHandle =
+  proc loadLib(path: string, global_symbols=false): TLibHandle =
     result = cast[TLibHandle](winLoadLibrary(path))
   proc loadLib(): TLibHandle =
     result = cast[TLibHandle](winLoadLibrary(nil))
diff --git a/tests/macros/tvarnimnode.nim b/tests/macros/tvarnimnode.nim
new file mode 100644
index 000000000..73fcc16ea
--- /dev/null
+++ b/tests/macros/tvarnimnode.nim
@@ -0,0 +1,19 @@
+discard """
+  output: 10
+"""
+
+#bug #926
+
+import macros
+
+proc test(f: var PNimrodNode) {.compileTime.} =
+  f = newNimNode(nnkStmtList)
+  f.add newCall(newIdentNode("echo"), newLit(10))
+
+macro blah(prc: stmt): stmt =
+  result = prc
+
+  test(result)
+
+proc test() {.blah.} =
+  echo 5
diff --git a/tests/manyloc/argument_parser/argument_parser.nim b/tests/manyloc/argument_parser/argument_parser.nim
index 95c71c08c..1edda4aa0 100644
--- a/tests/manyloc/argument_parser/argument_parser.nim
+++ b/tests/manyloc/argument_parser/argument_parser.nim
@@ -178,14 +178,14 @@ template new_parsed_parameter*(tkind: Tparam_kind, expr): Tparsed_parameter =
   ##     #parsed_param3 = new_parsed_parameter(PK_INT, "231")
   var result {.gensym.}: Tparsed_parameter
   result.kind = tkind
-  when tkind == PK_EMPTY: nil
+  when tkind == PK_EMPTY: discard
   elif tkind == PK_INT: result.int_val = expr
   elif tkind == PK_BIGGEST_INT: result.big_int_val = expr
   elif tkind == PK_FLOAT: result.float_val = expr
   elif tkind == PK_BIGGEST_FLOAT: result.big_float_val = expr
   elif tkind == PK_STRING: result.str_val = expr
   elif tkind == PK_BOOL: result.bool_val = expr
-  elif tkind == PK_HELP: nil
+  elif tkind == PK_HELP: discard
   else: {.error: "unknown kind".}
   result
 
diff --git a/todo.txt b/todo.txt
index 2e6eb708b..656bd06fc 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,8 +1,10 @@
 version 0.9.4
 =============
 
+- fix macros\tstringinterp.nim:
+  - problem: needs another level of indirection for 'seq'
+  - problem: deref is not correct
 - fix GC issues
-- fix macros\tstringinterp.nim
 - test and fix showoff