summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/vm.nim33
-rw-r--r--compiler/vmdeps.nim40
-rw-r--r--compiler/vmgen.nim6
-rw-r--r--lib/core/macros.nim6
4 files changed, 62 insertions, 23 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim
index f799334d6..ee58b6d48 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -1185,19 +1185,28 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
     of opcNGetType:
       let rb = instr.regB
       let rc = instr.regC
-      if rc == 0:
-        ensureKind(rkNode)
-        if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
-          regs[ra].node = opMapTypeToAst(regs[rb].node.typ, c.debug[pc])
+      case rc:
+        of 0:
+          # getType opcode:
+          ensureKind(rkNode)
+          if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
+            regs[ra].node = opMapTypeToAst(regs[rb].node.typ, c.debug[pc])
+          else:
+            stackTrace(c, tos, pc, errGenerated, "node has no type")
+        of 1:
+          # typeKind opcode:
+          ensureKind(rkInt)
+          if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
+            regs[ra].intVal = ord(regs[rb].node.typ.kind)
+          #else:
+          #  stackTrace(c, tos, pc, errGenerated, "node has no type")
         else:
-          stackTrace(c, tos, pc, errGenerated, "node has no type")
-      else:
-        # typeKind opcode:
-        ensureKind(rkInt)
-        if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
-          regs[ra].intVal = ord(regs[rb].node.typ.kind)
-        #else:
-        #  stackTrace(c, tos, pc, errGenerated, "node has no type")
+          # getTypeInst opcode:
+          ensureKind(rkNode)
+          if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
+            regs[ra].node = opMapTypeInstToAst(regs[rb].node.typ, c.debug[pc])
+          else:
+            stackTrace(c, tos, pc, errGenerated, "node has no type")
     of opcNStrVal:
       decodeB(rkNode)
       createStr regs[ra]
diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim
index a4f02092d..9519da8ba 100644
--- a/compiler/vmdeps.nim
+++ b/compiler/vmdeps.nim
@@ -67,9 +67,11 @@ proc atomicTypeX(name: string; t: PType; info: TLineInfo): PNode =
   result = newSymNode(sym)
   result.typ = t
 
-proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode
+proc mapTypeToAstImpl(t: PType; info: TLineInfo;
+                      inst=false; allowRecursion=false): PNode
 
-proc mapTypeToBracket(name: string; t: PType; info: TLineInfo): PNode =
+proc mapTypeToBracketImpl(name: string; t: PType; info: TLineInfo;
+                          inst=false): PNode =
   result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
   result.add atomicTypeX(name, t, info)
   for i in 0 .. < t.len:
@@ -78,10 +80,14 @@ proc mapTypeToBracket(name: string; t: PType; info: TLineInfo): PNode =
       void.typ = newType(tyEmpty, t.owner)
       result.add void
     else:
-      result.add mapTypeToAst(t.sons[i], info)
+      result.add mapTypeToAstImpl(t.sons[i], info, inst)
 
-proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode =
+proc mapTypeToAstImpl(t: PType; info: TLineInfo;
+                      inst=false; allowRecursion=false): PNode =
   template atomicType(name): expr = atomicTypeX(name, t, info)
+  template mapTypeToAst(t,info): expr = mapTypeToAstImpl(t, info, inst)
+  template mapTypeToBracket(name,t,info): expr =
+    mapTypeToBracketImpl(name, t, info, inst)
 
   case t.kind
   of tyNone: result = atomicType("none")
@@ -107,7 +113,14 @@ proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode =
     result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
     for i in 0 .. < t.len:
       result.add mapTypeToAst(t.sons[i], info)
-  of tyGenericInst, tyGenericBody, tyOrdinal, tyUserTypeClassInst:
+  of tyGenericInst:
+    if inst:
+      result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
+      for i in 0 .. < t.len-1:
+        result.add mapTypeToAst(t.sons[i], info)
+    else:
+      result = mapTypeToAst(t.lastSon, info)
+  of tyGenericBody, tyOrdinal, tyUserTypeClassInst:
     result = mapTypeToAst(t.lastSon, info)
   of tyDistinct:
     if allowRecursion:
@@ -174,10 +187,17 @@ proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode =
   of tyNot: result = mapTypeToBracket("not", t, info)
   of tyAnything: result = atomicType"anything"
   of tyStatic, tyFromExpr, tyFieldAccessor:
-    result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
-    result.add atomicType("static")
-    if t.n != nil:
-      result.add t.n.copyTree
+    if inst:
+      if t.n != nil: result = t.n.copyTree
+      else: result = atomicType "void"
+    else:
+      result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
+      result.add atomicType("static")
+      if t.n != nil:
+        result.add t.n.copyTree
 
 proc opMapTypeToAst*(t: PType; info: TLineInfo): PNode =
-  result = mapTypeToAst(t, info, true)
+  result = mapTypeToAstImpl(t, info, false, true)
+
+proc opMapTypeInstToAst*(t: PType; info: TLineInfo): PNode =
+  result = mapTypeToAstImpl(t, info, true, true)
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 019c79eb3..5ea0989dc 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -983,7 +983,11 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
   of mNGetType:
     let tmp = c.genx(n.sons[1])
     if dest < 0: dest = c.getTemp(n.typ)
-    c.gABC(n, opcNGetType, dest, tmp, if n[0].sym.name.s == "typeKind": 1 else: 0)
+    let rc = case n[0].sym.name.s:
+      of "getType": 0
+      of "typeKind": 1
+      else: 2  # "getTypeInst"
+    c.gABC(n, opcNGetType, dest, tmp, rc)
     c.freeTemp(tmp)
     #genUnaryABC(c, n, dest, opcNGetType)
   of mNStrVal: genUnaryABC(c, n, dest, opcNStrVal)
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index 678982a52..76fdea9b0 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -197,6 +197,12 @@ proc typeKind*(n: NimNode): NimTypeKind {.magic: "NGetType", noSideEffect.}
   ## Returns the type kind of the node 'n' that should represent a type, that
   ## means the node should have been obtained via `getType`.
 
+proc getTypeInst*(n: NimNode): NimNode {.magic: "NGetType", noSideEffect.}
+  ## Like getType except it includes generic parameters for a specific instance
+
+proc getTypeInst*(n: typedesc): NimNode {.magic: "NGetType", noSideEffect.}
+  ## Like getType except it includes generic parameters for a specific instance
+
 proc strVal*(n: NimNode): string  {.magic: "NStrVal", noSideEffect.}
 
 proc `intVal=`*(n: NimNode, val: BiggestInt) {.magic: "NSetIntVal", noSideEffect.}