summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ast.nim4
-rw-r--r--compiler/pragmas.nim19
-rw-r--r--compiler/semexprs.nim10
-rw-r--r--compiler/vm.nim6
-rw-r--r--compiler/vmdef.nim1
-rw-r--r--compiler/vmgen.nim2
6 files changed, 30 insertions, 12 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 30778c02d..dd6f47ed1 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -424,7 +424,7 @@ type
     nfIsRef     # this node is a 'ref' node; used for the VM
  
   TNodeFlags* = set[TNodeFlag]
-  TTypeFlag* = enum   # keep below 32 for efficiency reasons (now: 23)
+  TTypeFlag* = enum   # keep below 32 for efficiency reasons (now: 28)
     tfVarargs,        # procedure has C styled varargs
     tfNoSideEffect,   # procedure type does not allow side effects
     tfFinal,          # is the object final?
@@ -464,6 +464,8 @@ type
                       # T and I here can bind to both typedesc and static types
                       # before this is determined, we'll consider them to be a
                       # wildcard type.
+    tfGuarded         # guarded pointer
+    tfBorrowDot       # distinct type borrows '.'
 
   TTypeFlags* = set[TTypeFlag]
 
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index efd06eef4..b5dead5b2 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -52,7 +52,8 @@ const
   typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl, 
     wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow,
     wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef,
-    wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked}
+    wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked,
+    wBorrow}
   fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern, 
     wImportCpp, wImportObjC, wError}
   varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, 
@@ -511,6 +512,13 @@ proc pragmaRaisesOrTags(c: PContext, n: PNode) =
   else:
     invalidPragma(n)
 
+proc typeBorrow(sym: PSym, n: PNode) =
+  if n.kind == nkExprColonExpr:
+    let it = n.sons[1]
+    if it.kind != nkAccQuoted:
+      localError(n.info, "a type can only borrow `.` for now")
+  incl(sym.typ.flags, tfBorrowDot)
+
 proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
                   validPragmas: TSpecialWords): bool =
   var it = n.sons[i]
@@ -631,9 +639,12 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
           noVal(it)
           if sym.typ == nil: invalidPragma(it)
           else: incl(sym.typ.flags, tfVarargs)
-        of wBorrow: 
-          noVal(it)
-          incl(sym.flags, sfBorrow)
+        of wBorrow:
+          if sym.kind == skType:
+            typeBorrow(sym, it)
+          else:
+            noVal(it)
+            incl(sym.flags, sfBorrow)
         of wFinal: 
           noVal(it)
           if sym.typ == nil: invalidPragma(it)
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index b3b757640..70c57b15e 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1001,15 +1001,15 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
     # reset to prevent 'nil' bug: see "tests/reject/tenumitems.nim":
     ty = n.sons[0].typ
     return nil
-    
   ty = skipTypes(ty, {tyGenericInst, tyVar, tyPtr, tyRef})
+  while tfBorrowDot in ty.flags: ty = ty.skipTypes({tyDistinct})
   var check: PNode = nil
-  if ty.kind == tyObject: 
-    while true: 
+  if ty.kind == tyObject:
+    while true:
       check = nil
       f = lookupInRecordAndBuildCheck(c, n, ty.n, i, check)
-      if f != nil: break 
-      if ty.sons[0] == nil: break 
+      if f != nil: break
+      if ty.sons[0] == nil: break
       ty = skipTypes(ty.sons[0], {tyGenericInst})
     if f != nil:
       if fieldVisible(c, f):
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 8fea6b293..268289aca 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -448,7 +448,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
         let n = src.sons[rc]
         regs[ra].node = n
       else:
-        stackTrace(c, tos, pc, errIndexOutOfBounds)
+        stackTrace(c, tos, pc, errNilAccess)
     of opcWrObj:
       # a.b = c
       decodeBC(rkNode)
@@ -902,6 +902,10 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       let rb = instr.regBx - wordExcess - 1
       ensureKind(rkNode)
       regs[ra].node = c.globals.sons[rb]
+    of opcLdGlobalAddr:
+      let rb = instr.regBx - wordExcess - 1
+      ensureKind(rkNodeAddr)
+      regs[ra].nodeAddr = addr(c.globals.sons[rb])
     of opcRepr:
       decodeB(rkNode)
       createStr regs[ra]
diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim
index 90ff8e29f..d0c38a2ad 100644
--- a/compiler/vmdef.nim
+++ b/compiler/vmdef.nim
@@ -126,6 +126,7 @@ type
     opcLdConst,   # dest = constants[Bx]
     opcAsgnConst, # dest = copy(constants[Bx])
     opcLdGlobal,  # dest = globals[Bx]
+    opcLdGlobalAddr, # dest = addr(globals[Bx])
 
     opcLdImmInt,  # dest = immediate value
     opcNBindSym,
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 59d3d2495..e627fee48 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -1614,7 +1614,7 @@ proc genProc(c: PCtx; s: PSym): int =
     c.gABC(body, opcEof, eofInstr.regA)
     c.optimizeJumps(result)
     s.offset = c.prc.maxSlots
-    #if s.name.s == "tupleUnpack":
+    #if s.name.s == "addStuff":
     #  echo renderTree(body)
     #  c.echoCode(result)
     c.prc = oldPrc