summary refs log tree commit diff stats
path: root/compiler/vmgen.nim
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2015-07-21 10:21:14 +0300
committerZahary Karadjov <zahary@gmail.com>2015-08-02 23:58:22 +0300
commit02f97489b795cd33d49966e254b46fcc3f8072ba (patch)
treec2be27abe57fe3b0f1118f21065409abc9784629 /compiler/vmgen.nim
parent7af92708af94164cd1373be85a06dd4cc4e4439e (diff)
downloadNim-02f97489b795cd33d49966e254b46fcc3f8072ba.tar.gz
fix #1858 again; restores the support for static macro params
Diffstat (limited to 'compiler/vmgen.nim')
-rw-r--r--compiler/vmgen.nim21
1 files changed, 19 insertions, 2 deletions
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 1bee9788a..3f4ee8000 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -173,7 +173,8 @@ const
 proc bestEffort(c: PCtx): TLineInfo =
   (if c.prc == nil: c.module.info else: c.prc.sym.info)
 
-proc getTemp(cc: PCtx; typ: PType): TRegister =
+proc getTemp(cc: PCtx; tt: PType): TRegister =
+  let typ = tt.skipTypesOrNil({tyStatic})
   let c = cc.prc
   # we prefer the same slot kind here for efficiency. Unfortunately for
   # discardable return types we may not know the desired type. This can happen
@@ -707,7 +708,7 @@ proc genConv(c: PCtx; n, arg: PNode; dest: var TDest; opc=opcConv) =
   if dest < 0: dest = c.getTemp(n.typ)
   c.gABC(n, opc, dest, tmp)
   c.gABx(n, opc, 0, genType(c, n.typ))
-  c.gABx(n, opc, 0, genType(c, arg.typ))
+  c.gABx(n, opc, 0, genType(c, arg.typ.skipTypes({tyStatic})))
   c.freeTemp(tmp)
 
 proc genCard(c: PCtx; n: PNode; dest: var TDest) =
@@ -1617,6 +1618,11 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
         c.gABx(n, opcLdConst, dest, lit)
     of skType:
       genTypeLit(c, s.typ, dest)
+    of skGenericParam:
+      if c.prc.sym.kind == skMacro:
+        genRdVar(c, n, dest, flags)
+      else:
+        internalError(n.info, "cannot generate code for: " & s.name.s)
     else:
       globalError(n.info, errGenerated, "cannot generate code for: " & s.name.s)
   of nkCallKinds:
@@ -1767,6 +1773,14 @@ proc finalJumpTarget(c: PCtx; pc, diff: int) =
   c.code[pc] = ((oldInstr.uint32 and 0xffff'u32).uint32 or
                 uint32(diff+wordExcess) shl 16'u32).TInstr
 
+proc genGenericParams(c: PCtx; gp: PNode) =
+  var base = c.prc.maxSlots
+  for i in 0.. <gp.len:
+    var param = gp.sons[i].sym
+    param.position = base + i # XXX: fix this earlier; make it consistent with templates
+    c.prc.slots[base + i] = (inUse: true, kind: slotFixedLet)
+  c.prc.maxSlots = base + gp.len
+
 proc optimizeJumps(c: PCtx; start: int) =
   const maxIterations = 10
   for i in start .. <c.code.len:
@@ -1831,6 +1845,9 @@ proc genProc(c: PCtx; s: PSym): int =
     c.prc = p
     # iterate over the parameters and allocate space for them:
     genParams(c, s.typ.n)
+    # allocate additional space for any generically bound parameters
+    if s.kind == skMacro and s.ast[genericParamsPos].kind != nkEmpty:
+      genGenericParams(c, s.ast[genericParamsPos])
     if tfCapturesEnv in s.typ.flags:
       #let env = s.ast.sons[paramsPos].lastSon.sym
       #assert env.position == 2