summary refs log tree commit diff stats
path: root/tests/vm
diff options
context:
space:
mode:
Diffstat (limited to 'tests/vm')
-rw-r--r--tests/vm/meta.nim22
-rw-r--r--tests/vm/mevalffi.nim71
-rw-r--r--tests/vm/mscriptcompiletime.nim7
-rw-r--r--tests/vm/t11637.nim52
-rw-r--r--tests/vm/t17039.nim10
-rw-r--r--tests/vm/t17121.nim9
-rw-r--r--tests/vm/t18103.nim35
-rw-r--r--tests/vm/t19075.nim19
-rw-r--r--tests/vm/t19199.nim6
-rw-r--r--tests/vm/t20746.nim13
-rw-r--r--tests/vm/t21704.nim69
-rw-r--r--tests/vm/t2574.nim14
-rw-r--r--tests/vm/t9622.nim30
-rw-r--r--tests/vm/tableinstatic.nim4
-rw-r--r--tests/vm/taddrof.nim110
-rw-r--r--tests/vm/tanonproc.nim4
-rw-r--r--tests/vm/tbitops.nim45
-rw-r--r--tests/vm/tcastint.nim223
-rw-r--r--tests/vm/tcgemptycallarg.nim3
-rw-r--r--tests/vm/tclosureiterator.nim9
-rw-r--r--tests/vm/tcnstseq.nim68
-rw-r--r--tests/vm/tcompilesetting.nim18
-rw-r--r--tests/vm/tcompiletimerange.nim28
-rw-r--r--tests/vm/tcompiletimesideeffects.nim42
-rw-r--r--tests/vm/tcompiletimetable.nim17
-rw-r--r--tests/vm/tcomponent.nim2
-rw-r--r--tests/vm/tconst.nim58
-rw-r--r--tests/vm/tconstarrayresem.nim29
-rw-r--r--tests/vm/tconsteval.nim31
-rw-r--r--tests/vm/tconstobj.nim67
-rw-r--r--tests/vm/tconstprocassignments.nim18
-rw-r--r--tests/vm/tconstresem.nim10
-rw-r--r--tests/vm/tconstscope1.nim5
-rw-r--r--tests/vm/tconstscope2.nim5
-rw-r--r--tests/vm/tconsttable.nim15
-rw-r--r--tests/vm/tconsttable2.nim2
-rw-r--r--tests/vm/tconvaddr.nim49
-rw-r--r--tests/vm/teval1.nim26
-rw-r--r--tests/vm/texception.nim14
-rw-r--r--tests/vm/texcl.nim2
-rw-r--r--tests/vm/textensionmap.nim2
-rw-r--r--tests/vm/tfarjump.nim14
-rw-r--r--tests/vm/tfibconst.nim43
-rw-r--r--tests/vm/tfile_rw.nim22
-rw-r--r--tests/vm/tforwardproc.nim2
-rw-r--r--tests/vm/tgenericcompiletimeproc.nim36
-rw-r--r--tests/vm/tgloballetfrommacro.nim13
-rw-r--r--tests/vm/tgorge.nim9
-rwxr-xr-x[-rw-r--r--]tests/vm/tgorge.sh0
-rwxr-xr-x[-rw-r--r--]tests/vm/tgorgeex.sh0
-rw-r--r--tests/vm/tinheritance.nim79
-rw-r--r--tests/vm/tissues.nim76
-rw-r--r--tests/vm/tmanyregs.nim16
-rw-r--r--tests/vm/tmaxloopiterations.nim15
-rw-r--r--tests/vm/tmisc_vm.nim459
-rw-r--r--tests/vm/tmitems_vm.nim (renamed from tests/vm/tmitems.nim)6
-rw-r--r--tests/vm/tnewseqofcap.nim14
-rw-r--r--tests/vm/tnilclosurecall.nim8
-rw-r--r--tests/vm/tnilclosurecallstacktrace.nim23
-rw-r--r--tests/vm/tnilref.nim7
-rw-r--r--tests/vm/tnimnode.nim34
-rw-r--r--tests/vm/tnocompiletimefunc.nim14
-rw-r--r--tests/vm/tnocompiletimefunclambda.nim6
-rw-r--r--tests/vm/tnoreturn.nim32
-rw-r--r--tests/vm/topenarrays.nim89
-rw-r--r--tests/vm/toverflowopcaddimmint.nim2
-rw-r--r--tests/vm/toverflowopcaddint.nim2
-rw-r--r--tests/vm/toverflowopcmulint.nim4
-rw-r--r--tests/vm/toverflowopcsubimmint.nim2
-rw-r--r--tests/vm/toverflowopcsubint.nim2
-rw-r--r--tests/vm/tquadplus.nim5
-rw-r--r--tests/vm/tref.nim61
-rw-r--r--tests/vm/treset.nim50
-rw-r--r--tests/vm/trgba.nim36
-rw-r--r--tests/vm/triangle_array.nim6
-rw-r--r--tests/vm/tscriptcompiletime.nims9
-rw-r--r--tests/vm/tseq_badinit.nim4
-rw-r--r--tests/vm/tsetlen.nim30
-rw-r--r--tests/vm/tsignaturehash.nim20
-rw-r--r--tests/vm/tsimpleglobals.nim2
-rw-r--r--tests/vm/tslow_tables.nim30
-rw-r--r--tests/vm/tslurp.nim10
-rw-r--r--tests/vm/tstaticprintseq.nim6
-rw-r--r--tests/vm/tstring_openarray.nim25
-rw-r--r--tests/vm/tstringnil.nim10
-rw-r--r--tests/vm/tswap.nim14
-rw-r--r--tests/vm/ttouintconv.nim17
-rw-r--r--tests/vm/ttypedesc.nim31
-rw-r--r--tests/vm/tunsupportedintfloatcast.nim3
-rw-r--r--tests/vm/tvarsection.nim11
-rw-r--r--tests/vm/tvmmisc.nim750
-rw-r--r--tests/vm/tvmops.nim46
-rw-r--r--tests/vm/tvmopsDanger.nim13
-rw-r--r--tests/vm/twrong_concat.nim8
-rw-r--r--tests/vm/twrongarray.nim2
-rw-r--r--tests/vm/tyaytypedesc.nim8
-rw-r--r--tests/vm/tzero_extend.nim20
97 files changed, 3279 insertions, 240 deletions
diff --git a/tests/vm/meta.nim b/tests/vm/meta.nim
index 2aa01b5b3..32a441f27 100644
--- a/tests/vm/meta.nim
+++ b/tests/vm/meta.nim
@@ -39,7 +39,7 @@ proc newIdent*(node: NimNode): Ident =
       raise newException(ValueError, msg)
 
 proc render*(i: Ident): NimNode {.compileTime.} =
-  if i.name == nil:
+  if i.name == "":
     return newNimNode(nnkEmpty)
 
   if i.exported:
@@ -67,7 +67,7 @@ proc newBracket*(node: NimNode): Bracket =
       raise newException(ValueError, msg)
 
 # Field procs
-proc newField*(identifier: Ident, type_name: string, default: string = nil): Field =
+proc newField*(identifier: Ident, type_name: string, default: string = ""): Field =
   result.identifier = identifier
   result.type_name = type_name
   result.default = default
@@ -84,7 +84,7 @@ proc newField*(node: NimNode): Field =
         of nnkIdent:
           result.default = $(node[2])
         else:
-          result.default = nil
+          result.default = ""
     else:
       let msg = "newField cannot initialize from node kind: " & $(node.kind)
       raise newException(ValueError, msg)
@@ -102,7 +102,7 @@ proc newFieldSeq*(node: NimNode): FieldSeq =
         of nnkIdent:
           default = $(default_node)
         else:
-          default = nil
+          default = ""
       for i in 0..node.len - 3:
         let name = newIdent(node[i])
         result.add(newField(name, type_name, default))
@@ -115,8 +115,8 @@ proc newFieldSeq*(node: NimNode): FieldSeq =
 
 proc render*(f: Field): NimNode {.compileTime.} =
   let identifier = f.identifier.render()
-  let type_name = if f.type_name != nil: ident(f.type_name) else: newEmptyNode()
-  let default = if f.default != nil: ident(f.default) else: newEmptyNode()
+  let type_name = if f.type_name != "": ident(f.type_name) else: newEmptyNode()
+  let default = if f.default != "": ident(f.default) else: newEmptyNode()
   newIdentDefs(identifier, type_name, default)
 
 proc render*(fs: FieldSeq): NimNode {.compileTime.} =
@@ -127,7 +127,7 @@ proc render*(fs: FieldSeq): NimNode {.compileTime.} =
 # TypeDef procs
 proc newTypeDef*(identifier: Ident, is_ref = false,
                 object_type = "object",
-                base_type: string = nil): TypeDef {.compileTime.} =
+                base_type: string = ""): TypeDef {.compileTime.} =
   result.identifier = identifier
   result.fields = @[]
   result.is_ref = is_ref
@@ -165,7 +165,7 @@ proc render*(typedef: TypeDef): NimNode {.compileTime.} =
   result.add(newEmptyNode())
   let object_node = newNimNode(nnkObjectTy)
   object_node.add(newEmptyNode())
-  if typedef.base_type == nil:
+  if typedef.base_type == "":
     object_node.add(newEmptyNode())
   else:
     var base_type = newNimNode(nnkOfInherit)
@@ -195,8 +195,8 @@ proc render*(typeseq: TypeDefSeq): NimNode {.compileTime.} =
   for typedef in typeseq:
     result.add(typedef.render())
 
-proc newProc*(identifier: Ident, params: FieldSeq = nil,
-              returns: Ident, generics: FieldSeq = nil): Proc =
+proc newProc*(identifier: Ident, params: FieldSeq = @[],
+              returns: Ident, generics: FieldSeq = @[]): Proc =
   result.identifier = identifier
   result.params = params
   result.returns = returns
@@ -209,7 +209,7 @@ proc newProc*(node: NimNode): Proc =
       case node[2].kind:
         of nnkGenericParams:
           result.generics = newFieldSeq(node[2])
-        else: result.generics = nil
+        else: result.generics = @[]
       let formal_params = node[3]
       case formal_params[0].kind:
         of nnkIdent:
diff --git a/tests/vm/mevalffi.nim b/tests/vm/mevalffi.nim
new file mode 100644
index 000000000..ad8f8b62b
--- /dev/null
+++ b/tests/vm/mevalffi.nim
@@ -0,0 +1,71 @@
+# re-enable for windows once libffi can be installed in koch.nim
+# With win32 (not yet win64), libffi on windows works and this test passes.
+
+when defined(linux) or defined(bsd):
+  {.passL: "-lm".} # for exp
+proc c_exp(a: float64): float64 {.importc: "exp", header: "<math.h>".}
+
+proc c_printf(frmt: cstring): cint {.importc: "printf", header: "<stdio.h>", varargs, discardable.}
+
+const snprintfName = when defined(windows): "_snprintf" else: "snprintf"
+proc c_snprintf*(str: cstring, size: csize_t, format: cstring): cint {.importc: snprintfName, header: "<stdio.h>", varargs .}
+
+proc c_malloc(size: csize_t): pointer {.importc:"malloc", header: "<stdlib.h>".}
+proc c_free(p: pointer) {.importc:"free", header: "<stdlib.h>".}
+
+proc fun() =
+  block: # c_exp
+    var x = 0.3
+    let b = c_exp(x)
+    let b2 = int(b*1_000_000) # avoids floating point equality
+    doAssert b2 == 1349858
+    doAssert c_exp(0.3) == c_exp(x)
+    const x2 = 0.3
+    doAssert c_exp(x2) == c_exp(x)
+
+  block: # c_printf
+    c_printf("foo\n")
+    c_printf("foo:%d\n", 100)
+    c_printf("foo:%d\n", 101.cint)
+    c_printf("foo:%d:%d\n", 102.cint, 103.cint)
+    let temp = 104.cint
+    c_printf("foo:%d:%d:%d\n", 102.cint, 103.cint, temp)
+    var temp2 = 105.cint
+    c_printf("foo:%g:%s:%d:%d\n", 0.03, "asdf", 103.cint, temp2)
+
+  block: # c_snprintf, c_malloc, c_free
+    let n: uint = 50
+    var buffer2 = cstring(cast[ptr char](c_malloc(n)))
+
+    var s: cstring = "foobar"
+    var age: cint = 25
+    let num = c_snprintf(buffer2, n, "s1:%s s2:%s age:%d pi:%g", s, s, age, 3.14)
+    let numExp = 34 
+    doAssert num == numExp
+    c_printf("ret=[%s]\n", buffer2)
+    c_free(buffer2)
+
+  block: # c_printf bug
+    var a = 123
+    var a2 = a.addr
+    #[
+    bug: different behavior between CT RT in this case:
+    at CT, shows foo2:a=123
+    at RT, shows foo2:a=<address as int>
+    ]#
+    if false:
+      c_printf("foo2:a=%d\n", a2)
+
+
+static:
+  fun()
+fun()
+
+when not defined nimEvalffiStderrWorkaround:
+  import system/ansi_c
+  block:
+    proc fun2()=
+      c_fprintf(cstderr, "hello world stderr\n")
+      write(stderr, "hi stderr\n")
+    static: fun2()
+    fun2()
diff --git a/tests/vm/mscriptcompiletime.nim b/tests/vm/mscriptcompiletime.nim
new file mode 100644
index 000000000..ed7e7c029
--- /dev/null
+++ b/tests/vm/mscriptcompiletime.nim
@@ -0,0 +1,7 @@
+# bug.nim
+var bar* {.compileTime.} = 1
+
+proc dummy = discard
+
+static:
+  inc bar
\ No newline at end of file
diff --git a/tests/vm/t11637.nim b/tests/vm/t11637.nim
new file mode 100644
index 000000000..c061c6641
--- /dev/null
+++ b/tests/vm/t11637.nim
@@ -0,0 +1,52 @@
+type Foo = ref object
+  val: int
+
+proc `+`(a, b: Foo): Foo =
+  Foo(val: a.val + b.val)
+
+proc `*`(a: Foo, b: int): Foo =
+  Foo(val: a.val * b)
+
+proc `+=`(a: var Foo, b: Foo) =
+  a = Foo(
+    val: a.val + b.val
+  )
+
+proc foobar(a, b, c: Foo): tuple[bar, baz, buzz: Foo] =
+
+  let foo = a + b + c
+  result.bar = foo * 2
+
+  result.baz = foo * 3
+  result.buzz = result.baz
+
+  result.buzz += a * 10000
+  result.baz += b
+  result.buzz += b
+
+
+block: # Compile-Time
+  let
+    a {.compileTime.} = Foo(val: 1)
+    b {.compileTime.} = Foo(val: 2)
+    c {.compileTime.} = Foo(val: 3)
+    r {.compileTime.} = foobar(a, b, c)
+
+  static:
+    doAssert r.bar.val == 12
+    doAssert r.baz.val == 20
+    doAssert r.buzz.val == 10020
+
+####################################
+
+block: # Run-time
+  let
+    a = Foo(val: 1)
+    b = Foo(val: 2)
+    c = Foo(val: 3)
+    r = foobar(a, b, c)
+
+  # Expected values
+  doAssert r.bar.val == 12
+  doAssert r.baz.val == 20
+  doAssert r.buzz.val == 10020
diff --git a/tests/vm/t17039.nim b/tests/vm/t17039.nim
new file mode 100644
index 000000000..f92c93f30
--- /dev/null
+++ b/tests/vm/t17039.nim
@@ -0,0 +1,10 @@
+type
+  Obj1 = object
+    case kind: bool
+    of false:
+      field: seq[int]
+    else: discard
+
+static:
+  var obj1 = Obj1()
+  obj1.field.add(@[])
diff --git a/tests/vm/t17121.nim b/tests/vm/t17121.nim
new file mode 100644
index 000000000..bf2d6423f
--- /dev/null
+++ b/tests/vm/t17121.nim
@@ -0,0 +1,9 @@
+discard """
+  errormsg: "cannot 'importc' variable at compile time; c_printf"
+"""
+
+proc c_printf*(frmt: cstring): cint {.importc: "printf", header: "<stdio.h>", varargs, discardable.} =
+  ## foo bar
+  runnableExamples: discard
+static:
+  let a = c_printf("abc\n")
diff --git a/tests/vm/t18103.nim b/tests/vm/t18103.nim
new file mode 100644
index 000000000..8622ab290
--- /dev/null
+++ b/tests/vm/t18103.nim
@@ -0,0 +1,35 @@
+discard """
+  targets: "c cpp"
+  matrix: "--mm:refc; --mm:arc"
+"""
+
+import base64, complex, sequtils, math, sugar
+
+type
+
+  FP = float
+  T = object
+    index: int
+    arg: FP
+    val: Complex[FP]
+  M = object
+    alpha, beta: FP
+
+func a(s: openArray[T], model: M): seq[T] =
+  let f = (tn: int) => model.alpha + FP(tn) * model.beta;
+  return mapIt s:
+    block:
+      let s = it.val * rect(1.0, - f(it.index))
+      T(index: it.index, arg: phase(s), val: s)
+
+proc b(): float64 =
+  var s = toSeq(0..10).mapIt(T(index: it, arg: 1.0, val: complex.complex(1.0)))
+  discard a(s, M(alpha: 1, beta: 1))
+  return 1.0
+
+func cc(str: cstring, offset: ptr[cdouble]): cint {.exportc.} =
+  offset[] = b()
+  return 0
+
+static:
+  echo b()
diff --git a/tests/vm/t19075.nim b/tests/vm/t19075.nim
new file mode 100644
index 000000000..89ca9cb19
--- /dev/null
+++ b/tests/vm/t19075.nim
@@ -0,0 +1,19 @@
+discard """
+  timeout: 10
+  joinable: false
+"""
+
+# bug #19075
+const size = 50_000
+
+const stuff = block:
+    var a: array[size, int]
+    a
+
+const zeugs = block:
+    var zeugs: array[size, int]
+    for i in 0..<size:
+        zeugs[i] = stuff[i]
+    zeugs
+
+doAssert zeugs[0] == 0
\ No newline at end of file
diff --git a/tests/vm/t19199.nim b/tests/vm/t19199.nim
new file mode 100644
index 000000000..6ae48cb54
--- /dev/null
+++ b/tests/vm/t19199.nim
@@ -0,0 +1,6 @@
+# bug #19199
+proc mikasa(x: float) = doAssert x == 42
+
+static:
+  mikasa 42.uint.float
+mikasa 42.uint.float
diff --git a/tests/vm/t20746.nim b/tests/vm/t20746.nim
new file mode 100644
index 000000000..bfad269ef
--- /dev/null
+++ b/tests/vm/t20746.nim
@@ -0,0 +1,13 @@
+discard """
+  timeout: 10
+  joinable: false
+  output: "fine"
+"""
+
+func addString(): string =
+  let x = newString(1000000)
+  for i in 0..<1000000:
+    discard x[i]
+
+const translationTable = addString()
+echo "fine"
diff --git a/tests/vm/t21704.nim b/tests/vm/t21704.nim
new file mode 100644
index 000000000..27f4f5b06
--- /dev/null
+++ b/tests/vm/t21704.nim
@@ -0,0 +1,69 @@
+discard """
+matrix: "--hints:off"
+nimout: '''
+Found 2 tests to run.
+Found 3 benches to compile.
+ 
+  --passC:-Wno-stringop-overflow --passL:-Wno-stringop-overflow 
+ 
+  --passC:-Wno-stringop-overflow --passL:-Wno-stringop-overflow 
+ 
+  --passC:-Wno-stringop-overflow --passL:-Wno-stringop-overflow
+'''
+"""
+# bug #21704
+import std/strformat
+
+const testDesc: seq[string] = @[
+  "tests/t_hash_sha256_vs_openssl.nim",
+  "tests/t_cipher_chacha20.nim"
+]
+const benchDesc = [
+  "bench_sha256",
+  "bench_hash_to_curve",
+  "bench_ethereum_bls_signatures"
+]
+
+proc setupTestCommand(flags, path: string): string =
+  return "nim c -r " &
+    flags &
+    &" --nimcache:nimcache/{path} " & # Commenting this out also solves the issue
+    path
+
+proc testBatch(commands: var string, flags, path: string) =
+  commands &= setupTestCommand(flags, path) & '\n'
+
+proc setupBench(benchName: string): string =
+  var runFlags = if false: " -r "
+                 else: " " # taking this branch is needed to trigger the bug
+
+  echo runFlags # Somehow runflags isn't reset in corner cases
+  runFlags &= " --passC:-Wno-stringop-overflow --passL:-Wno-stringop-overflow "
+  echo runFlags
+
+  return "nim c " &
+       runFlags &
+       &" benchmarks/{benchName}.nim"
+
+proc buildBenchBatch(commands: var string, benchName: string) =
+  let command = setupBench(benchName)
+  commands &= command & '\n'
+
+proc addTestSet(cmdFile: var string) =
+  echo "Found " & $testDesc.len & " tests to run."
+
+  for path in testDesc:
+    var flags = "" # This is important
+    cmdFile.testBatch(flags, path)
+
+proc addBenchSet(cmdFile: var string) =
+  echo "Found " & $benchDesc.len & " benches to compile."
+  for bd in benchDesc:
+    cmdFile.buildBenchBatch(bd)
+
+proc task_bug() =
+  var cmdFile: string
+  cmdFile.addTestSet() # Comment this out and there is no bug
+  cmdFile.addBenchSet()
+
+static: task_bug()
diff --git a/tests/vm/t2574.nim b/tests/vm/t2574.nim
new file mode 100644
index 000000000..4332667b4
--- /dev/null
+++ b/tests/vm/t2574.nim
@@ -0,0 +1,14 @@
+discard """
+  errormsg: "cannot call method eval at compile time"
+  line: 14
+"""
+
+type
+  PExpr = ref object of RootObj
+
+method eval(e: PExpr): int =
+  discard
+
+static:
+  let x = PExpr()
+  discard x.eval
diff --git a/tests/vm/t9622.nim b/tests/vm/t9622.nim
new file mode 100644
index 000000000..fada8fe59
--- /dev/null
+++ b/tests/vm/t9622.nim
@@ -0,0 +1,30 @@
+discard """
+  targets: "c cpp"
+  matrix: "--mm:refc; --mm:arc"
+"""
+
+type
+  GlobNodeKind = enum
+    LiteralIdent,
+    Group
+
+  GlobNode = object
+    case kind: GlobNodeKind
+    of LiteralIdent:
+      value: string
+    of Group:
+      values: seq[string]
+
+  PathSegment = object
+    children: seq[GlobNode]
+
+  GlobPattern = seq[PathSegment]
+
+proc parseImpl(): GlobPattern =
+  if result.len == 0:
+    result.add PathSegment()
+  result[^1].children.add GlobNode(kind: LiteralIdent)
+
+block:
+  const pattern = parseImpl()
+  doAssert $pattern == """@[(children: @[(kind: LiteralIdent, value: "")])]"""
diff --git a/tests/vm/tableinstatic.nim b/tests/vm/tableinstatic.nim
index b0d24b477..934c3a8dd 100644
--- a/tests/vm/tableinstatic.nim
+++ b/tests/vm/tableinstatic.nim
@@ -2,7 +2,7 @@ discard """
   nimout: '''0
 0
 0
-{"hallo": "123", "welt": "456"}'''
+'''
 """
 
 import tables
@@ -35,4 +35,4 @@ static:
   otherTable["hallo"] = "123"
   otherTable["welt"]  = "456"
 
-  echo otherTable
+  doAssert otherTable == {"hallo": "123", "welt": "456"}.newTable
diff --git a/tests/vm/taddrof.nim b/tests/vm/taddrof.nim
new file mode 100644
index 000000000..bbe9345d2
--- /dev/null
+++ b/tests/vm/taddrof.nim
@@ -0,0 +1,110 @@
+discard """
+nimout: '''
+true
+true
+[nil, nil, nil, nil]
+[MyObjectRef(123, 321), nil, nil, nil]
+['A', '\x00', '\x00', '\x00']
+MyObjectRef(123, 321)
+(key: 8, val: 0)
+'''
+output: '''
+true
+true
+[nil, nil, nil, nil]
+[MyObjectRef(123, 321), nil, nil, nil]
+['A', '\x00', '\x00', '\x00']
+MyObjectRef(123, 321)
+'''
+"""
+
+type
+  MyObjectRef = ref object
+    a,b: int
+
+  MyContainerObject = ref object
+    member: MyObjectRef
+
+  MySuperContainerObject = ref object
+    member: MyContainerObject
+    arr: array[4, MyObjectRef]
+
+  MyOtherObject = ref object
+    case kind: bool
+    of true:
+      member: MyObjectRef
+    else:
+      discard
+
+proc `$`(arg: MyObjectRef): string =
+  result = "MyObjectRef("
+  result.addInt arg.a
+  result.add ", "
+  result.addInt arg.b
+  result.add ")"
+
+proc foobar(dst: var MyObjectRef) =
+  dst = new(MyObjectRef)
+  dst.a = 123
+  dst.b = 321
+
+proc changeChar(c: var char) =
+  c = 'A'
+
+proc test() =
+  # when it comes from a var, it works
+  var y: MyObjectRef
+  foobar(y)
+  echo y != nil
+  # when it comes from a member, it fails on VM
+  var x = new(MyContainerObject)
+  foobar(x.member)
+  echo x.member != nil
+
+  # when it comes from an array, it fails on VM
+  var arr: array[4, MyObjectRef]
+  echo arr
+  foobar(arr[0])
+  echo arr
+
+  var arr2: array[4, char]
+  changeChar(arr2[0])
+  echo arr2
+
+
+  var z = MyOtherObject(kind: true)
+  foobar(z.member)
+  echo z.member
+
+  # this still doesn't work
+  # var sc = new(MySuperContainerObject)
+  # sc.member = new(MyContainerObject)
+  # foobar(sc.member.member)
+  # echo sc.member.member
+  # foobar(sc.arr[1])
+  # echo sc.arr
+
+  #var str = "---"
+  #changeChar(str[1])
+  #echo str
+
+test()
+static:
+  test()
+
+type T = object
+  f: seq[tuple[key, val: int]]
+
+proc foo(s: var seq[tuple[key, val: int]]; i: int) =
+  s[i].key = 4*i
+  # r4 = addr(s[i])
+  # r4[0] = 4*i
+
+proc bar() =
+  var s: T
+  s.f = newSeq[tuple[key, val: int]](3)
+  foo(s.f, 2)
+  echo s.f[2]
+
+static:
+  bar()
diff --git a/tests/vm/tanonproc.nim b/tests/vm/tanonproc.nim
index c5cb57d75..1176c104e 100644
--- a/tests/vm/tanonproc.nim
+++ b/tests/vm/tanonproc.nim
@@ -4,7 +4,7 @@ discard """
 
 # bug #3561
 
-import macros, future, strutils
+import macros, sugar, strutils
 
 type
   Option[T] = ref object
@@ -42,7 +42,7 @@ proc getOrElse[T](o: Option[T], def: T): T =
 proc quoteStr(s: string): Option[string] =
   s.some.notEmpty.map(v => "`" & v & "`")
 
-macro str(s: string): typed =
+macro str(s: string): void =
   let x = s.strVal
   let y = quoteStr(x)
   let sn = newStrLitNode(y.getOrElse("NONE"))
diff --git a/tests/vm/tbitops.nim b/tests/vm/tbitops.nim
new file mode 100644
index 000000000..90d463ec9
--- /dev/null
+++ b/tests/vm/tbitops.nim
@@ -0,0 +1,45 @@
+discard """
+output: ""
+"""
+
+import strutils
+
+const x  = [1'i32, -1, -10, 10, -10, 10, -20, 30, -40, 50, 7 shl 28, -(7 shl 28), 7 shl 28, -(7 shl 28)]
+const y  = [-1'i32, 1, -10, -10, 10, 10, -20, -30, 40, 50, 1 shl 30, 1 shl 30, -(1 shl 30), -(1 shl 30)]
+
+const res_xor = block:
+  var tmp: seq[int64]
+  for i in 0 ..< x.len:
+    tmp.add(int64(x[i] xor y[i]))
+  tmp
+
+const res_and = block:
+  var tmp: seq[int64]
+  for i in 0 ..< x.len:
+    tmp.add(int64(x[i] and y[i]))
+  tmp
+
+const res_or = block:
+  var tmp: seq[int64]
+  for i in 0 ..< x.len:
+    tmp.add(int64(x[i] or y[i]))
+  tmp
+
+const res_not = block:
+  var tmp: seq[int64]
+  for i in 0 ..< x.len:
+    tmp.add(not x[i])
+  tmp
+
+let xx = x
+let yy = y
+
+for i in 0..<xx.len:
+  let z_xor = int64(xx[i] xor yy[i])
+  let z_and = int64(xx[i] and yy[i])
+  let z_or = int64(xx[i] or yy[i])
+  let z_not = int64(not xx[i])
+  doAssert(z_xor == res_xor[i], $i & ": " & $res_xor[i] & "  " & $z_xor)
+  doAssert(z_and == res_and[i], $i & ": " & $res_and[i] & "  " & $z_and)
+  doAssert(z_or == res_or[i], $i & ": " & $res_or[i] & "  " & $z_or)
+  doAssert(z_not == res_not[i], $i & ": " & $res_not[i] & "  " & $z_not)
diff --git a/tests/vm/tcastint.nim b/tests/vm/tcastint.nim
index 7b9ddd7d9..c306e4a31 100644
--- a/tests/vm/tcastint.nim
+++ b/tests/vm/tcastint.nim
@@ -1,8 +1,5 @@
-discard """
-  file: "tcastint.nim"
-  output: "OK"
-"""
-
+import macros
+from stdtest/testutils import disableVM
 type
   Dollar = distinct int
   XCoord = distinct int32
@@ -14,6 +11,12 @@ proc `==`(x, y: XCoord): bool {.borrow.}
 
 proc dummy[T](x: T): T = x
 
+template roundTrip(a, T) =
+  let a2 = a # sideeffect safe
+  let b = cast[T](a2)
+  let c = cast[type(a2)](b)
+  doAssert c == a2
+
 proc test() =
   let U8 = 0b1011_0010'u8
   let I8 = 0b1011_0010'i8
@@ -101,20 +104,206 @@ proc test() =
     doAssert(cast[int](digit) == raw)
     doAssert(cast[Digit](raw) == digit)
 
-  when defined nimvm:
-    doAssert(not compiles(cast[float](I64A)))
-    doAssert(not compiles(cast[float32](I64A)))
+  block:
+    roundTrip(I64A, float)
+    roundTrip(I8, uint16)
+    roundTrip(I8, uint32)
+    roundTrip(I8, uint64)
+    doAssert cast[uint16](I8) == 65458'u16
+    doAssert cast[uint32](I8) == 4294967218'u32
+    doAssert cast[uint64](I8) == 18446744073709551538'u64
+    doAssert cast[uint32](I64A) == 2571663889'u32
+    doAssert cast[uint16](I64A) == 31249
+    doAssert cast[char](I64A).ord == 17
+    doAssert compiles(cast[float32](I64A))
+
+  disableVM: # xxx Error: VM does not support 'cast' from tyInt64 to tyFloat32
+    doAssert cast[uint32](cast[float32](I64A)) == 2571663889'u32
+
+const prerecordedResults = [
+  # cast to char
+  "\0", "\255",
+  "\0", "\255",
+  "\0", "\255",
+  "\0", "\255",
+  "\0", "\255",
+  "\128", "\127",
+  "\0", "\255",
+  "\0", "\255",
+  "\0", "\255",
+  # cast to uint8
+  "0", "255",
+  "0", "255",
+  "0", "255",
+  "0", "255",
+  "0", "255",
+  "128", "127",
+  "0", "255",
+  "0", "255",
+  "0", "255",
+  # cast to uint16
+  "0", "255",
+  "0", "255",
+  "0", "65535",
+  "0", "65535",
+  "0", "65535",
+  "65408", "127",
+  "32768", "32767",
+  "0", "65535",
+  "0", "65535",
+  # cast to uint32
+  "0", "255",
+  "0", "255",
+  "0", "65535",
+  "0", "4294967295",
+  "0", "4294967295",
+  "4294967168", "127",
+  "4294934528", "32767",
+  "2147483648", "2147483647",
+  "0", "4294967295",
+  # cast to uint64
+  "0", "255",
+  "0", "255",
+  "0", "65535",
+  "0", "4294967295",
+  "0", "18446744073709551615",
+  "18446744073709551488", "127",
+  "18446744073709518848", "32767",
+  "18446744071562067968", "2147483647",
+  "9223372036854775808", "9223372036854775807",
+  # cast to int8
+  "0", "-1",
+  "0", "-1",
+  "0", "-1",
+  "0", "-1",
+  "0", "-1",
+  "-128", "127",
+  "0", "-1",
+  "0", "-1",
+  "0", "-1",
+  # cast to int16
+  "0", "255",
+  "0", "255",
+  "0", "-1",
+  "0", "-1",
+  "0", "-1",
+  "-128", "127",
+  "-32768", "32767",
+  "0", "-1",
+  "0", "-1",
+  # cast to int32
+  "0", "255",
+  "0", "255",
+  "0", "65535",
+  "0", "-1",
+  "0", "-1",
+  "-128", "127",
+  "-32768", "32767",
+  "-2147483648", "2147483647",
+  "0", "-1",
+  # cast to int64
+  "0", "255",
+  "0", "255",
+  "0", "65535",
+  "0", "4294967295",
+  "0", "-1",
+  "-128", "127",
+  "-32768", "32767",
+  "-2147483648", "2147483647",
+  "-9223372036854775808", "9223372036854775807",
+]
+
+proc free_integer_casting() =
+  # cast from every integer type to every type and ensure same
+  # behavior in vm and execution time.
+  macro bar(arg: untyped) =
+    result = newStmtList()
+    var i = 0
+    for it1 in arg:
+      let typA = it1[0]
+      for it2 in arg:
+        let lowB = it2[1]
+        let highB = it2[2]
+        let castExpr1 = nnkCast.newTree(typA, lowB)
+        let castExpr2 = nnkCast.newTree(typA, highB)
+        let lit1 = newLit(prerecordedResults[i*2])
+        let lit2 = newLit(prerecordedResults[i*2+1])
+        result.add quote do:
+          doAssert($(`castExpr1`) == `lit1`)
+          doAssert($(`castExpr2`) == `lit2`)
+        i += 1
+
+  bar([
+    (char, '\0', '\255'),
+    (uint8, 0'u8, 0xff'u8),
+    (uint16, 0'u16, 0xffff'u16),
+    (uint32, 0'u32, 0xffffffff'u32),
+    (uint64, 0'u64, 0xffffffffffffffff'u64),
+    (int8,  0x80'i8, 0x7f'i8),
+    (int16, 0x8000'i16, 0x7fff'i16),
+    (int32, 0x80000000'i32, 0x7fffffff'i32),
+    (int64, 0x8000000000000000'i64, 0x7fffffffffffffff'i64)
+  ])
+
+proc test_float_cast =
+
+  const
+    exp_bias = 1023'i64
+    exp_shift = 52
+    exp_mask = 0x7ff'i64 shl exp_shift
+    mantissa_mask = 0xfffffffffffff'i64
+
+  let f = 8.0
+  let fx = cast[int64](f)
+  let exponent = ((fx and exp_mask) shr exp_shift) - exp_bias
+  let mantissa = fx and mantissa_mask
+  doAssert(exponent == 3, $exponent)
+  doAssert(mantissa == 0, $mantissa)
+
+  # construct 2^N float, where N is integer
+  let x = -2'i64
+  let xx = (x + exp_bias) shl exp_shift
+  let xf = cast[float](xx)
+  doAssert(xf == 0.25, $xf)
+
+proc test_float32_cast =
+
+  const
+    exp_bias = 127'i32
+    exp_shift = 23
+    exp_mask = 0x7f800000'i32
+    mantissa_mask = 0x007ffff'i32
+
+  let f = -0.5'f32
+  let fx = cast[int32](f)
+  let exponent = ((fx and exp_mask) shr exp_shift) - exp_bias
+  let mantissa = fx and mantissa_mask
+  doAssert(exponent == -1, $exponent)
+  doAssert(mantissa == 0, $mantissa)
 
-    doAssert(not compiles(cast[char](I64A)))
-    doAssert(not compiles(cast[uint16](I64A)))
-    doAssert(not compiles(cast[uint32](I64A)))
+  # construct 2^N float32 where N is integer
+  let x = 4'i32
+  let xx = (x + exp_bias) shl exp_shift
+  let xf = cast[float32](xx)
+  doAssert(xf == 16.0'f32, $xf)
 
-    doAssert(not compiles(cast[uint16](I8)))
-    doAssert(not compiles(cast[uint32](I8)))
-    doAssert(not compiles(cast[uint64](I8)))
+proc test_float32_castB() =
+  let a: float32 = -123.125
+  let b = cast[int32](a)
+  let c = cast[uint32](a)
+  doAssert b == -1024049152
+  doAssert cast[uint64](b) == 18446744072685502464'u64
+  doAssert c == 3270918144'u32
+  # ensure the unused bits in the internal representation don't have
+  # any surprising content.
+  doAssert cast[uint64](c) == 3270918144'u64
 
-test()
-static:
+template main() =
   test()
+  test_float_cast()
+  test_float32_cast()
+  free_integer_casting()
+  test_float32_castB()
 
-echo "OK"
+static: main()
+main()
diff --git a/tests/vm/tcgemptycallarg.nim b/tests/vm/tcgemptycallarg.nim
new file mode 100644
index 000000000..1bedb5070
--- /dev/null
+++ b/tests/vm/tcgemptycallarg.nim
@@ -0,0 +1,3 @@
+static:
+  doAssertRaises(ValueError):
+    raise newException(ValueError, "Yes")
diff --git a/tests/vm/tclosureiterator.nim b/tests/vm/tclosureiterator.nim
new file mode 100644
index 000000000..c909392d5
--- /dev/null
+++ b/tests/vm/tclosureiterator.nim
@@ -0,0 +1,9 @@
+discard """
+  errormsg: "Closure iterators are not supported by VM!"
+"""
+
+iterator iter*(): int {.closure.} =
+  yield 3
+
+static:
+  var x = iter
diff --git a/tests/vm/tcnstseq.nim b/tests/vm/tcnstseq.nim
new file mode 100644
index 000000000..5679a6e37
--- /dev/null
+++ b/tests/vm/tcnstseq.nim
@@ -0,0 +1,68 @@
+discard """
+output: '''
+AngelikaAnneAnnaAnkaAnja
+AngelikaAnneAnnaAnkaAnja
+AngelikaAnneAnnaAnkaAnja
+onetwothree
+onetwothree
+onetwothree
+one1two2three3
+'''
+"""
+# Test the new implicit conversion from sequences to arrays in a constant
+# context.
+
+import strutils
+
+
+block t1:
+  const
+    myWords = "Angelika Anne Anna Anka Anja".split()
+
+  for x in items(myWords):
+    write(stdout, x) #OUT AngelikaAnneAnnaAnkaAnja
+  echo ""
+
+
+block t2:
+  const
+    myWords = @["Angelika", "Anne", "Anna", "Anka", "Anja"]
+
+  for i in 0 .. high(myWords):
+    write(stdout, myWords[i]) #OUT AngelikaAnneAnnaAnkaAnja
+  echo ""
+
+
+block t3:
+  for w in items(["Angelika", "Anne", "Anna", "Anka", "Anja"]):
+    write(stdout, w) #OUT AngelikaAnneAnnaAnkaAnja
+  echo ""
+
+
+block t2656:
+  iterator it1(args: seq[string]): string =
+    for s in args: yield s
+  iterator it2(args: seq[string]): string {.closure.} =
+    for s in args: yield s
+  iterator it3(args: openArray[string]): string {.closure.} =
+    for s in args: yield s
+  iterator it4(args: openArray[(string, string)]): string {.closure.} =
+    for s1, s2 in items(args): yield s1 & s2
+
+  block:
+    const myConstSeq = @["one", "two", "three"]
+    for s in it1(myConstSeq):
+      stdout.write s
+    echo ""
+    for s in it2(myConstSeq):
+      stdout.write s
+    echo ""
+    for s in it3(myConstSeq):
+      stdout.write s
+    echo ""
+
+  block:
+    const myConstSeq = @[("one", "1"), ("two", "2"), ("three", "3")]
+    for s in it4(myConstSeq):
+      stdout.write s
+    echo ""
diff --git a/tests/vm/tcompilesetting.nim b/tests/vm/tcompilesetting.nim
new file mode 100644
index 000000000..d6c08e70f
--- /dev/null
+++ b/tests/vm/tcompilesetting.nim
@@ -0,0 +1,18 @@
+discard """
+cmd: "nim c --nimcache:build/myNimCache --nimblePath:myNimblePath --gc:arc $file"
+joinable: false
+"""
+
+import std/[strutils,compilesettings]
+from std/os import fileExists, `/`
+
+template main =
+  doAssert querySetting(nimcacheDir) == nimcacheDir.querySetting
+  doAssert "myNimCache" in nimcacheDir.querySetting
+  doAssert "myNimblePath" in nimblePaths.querySettingSeq[0]
+  doAssert querySetting(backend) == "c"
+  doAssert fileExists(libPath.querySetting / "system.nim")
+  doAssert querySetting(mm) == "arc"
+
+static: main()
+main()
diff --git a/tests/vm/tcompiletimerange.nim b/tests/vm/tcompiletimerange.nim
new file mode 100644
index 000000000..cd675b4a3
--- /dev/null
+++ b/tests/vm/tcompiletimerange.nim
@@ -0,0 +1,28 @@
+discard """
+"""
+
+# issue #8199
+
+const rangesGCHoldEnabled = true # not defined(rangesDisableGCHold)
+
+type
+  # A view into immutable array
+  Range*[T] {.shallow.} = object
+    when rangesGCHoldEnabled:
+      gcHold: seq[T] # 0
+    start: ptr T # 1
+    mLen: int32 # 2
+
+type
+  BytesRange* = Range[byte]
+  NibblesRange* = object
+    bytes: BytesRange
+
+const
+  zeroBytesRange* = BytesRange()
+
+proc initNibbleRange*(bytes: BytesRange): NibblesRange =
+  result.bytes = bytes
+
+const
+  zeroNibblesRange* = initNibbleRange(zeroBytesRange)
diff --git a/tests/vm/tcompiletimesideeffects.nim b/tests/vm/tcompiletimesideeffects.nim
new file mode 100644
index 000000000..4cd57b3bd
--- /dev/null
+++ b/tests/vm/tcompiletimesideeffects.nim
@@ -0,0 +1,42 @@
+discard """
+  output:
+'''
+@[0, 1, 2]
+@[3, 4, 5]
+@[0, 1, 2]
+3
+4
+'''
+"""
+
+template runNTimes(n: int, f : untyped) : untyped =
+  var accum: seq[type(f)]
+  for i in 0..n-1:
+    accum.add(f)
+  accum
+
+var state {.compileTime.} : int = 0
+proc fill(): int {.compileTime.} =
+  result = state
+  inc state
+
+# invoke fill() at compile time as a compile time expression
+const C1 = runNTimes(3, fill())
+echo C1
+
+# invoke fill() at compile time as a set of compile time statements
+const C2 =
+  block:
+    runNTimes(3, fill())
+echo C2
+
+# invoke fill() at compile time after a compile time reset of state
+const C3 =
+  block:
+    state = 0
+    runNTimes(3, fill())
+echo C3
+
+# evaluate fill() at compile time and use the results at runtime
+echo fill()
+echo fill()
diff --git a/tests/vm/tcompiletimetable.nim b/tests/vm/tcompiletimetable.nim
index e78c06536..1db490f1a 100644
--- a/tests/vm/tcompiletimetable.nim
+++ b/tests/vm/tcompiletimetable.nim
@@ -1,9 +1,16 @@
 discard """
-  nimout: '''2
+  nimout: '''
+2
 3
 4:2
 Got Hi
-Got Hey'''
+Got Hey
+'''
+  output:'''
+a
+b
+c
+'''
 """
 
 # bug #404
@@ -47,3 +54,9 @@ addStuff("Hey"): echo "Hey"
 addStuff("Hi"): echo "Hi"
 dump()
 
+# ensure .compileTime vars can be used at runtime:
+import macros
+
+var xzzzz {.compileTime.}: array[3, string] = ["a", "b", "c"]
+
+for i in 0..high(xzzzz): echo xzzzz[i]
diff --git a/tests/vm/tcomponent.nim b/tests/vm/tcomponent.nim
index e7962e7ab..b509bc5d7 100644
--- a/tests/vm/tcomponent.nim
+++ b/tests/vm/tcomponent.nim
@@ -11,7 +11,7 @@ FOO: blah'''
 
 import macros, sequtils, tables
 import strutils
-import future, meta
+import sugar, meta
 
 type
   Component = object
diff --git a/tests/vm/tconst.nim b/tests/vm/tconst.nim
new file mode 100644
index 000000000..5cfe7533e
--- /dev/null
+++ b/tests/vm/tconst.nim
@@ -0,0 +1,58 @@
+discard """
+  targets: "c cpp js"
+"""
+
+import std/strutils
+
+template forceConst(a: untyped): untyped =
+  ## Force evaluation at CT, but `static(a)` is simpler
+  const ret = a
+  ret
+
+proc isNimVm(): bool =
+  when nimvm: result = true
+  else: result = false
+
+block:
+  doAssert forceConst(isNimVm())
+  doAssert not isNimVm()
+  doAssert forceConst(isNimVm()) == static(isNimVm())
+  doAssert forceConst(isNimVm()) == isNimVm().static
+
+template main() =
+  # xxx merge more const related tests here
+  const ct = CompileTime
+    # refs https://github.com/timotheecour/Nim/issues/718, apparently `CompileTime`
+    # isn't cached, which seems surprising.
+  block:
+    const
+      a = """
+    Version $1|
+    Compiled at: $2, $3
+    """ % [NimVersion & spaces(44-len(NimVersion)), CompileDate, ct]
+    let b = $a
+    doAssert ct in b, $(b, ct)
+    doAssert NimVersion in b
+
+  block: # Test for fix on broken const unpacking
+    template mytemp() =
+      const
+        (x, increment) = (4, true)
+        a = 100
+      discard (x, increment, a)
+    mytemp()
+
+  block: # bug #12334
+    block:
+      const b: cstring = "foo"
+      var c = b
+      doAssert c == "foo"
+    block:
+      const a = "foo"
+      const b: cstring = a
+      var c = b
+      doAssert c == "foo"
+
+
+static: main()
+main()
diff --git a/tests/vm/tconstarrayresem.nim b/tests/vm/tconstarrayresem.nim
new file mode 100644
index 000000000..6701cfe4d
--- /dev/null
+++ b/tests/vm/tconstarrayresem.nim
@@ -0,0 +1,29 @@
+# issue #23010
+
+type
+  Result[T, E] = object
+    case oResult: bool
+    of false:
+      discard
+    of true:
+      vResult: T
+
+  Opt[T] = Result[T, void]
+
+template ok[T, E](R: type Result[T, E], x: untyped): R =
+  R(oResult: true, vResult: x)
+
+template c[T](v: T): Opt[T] = Opt[T].ok(v)
+
+type
+  FixedBytes[N: static[int]] = distinct array[N, byte]
+
+  H = object
+    d: FixedBytes[2]
+
+const b = default(H)
+template g(): untyped =
+  const t = default(H)
+  b
+
+discard c(g())
diff --git a/tests/vm/tconsteval.nim b/tests/vm/tconsteval.nim
deleted file mode 100644
index f4260495a..000000000
--- a/tests/vm/tconsteval.nim
+++ /dev/null
@@ -1,31 +0,0 @@
-discard """
-"""
-
-import strutils
-
-const
-  HelpText = """
-+-----------------------------------------------------------------+
-|         Maintenance program for Nim                             |
-|             Version $1|
-|             (c) 2012 Andreas Rumpf                              |
-+-----------------------------------------------------------------+
-Compiled at: $2, $3
-
-Usage:
-  koch [options] command [options for command]
-Options:
-  --force, -f, -B, -b      forces rebuild
-  --help, -h               shows this help and quits
-Possible Commands:
-  boot [options]           bootstraps with given command line options
-  clean                    cleans Nim project; removes generated files
-  web                      generates the website
-  csource [options]        builds the C sources for installation
-  zip                      builds the installation ZIP package
-  inno                     builds the Inno Setup installer
-""" % [NimVersion & spaces(44-len(NimVersion)),
-       CompileDate, CompileTime]
-
-echo HelpText
-
diff --git a/tests/vm/tconstobj.nim b/tests/vm/tconstobj.nim
index 38fcdd844..7dc20a0ba 100644
--- a/tests/vm/tconstobj.nim
+++ b/tests/vm/tconstobj.nim
@@ -1,10 +1,13 @@
 discard """
-  output: '''(name: "hello")
-(-1, 0)'''
+  output: '''
+(name: "hello")
+(-1, 0)
+(FirstName: "James", LastName: "Franco")
+[1, 2, 3]
+'''
 """
 
 # bug #2774, bug #3195
-
 type Foo = object
   name: string
 
@@ -14,7 +17,6 @@ const fooArray = [
 
 echo fooArray[0]
 
-
 type
     Position = object
         x, y: int
@@ -34,3 +36,60 @@ const
      ]
 
 echo offset[1]
+
+# bug #1547
+import tables
+
+type Person* = object
+    FirstName*: string
+    LastName*: string
+
+let people = {
+    "001": Person(FirstName: "James", LastName: "Franco")
+}.toTable()
+
+echo people["001"]
+
+# Object downconversion should not copy
+
+type
+  SomeBaseObj  {.inheritable.} = object of RootObj
+    txt : string
+  InheritedFromBase = object of SomeBaseObj
+    other : string
+
+proc initBase(sbo: var SomeBaseObj) =
+  sbo.txt = "Initialized string from base"
+
+static:
+  var ifb2: InheritedFromBase
+  initBase(SomeBaseObj(ifb2))
+  echo repr(ifb2)
+  doAssert(ifb2.txt == "Initialized string from base")
+
+static: # issue #11861
+  var ifb2: InheritedFromBase
+  initBase(ifb2)
+  doAssert(ifb2.txt == "Initialized string from base")
+
+
+static: # issue #15662
+  proc a(T: typedesc) = echo T.type
+  a((int, int))
+
+# bug #16069
+type
+  E = enum
+    val1, val2
+  Obj = object
+    case k: E
+    of val1:
+      x: array[3, int]
+    of val2:
+      y: uint32
+
+const
+  foo = [1, 2, 3]
+  arr = Obj(k: val1, x: foo)
+
+echo arr.x
diff --git a/tests/vm/tconstprocassignments.nim b/tests/vm/tconstprocassignments.nim
new file mode 100644
index 000000000..0e2d2ed16
--- /dev/null
+++ b/tests/vm/tconstprocassignments.nim
@@ -0,0 +1,18 @@
+discard """
+  output: '''
+100
+100
+'''
+"""
+
+proc f():int {.compileTime.} = 100
+
+const F = f
+echo F()
+
+const G = proc ():int =
+  let x = f
+  let y = x
+  y()
+
+echo G()
diff --git a/tests/vm/tconstresem.nim b/tests/vm/tconstresem.nim
new file mode 100644
index 000000000..4526cb891
--- /dev/null
+++ b/tests/vm/tconstresem.nim
@@ -0,0 +1,10 @@
+block: # issue #19849
+  type
+    Vec2[T] = object
+      x, y: T
+    Vec2i = Vec2[int]
+  template getX(p: Vec2i): int = p.x
+  let x = getX:
+    const t = Vec2i(x: 1, y: 2)
+    t
+  doAssert x == 1
diff --git a/tests/vm/tconstscope1.nim b/tests/vm/tconstscope1.nim
new file mode 100644
index 000000000..41c45a28f
--- /dev/null
+++ b/tests/vm/tconstscope1.nim
@@ -0,0 +1,5 @@
+# issue #5395
+
+const a = (var b = 3; b)
+echo b #[tt.Error
+     ^ undeclared identifier: 'b']#
diff --git a/tests/vm/tconstscope2.nim b/tests/vm/tconstscope2.nim
new file mode 100644
index 000000000..d858e96c2
--- /dev/null
+++ b/tests/vm/tconstscope2.nim
@@ -0,0 +1,5 @@
+const
+  a = (var x = 3; x)
+  # should we allow this?
+  b = x #[tt.Error
+      ^ undeclared identifier: 'x']#
diff --git a/tests/vm/tconsttable.nim b/tests/vm/tconsttable.nim
index 64a74a59d..152a33cba 100644
--- a/tests/vm/tconsttable.nim
+++ b/tests/vm/tconsttable.nim
@@ -17,3 +17,18 @@ x = "ah"
 echo foo[x]
 x = "possible."
 echo foo[x]
+
+block: # bug #19840
+  const testBytes = [byte 0xD8, 0x08, 0xDF, 0x45, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x61]
+  var tempStr = "__________________"
+
+  tempStr.prepareMutation
+  copyMem(addr tempStr[0], addr testBytes[0], testBytes.len)
+
+block: # bug #22389
+  func foo(): ptr UncheckedArray[byte] =
+    const bar = [77.byte]
+    cast[ptr UncheckedArray[byte]](addr bar[0])
+
+  doAssert foo()[0] == 77
+
diff --git a/tests/vm/tconsttable2.nim b/tests/vm/tconsttable2.nim
index e07734eb5..5a392fb66 100644
--- a/tests/vm/tconsttable2.nim
+++ b/tests/vm/tconsttable2.nim
@@ -1,5 +1,5 @@
 discard """
-  msg: '''61'''
+  nimout: '''61'''
 """
 
 # bug #2297
diff --git a/tests/vm/tconvaddr.nim b/tests/vm/tconvaddr.nim
new file mode 100644
index 000000000..9762a9e59
--- /dev/null
+++ b/tests/vm/tconvaddr.nim
@@ -0,0 +1,49 @@
+block: # issue #24097
+  type Foo = distinct int
+  proc foo(x: var Foo) =
+    int(x) += 1
+  proc bar(x: var int) =
+    x += 1
+  static:
+    var x = Foo(1)
+    int(x) = int(x) + 1
+    doAssert x.int == 2
+    int(x) += 1
+    doAssert x.int == 3
+    foo(x)
+    doAssert x.int == 4
+    bar(int(x)) # need vmgen flags propagated for this
+    doAssert x.int == 5
+  type Bar = object
+    x: Foo
+  static:
+    var obj = Bar(x: Foo(1))
+    int(obj.x) = int(obj.x) + 1
+    doAssert obj.x.int == 2
+    int(obj.x) += 1
+    doAssert obj.x.int == 3
+    foo(obj.x)
+    doAssert obj.x.int == 4
+    bar(int(obj.x)) # need vmgen flags propagated for this
+    doAssert obj.x.int == 5
+  static:
+    var arr = @[Foo(1)]
+    int(arr[0]) = int(arr[0]) + 1
+    doAssert arr[0].int == 2
+    int(arr[0]) += 1
+    doAssert arr[0].int == 3
+    foo(arr[0])
+    doAssert arr[0].int == 4
+    bar(int(arr[0])) # need vmgen flags propagated for this
+    doAssert arr[0].int == 5
+  proc testResult(): Foo =
+    result = Foo(1)
+    int(result) = int(result) + 1
+    doAssert result.int == 2
+    int(result) += 1
+    doAssert result.int == 3
+    foo(result)
+    doAssert result.int == 4
+    bar(int(result)) # need vmgen flags propagated for this
+    doAssert result.int == 5
+  doAssert testResult().int == 5
diff --git a/tests/vm/teval1.nim b/tests/vm/teval1.nim
index 0eaa050da..0316ea238 100644
--- a/tests/vm/teval1.nim
+++ b/tests/vm/teval1.nim
@@ -1,3 +1,8 @@
+
+discard """
+nimout: "##"
+"""
+
 import macros
 
 proc testProc: string {.compileTime.} =
@@ -14,9 +19,24 @@ when true:
 const
   x = testProc()
 
-echo "##", x, "##"
+doAssert x == ""
 
 # bug #1310
 static:
-    var i, j: set[int8] = {}
-    var k = i + j
+  var i, j: set[int8] = {}
+  var k = i + j
+
+type
+  Obj = object
+    x: int
+
+converter toObj(x: int): Obj = Obj(x: x)
+
+# bug #10514
+block:
+  const
+    b: Obj = 42
+    bar = [b]
+
+  let i_runtime = 0
+  doAssert bar[i_runtime] == b
diff --git a/tests/vm/texception.nim b/tests/vm/texception.nim
new file mode 100644
index 000000000..65a781281
--- /dev/null
+++ b/tests/vm/texception.nim
@@ -0,0 +1,14 @@
+proc someFunc() =
+  try:
+    raise newException(ValueError, "message")
+  except ValueError as err:
+    doAssert err.name == "ValueError"
+    doAssert err.msg == "message"
+    raise
+
+static:
+  try:
+    someFunc()
+  except:
+    discard
+  
\ No newline at end of file
diff --git a/tests/vm/texcl.nim b/tests/vm/texcl.nim
index e23a423fe..41975f27b 100644
--- a/tests/vm/texcl.nim
+++ b/tests/vm/texcl.nim
@@ -18,7 +18,7 @@ proc initOpts(): set[nlOptions] =
 
 const cOpts = initOpts()
 
-macro nlo(): typed =
+macro nlo() =
   nlOpts.incl(nloNone)
   nlOpts.excl(nloDebug)
   result = newEmptyNode()
diff --git a/tests/vm/textensionmap.nim b/tests/vm/textensionmap.nim
index 5d4b25d01..7ada1880d 100644
--- a/tests/vm/textensionmap.nim
+++ b/tests/vm/textensionmap.nim
@@ -10,4 +10,4 @@ const EXTENSIONMAP = {
   "c": @["*.c", "*.h"],
 }.toTable()
 
-const EXTENSIONS = toSet(concat(toSeq(EXTENSIONMAP.values())))
+const EXTENSIONS = toHashSet(concat(toSeq(EXTENSIONMAP.values())))
diff --git a/tests/vm/tfarjump.nim b/tests/vm/tfarjump.nim
new file mode 100644
index 000000000..f5798b8d2
--- /dev/null
+++ b/tests/vm/tfarjump.nim
@@ -0,0 +1,14 @@
+# Test a VM relative jump with an offset larger then 32767 instructions.
+
+import macros
+
+static:
+  var a = 0
+  macro foo(): untyped =
+    let s = newStmtList()
+    for i in 1..6554:
+      s.add nnkCommand.newTree(ident("inc"), ident("a"))
+    quote do:
+      if true:
+        `s`
+  foo()
diff --git a/tests/vm/tfibconst.nim b/tests/vm/tfibconst.nim
new file mode 100644
index 000000000..cca6dd84f
--- /dev/null
+++ b/tests/vm/tfibconst.nim
@@ -0,0 +1,43 @@
+discard """
+  nimout: '''
+Fibonacci sequence: 0, 1, 1, 2, 3
+Sequence continues: 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610
+'''
+"""
+
+
+import strformat
+
+var fib_n {.compileTime.}: int
+var fib_prev {.compileTime.}: int
+var fib_prev_prev {.compileTime.}: int
+
+proc next_fib(): int {.compileTime.} =
+  let fib = if fib_n < 2:
+    fib_n
+  else:
+    fib_prev_prev + fib_prev
+  inc(fib_n)
+  fib_prev_prev = fib_prev
+  fib_prev = fib
+  fib
+
+const f0 = next_fib()
+const f1 = next_fib()
+const f2 = next_fib()
+const f3 = next_fib()
+const f4 = next_fib()
+
+static:
+  echo fmt"Fibonacci sequence: {f0}, {f1}, {f2}, {f3}, {f4}"
+
+const fib_continues = block:
+  var result = fmt"Sequence continues: "
+  for i in 0..10:
+    if i > 0:
+      add(result, ", ")
+    add(result, $next_fib())
+  result
+
+static:
+  echo fib_continues
\ No newline at end of file
diff --git a/tests/vm/tfile_rw.nim b/tests/vm/tfile_rw.nim
new file mode 100644
index 000000000..439886e49
--- /dev/null
+++ b/tests/vm/tfile_rw.nim
@@ -0,0 +1,22 @@
+# test file read write in vm
+
+import os, strutils
+
+const filename  = splitFile(currentSourcePath).dir / "tfile_rw.txt"
+
+const mytext = "line1\nline2\nline3"
+static:
+  writeFile(filename, mytext)
+const myfile_str = staticRead(filename)
+const myfile_str2 = readFile(filename)
+const myfile_str_seq = readLines(filename, 3)
+
+static:
+  doAssert myfile_str == mytext
+  doAssert myfile_str2 == mytext
+  doAssert myfile_str_seq[0] == "line1"
+  doAssert myfile_str_seq[1] == "line2"
+  doAssert myfile_str_seq.join("\n") == mytext
+
+
+removeFile(filename)
diff --git a/tests/vm/tforwardproc.nim b/tests/vm/tforwardproc.nim
index 727ac6641..bcd929f0e 100644
--- a/tests/vm/tforwardproc.nim
+++ b/tests/vm/tforwardproc.nim
@@ -14,4 +14,4 @@ proc initArray(): array[10, int] =
   for f in 0..<10:
     result[f] = 3
 
-when isMainModule: echo repr(someTable)
+when true: echo repr(someTable)
diff --git a/tests/vm/tgenericcompiletimeproc.nim b/tests/vm/tgenericcompiletimeproc.nim
new file mode 100644
index 000000000..08099ebbe
--- /dev/null
+++ b/tests/vm/tgenericcompiletimeproc.nim
@@ -0,0 +1,36 @@
+block: # issue #10753
+  proc foo(x: int): int {.compileTime.} = x
+  const a = foo(123)
+  doAssert foo(123) == a
+
+  proc bar[T](x: T): T {.compileTime.} = x
+  const b = bar(123)
+  doAssert bar(123) == b
+  const c = bar("abc")
+  doAssert bar("abc") == c
+
+block: # issue #22021
+  proc foo(x: static int): int {.compileTime.} = x + 1
+  doAssert foo(123) == 124
+
+block: # issue #19365
+  proc f[T](x: static T): T {.compileTime.} = x + x
+  doAssert f(123) == 246
+  doAssert f(1.0) == 2.0
+
+block:
+  # don't fold compile time procs in typeof
+  proc fail[T](x: T): T {.compileTime.} =
+    doAssert false
+    x
+  doAssert typeof(fail(123)) is typeof(123)
+  proc p(x: int): int = x
+
+  type Foo = typeof(p(fail(123)))
+
+block: # issue #24150, related regression
+  proc w(T: type): T {.compileTime.} = default(ptr T)[]
+  template y(v: auto): auto = typeof(v) is int
+  discard compiles(y(w int))
+  proc s(): int {.compileTime.} = discard
+  discard s()
diff --git a/tests/vm/tgloballetfrommacro.nim b/tests/vm/tgloballetfrommacro.nim
new file mode 100644
index 000000000..4be09b56e
--- /dev/null
+++ b/tests/vm/tgloballetfrommacro.nim
@@ -0,0 +1,13 @@
+discard """
+errormsg: "cannot evaluate at compile time: BUILTIN_NAMES"
+line: 11
+"""
+
+import sets
+
+let BUILTIN_NAMES = toHashSet(["int8", "int16", "int32", "int64"])
+
+macro test*(): bool =
+  echo "int64" notin BUILTIN_NAMES
+
+echo test()
diff --git a/tests/vm/tgorge.nim b/tests/vm/tgorge.nim
index 694754f41..1f77d2c95 100644
--- a/tests/vm/tgorge.nim
+++ b/tests/vm/tgorge.nim
@@ -1,8 +1,17 @@
+discard """
+disabled: "windows"
+"""
+
+# If your os is windows and this test fails for you locally, please
+# check what is going wrong.
+
 import os
 
 template getScriptDir(): string =
   parentDir(instantiationInfo(-1, true).filename)
 
+# See also simpler test in Nim/tests/vm/tvmops.nim for a simpler
+# cross platform way.
 block gorge:
   const
     execName = when defined(windows): "tgorge.bat" else: "./tgorge.sh"
diff --git a/tests/vm/tgorge.sh b/tests/vm/tgorge.sh
index ba47afeae..ba47afeae 100644..100755
--- a/tests/vm/tgorge.sh
+++ b/tests/vm/tgorge.sh
diff --git a/tests/vm/tgorgeex.sh b/tests/vm/tgorgeex.sh
index 36ba0a02f..36ba0a02f 100644..100755
--- a/tests/vm/tgorgeex.sh
+++ b/tests/vm/tgorgeex.sh
diff --git a/tests/vm/tinheritance.nim b/tests/vm/tinheritance.nim
index d465e22b9..2a98ed923 100644
--- a/tests/vm/tinheritance.nim
+++ b/tests/vm/tinheritance.nim
@@ -1,6 +1,7 @@
 discard """
-  msg: '''Hello fred , managed by sally
-Hello sally , managed by bob'''
+  nimout: '''Hello fred, managed by sally
+Hello sally, managed by bob
+0'''
 """
 # bug #3973
 
@@ -10,20 +11,84 @@ type
     ecCode2
 
   Person* = object of RootObj
-    name* : string
+    name*: string
     last_name*: string
 
   Employee* = object of Person
-    empl_code* : EmployeeCode
-    mgr_name* : string
+    empl_code*: EmployeeCode
+    mgr_name*: string
 
 proc test() =
   var
     empl1 = Employee(name: "fred", last_name: "smith", mgr_name: "sally", empl_code: ecCode1)
     empl2 = Employee(name: "sally", last_name: "jones", mgr_name: "bob", empl_code: ecCode2)
 
-  echo "Hello ", empl1.name, " , managed by ", empl1.mgr_name
-  echo "Hello ", empl2.name, " , managed by ", empl2.mgr_name
+  echo "Hello ", empl1.name, ", managed by ", empl1.mgr_name
+  echo "Hello ", empl2.name, ", managed by ", empl2.mgr_name
 
 static:
   test()
+
+#----------------------------------------------
+# Bugs #9701 and #9702
+type
+  MyKind = enum
+    kA, kB, kC
+
+  Base = ref object of RootObj
+    x: string
+
+  A = ref object of Base
+    a: string
+
+  B = ref object of Base
+    b: string
+
+  C = ref object of B
+    c: string
+
+template check_templ(n: Base, k: MyKind) =
+  if k == kA: doAssert(n of A) else: doAssert(not (n of A))
+  if k in {kB, kC}: doAssert(n of B) else: doAssert(not (n of B))
+  if k == kC: doAssert(n of C) else: doAssert(not (n of C))
+  doAssert(n of Base)
+
+proc check_proc(n: Base, k: MyKind) =
+  if k == kA: doAssert(n of A) else: doAssert(not (n of A))
+  if k in {kB, kC}: doAssert(n of B) else: doAssert(not (n of B))
+  if k == kC: doAssert(n of C) else: doAssert(not (n of C))
+  doAssert(n of Base)
+
+static:
+  let aa = new(A)
+  check_templ(aa, kA)
+  check_proc(aa, kA)
+  let bb = new(B)
+  check_templ(bb, kB)
+  check_proc(bb, kB)
+  let cc = new(C)
+  check_templ(cc, kC)
+  check_proc(cc, kC)
+
+let aa = new(A)
+check_templ(aa, kA)
+check_proc(aa, kA)
+let bb = new(B)
+check_templ(bb, kB)
+check_proc(bb, kB)
+let cc = new(C)
+check_templ(cc, kC)
+check_proc(cc, kC)
+
+type
+  BBar = object of RootObj
+    bbarField: set[char]
+    xbarField: string
+    d, e: int
+  FooBar = object of BBar
+    a: int
+    b: string
+
+static:
+  var fb: FooBar
+  echo fb.a
diff --git a/tests/vm/tissues.nim b/tests/vm/tissues.nim
new file mode 100644
index 000000000..f0ae6c296
--- /dev/null
+++ b/tests/vm/tissues.nim
@@ -0,0 +1,76 @@
+import macros
+
+block t9043: # bug #9043
+  proc foo[N: static[int]](dims: array[N, int]): string =
+    const N1 = N
+    const N2 = dims.len
+    const ret = $(N, dims.len, N1, N2)
+    static: doAssert ret == $(N, dims.len, N1, N2)
+    ret
+
+  doAssert foo([1, 2]) == "(2, 2, 2, 2)"
+
+block t4952:
+  proc doCheck(tree: NimNode) =
+    let res: tuple[n: NimNode] = (n: tree)
+    assert: tree.kind == res.n.kind
+    for sub in tree:
+      doCheck(sub)
+
+  macro id(body: untyped): untyped =
+    doCheck(body)
+
+  id(foo((i: int)))
+
+  static:
+    let tree = newTree(nnkExprColonExpr)
+    let t = (n: tree)
+    doAssert: t.n.kind == tree.kind
+
+
+# bug #19909
+type
+  SinglyLinkedList[T] = ref object
+  SinglyLinkedListObj[T] = ref object
+
+
+proc addMoved[T](a, b: var SinglyLinkedList[T]) =
+  if a.addr != b.addr: discard
+
+proc addMoved[T](a, b: var SinglyLinkedListObj[T]) =
+  if a.addr != b.addr: discard
+
+proc main =
+  var a: SinglyLinkedList[int]; new a
+  var b: SinglyLinkedList[int]; new b
+  a.addMoved b
+
+  var a0: SinglyLinkedListObj[int]
+  var b0: SinglyLinkedListObj[int]
+  a0.addMoved b0
+
+static: main()
+
+
+# bug #18641
+
+type A = object
+  ha1: int
+static:
+  var a = A()
+  var a2 = a.addr
+  a2.ha1 = 11
+  doAssert a2.ha1 == 11
+  a.ha1 = 12
+  doAssert a.ha1 == 12
+  doAssert a2.ha1 == 12 # ok
+static:
+  proc fn() =
+    var a = A()
+    var a2 = a.addr
+    a2.ha1 = 11
+    doAssert a2.ha1 == 11
+    a.ha1 = 12
+    doAssert a.ha1 == 12
+    doAssert a2.ha1 == 12 # fails
+  fn()
diff --git a/tests/vm/tmanyregs.nim b/tests/vm/tmanyregs.nim
new file mode 100644
index 000000000..711c69285
--- /dev/null
+++ b/tests/vm/tmanyregs.nim
@@ -0,0 +1,16 @@
+import macros
+
+# Generate a proc with more then 255 registers. Should not generate an error at
+# compile time
+
+static:
+  macro mkFoo() =
+    let ss = newStmtList()
+    for i in 1..256:
+      ss.add parseStmt "var x" & $i & " = " & $i
+      ss.add parseStmt "inc x" & $i
+    quote do:
+      proc foo() =
+        `ss`
+  mkFoo()
+  foo()
diff --git a/tests/vm/tmaxloopiterations.nim b/tests/vm/tmaxloopiterations.nim
new file mode 100644
index 000000000..c256df518
--- /dev/null
+++ b/tests/vm/tmaxloopiterations.nim
@@ -0,0 +1,15 @@
+discard """
+errormsg: "interpretation requires too many iterations; if you are sure this is not a bug in your code"
+"""
+
+# issue #9829
+
+macro foo(): untyped  =
+  let lines = ["123", "5423"]
+  var idx = 0
+  while idx < lines.len():
+    if lines[idx].len() < 1:
+      inc(idx)
+      continue
+
+foo()
diff --git a/tests/vm/tmisc_vm.nim b/tests/vm/tmisc_vm.nim
new file mode 100644
index 000000000..1ad830b5f
--- /dev/null
+++ b/tests/vm/tmisc_vm.nim
@@ -0,0 +1,459 @@
+discard """
+  targets: "c js"
+  output: '''
+[127, 127, 0, 255][127, 127, 0, 255]
+(data: 1)
+(2, 1)
+(2, 1)
+(2, 1)
+(f0: 5)
+'''
+
+  nimout: '''caught Exception
+main:begin
+main:end
+@[{0}]
+(width: 0, height: 0, path: "")
+@[(width: 0, height: 0, path: ""), (width: 0, height: 0, path: "")]
+Done!
+foo4
+foo4
+foo4
+(a: 0, b: 0)
+(a: 0, b: 0)
+(a: 0, b: 0)
+z1 m: (lo: 12)
+z2 a: (lo: 3)
+x1 a: (lo: 3)
+x2 a: (lo: 6)
+x3 a: (lo: 0)
+z3 a: (lo: 3)
+x1 a: (lo: 3)
+x2 a: (lo: 6)
+x3 a: (lo: 0)
+(2, 1)
+(2, 1)
+(2, 1)
+(f0: 5)
+'''
+"""
+import std/sets
+
+#bug #1009
+type
+  TAggRgba8* = array[4, byte]
+
+template R*(self: TAggRgba8): byte = self[0]
+template G*(self: TAggRgba8): byte = self[1]
+template B*(self: TAggRgba8): byte = self[2]
+template A*(self: TAggRgba8): byte = self[3]
+
+template `R=`*(self: TAggRgba8, val: byte) =
+  self[0] = val
+template `G=`*(self: TAggRgba8, val: byte) =
+  self[1] = val
+template `B=`*(self: TAggRgba8, val: byte) =
+  self[2] = val
+template `A=`*(self: TAggRgba8, val: byte) =
+  self[3] = val
+
+proc ABGR*(val: int | int64): TAggRgba8 =
+  var V = val
+  result.R = byte(V and 0xFF)
+  V = V shr 8
+  result.G = byte(V and 0xFF)
+  V = V shr 8
+  result.B = byte(V and 0xFF)
+  result.A = byte((V shr 8) and 0xFF)
+
+const
+  c1 = ABGR(0xFF007F7F)
+echo ABGR(0xFF007F7F).repr, c1.repr
+
+
+# bug 8740
+
+static:
+  try:
+    raise newException(ValueError, "foo")
+  except Exception:
+    echo "caught Exception"
+  except Defect:
+    echo "caught Defect"
+  except ValueError:
+    echo "caught ValueError"
+
+# bug #10538
+
+block:
+  proc fun1(): seq[int] =
+    try:
+      try:
+        result.add(1)
+        return
+      except:
+        result.add(-1)
+      finally:
+        result.add(2)
+    finally:
+      result.add(3)
+    result.add(4)
+
+  let x1 = fun1()
+  const x2 = fun1()
+  doAssert(x1 == x2)
+
+# bug #11610
+proc simpleTryFinally()=
+  try:
+    echo "main:begin"
+  finally:
+    echo "main:end"
+
+static: simpleTryFinally()
+
+# bug #10981
+
+proc main =
+  for i in 0..<15:
+    var someSets = @[initHashSet[int]()]
+    someSets[^1].incl(0) # <-- segfaults
+    if i == 0:
+      echo someSets
+
+static:
+  main()
+
+# bug #7261
+const file = """
+sprites.png
+size: 1024,1024
+format: RGBA8888
+filter: Linear,Linear
+repeat: none
+char/slide_down
+  rotate: false
+  xy: 730, 810
+  size: 204, 116
+  orig: 204, 116
+  offset: 0, 0
+  index: -1
+"""
+
+type
+  AtlasPage = object
+    width, height: int
+    path: string
+
+  CtsStream = object
+    data: string
+    pos: int
+
+proc atEnd(stream: CtsStream): bool =
+  stream.pos >= stream.data.len
+
+proc readChar(stream: var CtsStream): char =
+  if stream.atEnd:
+    result = '\0'
+  else:
+    result = stream.data[stream.pos]
+    inc stream.pos
+
+proc readLine(s: var CtsStream, line: var string): bool =
+  # This is pretty much copied from the standard library:
+  line.setLen(0)
+  while true:
+    var c = readChar(s)
+    if c == '\c':
+      c = readChar(s)
+      break
+    elif c == '\L': break
+    elif c == '\0':
+      if line.len > 0: break
+      else: return false
+    line.add(c)
+  result = true
+
+proc peekLine(s: var CtsStream, line: var string): bool =
+  let oldPos = s.pos
+  result = s.readLine(line)
+  s.pos = oldPos
+
+proc initCtsStream(data: string): CtsStream =
+  CtsStream(
+    pos: 0,
+    data: data
+  )
+
+# ********************
+# Interesting stuff happens here:
+# ********************
+
+proc parseAtlas(stream: var CtsStream) =
+  var pages = @[AtlasPage(), AtlasPage()]
+  var line = ""
+
+  block:
+    let page = addr pages[^1]
+    discard stream.peekLine(line)
+    discard stream.peekLine(line)
+    echo page[]
+  echo pages
+
+static:
+  var stream = initCtsStream(file)
+  parseAtlas(stream)
+  echo "Done!"
+
+
+# bug #12244
+
+type
+  Apple = object
+    data: int
+
+func what(x: var Apple) =
+  x = Apple(data: 1)
+
+func oh_no(): Apple =
+  what(result)
+
+const
+  vmCrash = oh_no()
+
+debugEcho vmCrash
+
+
+# bug #12310
+
+proc someTransform(s: var array[8, uint64]) =
+  var s1 = 5982491417506315008'u64
+  s[1] += s1
+
+static:
+  var state: array[8, uint64]
+  state[1] = 7105036623409894663'u64
+  someTransform(state)
+
+  doAssert state[1] == 13087528040916209671'u64
+
+import macros
+# bug #12670
+
+macro fooImpl(arg: untyped) =
+  result = quote do:
+    `arg`
+
+proc foo(): string {.compileTime.} =
+  fooImpl:
+    result = "foo"
+    result.addInt 4
+
+static:
+  echo foo()
+  echo foo()
+  echo foo()
+
+# bug #12488
+type
+  MyObject = object
+    a,b: int
+  MyObjectRef = ref MyObject
+
+static:
+  let x1 = new(MyObject)
+  echo x1[]
+  let x2 = new(MyObjectRef)
+  echo x2[]
+  let x3 = new(ref MyObject) # cannot generate VM code for ref MyObject
+  echo x3[]
+
+# bug #19464
+type
+  Wrapper = object
+    inner: int
+
+proc assign(r: var Wrapper, a: Wrapper) =
+  r = a
+
+proc myEcho(a: Wrapper) =
+  var tmp = a
+  assign(tmp, Wrapper(inner: 0)) # this shouldn't modify `a`
+  doAssert a.inner == 1
+
+static:
+  var result: Wrapper
+  assign(result, Wrapper(inner: 1))
+  myEcho(result)
+
+when true:
+  # bug #15974
+  type Foo = object
+    f0: int
+
+  proc fn(a: var Foo) =
+    var s: Foo
+    a = Foo(f0: 2)
+    s = a
+    doAssert s.f0 == 2
+    a = Foo(f0: 3)
+    doAssert s.f0 == 2
+
+  proc test2()=
+    var a = Foo(f0: 1)
+    fn(a)
+
+  static: test2()
+  test2()
+
+# bug #12551
+type
+  StUint = object
+    lo: uint64
+
+func `+=`(x: var Stuint, y: Stuint) =
+  x.lo += y.lo
+
+func `-`(x, y: Stuint): Stuint =
+  result.lo = x.lo - y.lo
+
+func `+`(x, y: Stuint): Stuint =
+  result.lo = x.lo + y.lo
+
+func `-=`(x: var Stuint, y: Stuint) =
+  x = x - y
+
+func `<`(x, y: Stuint): bool=
+  x.lo < y.lo
+
+func `==`(x, y: Stuint): bool =
+  x.lo == y.lo
+
+func `<=`(x, y: Stuint): bool =
+  x.lo <= y.lo
+
+proc div3n2n(r: var Stuint, b: Stuint) =
+  var d: Stuint
+  r = d
+  r += b
+
+func div2n1n(r: var Stuint, b: Stuint) =
+  div3n2n(r, b)
+
+func divmodBZ(x, y: Stuint, r: var Stuint)=
+  div2n1n(r, y)
+  r.lo = 3
+
+func `mod`(x, y: Stuint): Stuint =
+  divmodBZ(x, y, result)
+
+func doublemod_internal(a, m: Stuint): Stuint =
+  result = a
+  if a >= m - a:
+    result -= m
+  result += a
+
+func mulmod_internal(a, b, m: Stuint): Stuint =
+  var (a, b) = (a, b)
+  swap(a, b)
+  debugEcho "x1 a: ", a
+  a = doublemod_internal(a, m)
+  debugEcho "x2 a: ", a
+  a = doublemod_internal(a, m)
+  debugEcho "x3 a: ", a
+
+func powmod_internal(a, m: Stuint): Stuint =
+  var a = a
+  debugEcho "z1 m: ", m
+  debugEcho "z2 a: ", a
+  result = mulmod_internal(result, a, m)
+  debugEcho "z3 a: ", a
+  a = mulmod_internal(a, a, m)
+
+func powmod*(a, m: Stuint) =
+  discard powmod_internal(a mod m, m)
+
+static:
+  var x = Stuint(lo: high(uint64))
+  var y = Stuint(lo: 12)
+
+  powmod(x, y)
+
+# bug #16780
+when true:
+  template swap*[T](a, b: var T) =
+    var a2 = addr(a)
+    var b2 = addr(b)
+    var aOld = a2[]
+    a2[] = b2[]
+    b2[] = aOld
+
+  proc rather =
+    block:
+      var a = 1
+      var b = 2
+      swap(a, b)
+      echo (a,b)
+
+    block:
+      type Foo = ref object
+        x: int
+      var a = Foo(x:1)
+      var b = Foo(x:2)
+      swap(a, b)
+      echo (a.x, b.x)
+
+    block:
+      type Foo = object
+        x: int
+      var a = Foo(x:1)
+      var b = Foo(x:2)
+      swap(a, b)
+      echo (a.x,b.x)
+
+  static: rather()
+  rather()
+
+# bug #16020
+when true:
+  block:
+    type Foo = object
+      f0: int
+    proc main=
+      var f = Foo(f0: 3)
+      var f2 = f.addr
+      f2[].f0 += 1
+      f2.f0 += 1
+      echo f
+    static: main()
+    main()
+
+import tables, strutils
+
+# bug #14553
+const PpcPatterns = @[("aaaa", "bbbb"), ("aaaaa", "bbbbb"), ("aaaaaa", "bbbbbb"), ("aaaaaaa", "bbbbbbb"), ("aaaaaaaa", "bbbbb")]
+
+static:
+    var
+        needSecondIdentifier = initTable[uint32, seq[(string, string)]]()
+
+    for (name, pattern) in PpcPatterns:
+        let
+            firstPart = 0'u32
+            lastPart = "test"
+
+        needSecondIdentifier.mgetOrPut(firstPart, @[]).add((name, pattern))
+
+    doAssert needSecondIdentifier[0] == @[("aaaa", "bbbb"), ("aaaaa", "bbbbb"), ("aaaaaa", "bbbbbb"), ("aaaaaaa", "bbbbbbb"), ("aaaaaaaa", "bbbbb")]
+
+# bug #17864
+macro transform*(fn: typed) =
+  quote do:
+    `fn`
+
+var map: Table[string, HashSet[string]]
+proc publish*(): void {.transform.} =
+  map["k"] = init_hash_set[string]()
+  map["k"].incl "d"
+
+publish()
diff --git a/tests/vm/tmitems.nim b/tests/vm/tmitems_vm.nim
index a0e64d6aa..787d52cc6 100644
--- a/tests/vm/tmitems.nim
+++ b/tests/vm/tmitems_vm.nim
@@ -1,5 +1,5 @@
 discard """
-  msg: '''13'''
+  nimout: '''13'''
   output: '''3
 3
 3'''
@@ -7,7 +7,7 @@ discard """
 # bug #3731
 var list {.compileTime.} = newSeq[int]()
 
-macro calc*(): typed =
+macro calc*(): void =
   list.add(1)
   for c in list.mitems:
     c = 13
@@ -19,7 +19,7 @@ calc()
 
 # bug #3859
 import macros
-macro m: typed =
+macro m: void =
   var s = newseq[NimNode](3)
   # var s: array[3,NimNode]                 # not working either
   for i in 0..<s.len: s[i] = newLit(3)    # works
diff --git a/tests/vm/tnewseqofcap.nim b/tests/vm/tnewseqofcap.nim
new file mode 100644
index 000000000..a7dc07aa6
--- /dev/null
+++ b/tests/vm/tnewseqofcap.nim
@@ -0,0 +1,14 @@
+const
+  foo = @["aaa", "bbb", "ccc"]
+
+proc myTuple: tuple[n: int, bar: seq[string]] =
+  result.n = 42
+  result.bar = newSeqOfCap[string](foo.len)
+  for f in foo:
+    result.bar.add(f)
+
+# It works if you change the below `const` to `let`
+const
+  (n, bar) = myTuple()
+
+doAssert bar == @["aaa", "bbb", "ccc"]
\ No newline at end of file
diff --git a/tests/vm/tnilclosurecall.nim b/tests/vm/tnilclosurecall.nim
new file mode 100644
index 000000000..449865b9c
--- /dev/null
+++ b/tests/vm/tnilclosurecall.nim
@@ -0,0 +1,8 @@
+discard """
+  errormsg: "attempt to call nil closure"
+  line: 8
+"""
+
+static:
+  let x: proc () = nil
+  x()
diff --git a/tests/vm/tnilclosurecallstacktrace.nim b/tests/vm/tnilclosurecallstacktrace.nim
new file mode 100644
index 000000000..879060e8e
--- /dev/null
+++ b/tests/vm/tnilclosurecallstacktrace.nim
@@ -0,0 +1,23 @@
+discard """
+  action: reject
+  nimout: '''
+stack trace: (most recent call last)
+tnilclosurecallstacktrace.nim(23, 6) tnilclosurecallstacktrace
+tnilclosurecallstacktrace.nim(20, 6) baz
+tnilclosurecallstacktrace.nim(17, 6) bar
+tnilclosurecallstacktrace.nim(14, 4) foo
+tnilclosurecallstacktrace.nim(14, 4) Error: attempt to call nil closure
+'''
+"""
+
+proc foo(x: proc ()) =
+  x()
+
+proc bar(x: proc ()) =
+  foo(x)
+
+proc baz(x: proc ()) =
+  bar(x)
+
+static:
+  baz(nil)
diff --git a/tests/vm/tnilref.nim b/tests/vm/tnilref.nim
new file mode 100644
index 000000000..5e27cf0cb
--- /dev/null
+++ b/tests/vm/tnilref.nim
@@ -0,0 +1,7 @@
+discard """
+  errormsg: "attempt to access a nil address"
+"""
+
+static:
+    var s: ref int
+    s[] = 1
\ No newline at end of file
diff --git a/tests/vm/tnimnode.nim b/tests/vm/tnimnode.nim
index 188bac9bf..f1c4d5e5a 100644
--- a/tests/vm/tnimnode.nim
+++ b/tests/vm/tnimnode.nim
@@ -4,19 +4,17 @@ proc assertEq(arg0,arg1: string): void =
   if arg0 != arg1:
     raiseAssert("strings not equal:\n" & arg0 & "\n" & arg1)
 
-static:
-  # a simple assignment of stmtList to another variable
-  var node: NimNode
-  # an assignment of stmtList into an array
-  var nodeArray: array[1, NimNode]
-  # an assignment of stmtList into a seq
-  var nodeSeq = newSeq[NimNode](2)
-
+# a simple assignment of stmtList to another variable
+var node {.compileTime.}: NimNode
+# an assignment of stmtList into an array
+var nodeArray {.compileTime.}: array[1, NimNode]
+# an assignment of stmtList into a seq
+var nodeSeq {.compileTime.} = newSeq[NimNode](2)
 
 proc checkNode(arg: NimNode; name: string): void {. compileTime .} =
   echo "checking ", name
 
-  assertEq arg.lispRepr , "StmtList(DiscardStmt(Empty()))"
+  assertEq arg.lispRepr, """(StmtList (DiscardStmt (Empty)))"""
 
   node = arg
   nodeArray = [arg]
@@ -26,19 +24,19 @@ proc checkNode(arg: NimNode; name: string): void {. compileTime .} =
   seqAppend.add(arg)   # bit this creates a copy
   arg.add newCall(ident"echo", newLit("Hello World"))
 
-  assertEq arg.lispRepr          , """StmtList(DiscardStmt(Empty()), Call(Ident("echo"), StrLit("Hello World")))"""
-  assertEq node.lispRepr         , """StmtList(DiscardStmt(Empty()), Call(Ident("echo"), StrLit("Hello World")))"""
-  assertEq nodeArray[0].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident("echo"), StrLit("Hello World")))"""
-  assertEq nodeSeq[0].lispRepr   , """StmtList(DiscardStmt(Empty()), Call(Ident("echo"), StrLit("Hello World")))"""
-  assertEq seqAppend[0].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident("echo"), StrLit("Hello World")))"""
-  assertEq seqAppend[1].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident("echo"), StrLit("Hello World")))"""
+  assertEq arg.lispRepr,          """(StmtList (DiscardStmt (Empty)) (Call (Ident "echo") (StrLit "Hello World")))"""
+  assertEq node.lispRepr,         """(StmtList (DiscardStmt (Empty)) (Call (Ident "echo") (StrLit "Hello World")))"""
+  assertEq nodeArray[0].lispRepr, """(StmtList (DiscardStmt (Empty)) (Call (Ident "echo") (StrLit "Hello World")))"""
+  assertEq nodeSeq[0].lispRepr,   """(StmtList (DiscardStmt (Empty)) (Call (Ident "echo") (StrLit "Hello World")))"""
+  assertEq seqAppend[0].lispRepr, """(StmtList (DiscardStmt (Empty)) (Call (Ident "echo") (StrLit "Hello World")))"""
+  assertEq seqAppend[1].lispRepr, """(StmtList (DiscardStmt (Empty)) (Call (Ident "echo") (StrLit "Hello World")))"""
 
   echo "OK"
 
-static:
-  # the root node that is used to generate the Ast
-  var stmtList: NimNode
+# the root node that is used to generate the Ast
+var stmtList {.compileTime.}: NimNode
 
+static:
   stmtList = newStmtList(nnkDiscardStmt.newTree(newEmptyNode()))
 
   checkNode(stmtList, "direct construction")
diff --git a/tests/vm/tnocompiletimefunc.nim b/tests/vm/tnocompiletimefunc.nim
new file mode 100644
index 000000000..a95648c0f
--- /dev/null
+++ b/tests/vm/tnocompiletimefunc.nim
@@ -0,0 +1,14 @@
+discard """
+  errormsg: "request to generate code for .compileTime proc: foo"
+"""
+
+# ensure compileTime funcs can't be called from runtime
+
+func foo(a: int): int {.compileTime.} =
+  a * a
+
+proc doAThing(): int =
+  for i in 0..2:
+    result += foo(i)
+
+echo doAThing()
diff --git a/tests/vm/tnocompiletimefunclambda.nim b/tests/vm/tnocompiletimefunclambda.nim
new file mode 100644
index 000000000..d134eea40
--- /dev/null
+++ b/tests/vm/tnocompiletimefunclambda.nim
@@ -0,0 +1,6 @@
+discard """
+  errormsg: "request to generate code for .compileTime proc: :anonymous"
+"""
+
+let a = func(a: varargs[int]) {.compileTime, closure.} =
+  discard a[0]
\ No newline at end of file
diff --git a/tests/vm/tnoreturn.nim b/tests/vm/tnoreturn.nim
new file mode 100644
index 000000000..d4f8601a9
--- /dev/null
+++ b/tests/vm/tnoreturn.nim
@@ -0,0 +1,32 @@
+block: # issue #22216
+  type
+    Result[T, E] = object
+      case oVal: bool
+      of false:
+        eVal: E
+      of true:
+        vVal: T
+
+  func raiseResultDefect(m: string) {.noreturn, noinline.} =
+    raise (ref Defect)(msg: m)
+
+  template withAssertOk(self: Result, body: untyped): untyped =
+    case self.oVal
+    of false:
+      raiseResultDefect("Trying to access value with err Result")    
+    else:
+      body
+
+  func value[T, E](self: Result[T, E]): T {.inline.} =    
+    withAssertOk(self):  
+      self.vVal
+      
+  const
+    x = Result[int, string](oVal: true, vVal: 123)
+    z = x.value()
+    
+  let
+    xx = Result[int, string](oVal: true, vVal: 123)
+    zz = x.value()
+  
+  doAssert z == zz
diff --git a/tests/vm/topenarrays.nim b/tests/vm/topenarrays.nim
new file mode 100644
index 000000000..375d2523d
--- /dev/null
+++ b/tests/vm/topenarrays.nim
@@ -0,0 +1,89 @@
+proc mutate(a: var openarray[int]) =
+  var i = 0
+  for x in a.mitems:
+    x = i
+    inc i
+
+proc mutate(a: var openarray[char]) =
+  var i = 1
+  for ch in a.mitems:
+    ch = 'a'
+
+
+static:
+  var a = [10, 20, 30]
+  assert a.toOpenArray(1, 2).len == 2
+
+  mutate(a)
+  assert a.toOpenArray(0, 2) == [0, 1, 2]
+  assert a.toOpenArray(0, 0) == [0]
+  assert a.toOpenArray(1, 2) == [1, 2]
+  assert "Hello".toOpenArray(1, 4) == "ello"
+  var str = "Hello"
+  str.toOpenArray(2, 4).mutate()
+  assert str.toOpenArray(0, 4).len == 5
+  assert str.toOpenArray(0, 0).len == 1
+  assert str.toOpenArray(0, 0).high == 0
+  assert str == "Heaaa"
+  assert str.toOpenArray(0, 4) == "Heaaa"
+
+  var arr: array[3..4, int] = [1, 2]
+  assert arr.toOpenArray(3, 4) == [1, 2]
+  assert arr.toOpenArray(3, 4).len == 2
+  assert arr.toOpenArray(3, 3).high == 0
+
+  assert arr.toOpenArray(3, 4).toOpenArray(0, 0) == [1]
+
+
+proc doThing(s: static openArray[int]) = discard
+
+doThing([10, 20, 30].toOpenArray(0, 0))
+
+# bug #19969
+proc f(): array[1, byte] =
+  var a: array[1, byte]
+  result[0..0] = a.toOpenArray(0, 0)
+
+doAssert static(f()) == [byte(0)]
+
+
+# bug #15952
+proc main1[T](a: openArray[T]) = discard
+proc main2[T](a: var openArray[T]) = discard
+
+proc main =
+  var a = [1,2,3,4,5]
+  main1(a.toOpenArray(1,3))
+  main2(a.toOpenArray(1,3))
+static: main()
+main()
+
+# bug #16306
+{.experimental: "views".}
+proc test(x: openArray[int]): tuple[id: int] =
+  let y: openArray[int] = toOpenArray(x, 0, 2)
+  result = (y[0],)
+template fn=
+  doAssert test([0,1,2,3,4,5]).id == 0
+fn() # ok
+static: fn()
+
+
+block: # bug #22095
+  type
+    StUint = object
+      limbs: array[4, uint64]
+
+  func shlAddMod(a: var openArray[uint64]) =  
+    a[0] = 10
+
+  func divRem(r: var openArray[uint64]) =
+    shlAddMod(r.toOpenArray(0, 3))
+
+  func fn(): StUint =
+    divRem(result.limbs)
+
+  const
+    z = fn()
+
+  doAssert z.limbs[0] == 10
diff --git a/tests/vm/toverflowopcaddimmint.nim b/tests/vm/toverflowopcaddimmint.nim
index c36b9ed9b..4ff614e5b 100644
--- a/tests/vm/toverflowopcaddimmint.nim
+++ b/tests/vm/toverflowopcaddimmint.nim
@@ -7,5 +7,5 @@ static:
     var
       x = int64.high
     discard x + 1
-    assert false
+    doAssert false
   p()
diff --git a/tests/vm/toverflowopcaddint.nim b/tests/vm/toverflowopcaddint.nim
index 6d96afc78..d494245b1 100644
--- a/tests/vm/toverflowopcaddint.nim
+++ b/tests/vm/toverflowopcaddint.nim
@@ -8,5 +8,5 @@ static:
       x = int64.high
       y = 1
     discard x + y
-    assert false
+    doAssert false
   p()
diff --git a/tests/vm/toverflowopcmulint.nim b/tests/vm/toverflowopcmulint.nim
index 81b3234ba..936eea6c2 100644
--- a/tests/vm/toverflowopcmulint.nim
+++ b/tests/vm/toverflowopcmulint.nim
@@ -5,7 +5,7 @@ discard """
 static:
   proc p =
     var
-      x = 1 shl 62
+      x = 1'i64 shl 62
     discard x * 2
-    assert false
+    doAssert false
   p()
diff --git a/tests/vm/toverflowopcsubimmint.nim b/tests/vm/toverflowopcsubimmint.nim
index 09d6f745b..08356590c 100644
--- a/tests/vm/toverflowopcsubimmint.nim
+++ b/tests/vm/toverflowopcsubimmint.nim
@@ -6,5 +6,5 @@ static:
   proc p =
     var x = int64.low
     discard x - 1
-    assert false
+    doAssert false
   p()
diff --git a/tests/vm/toverflowopcsubint.nim b/tests/vm/toverflowopcsubint.nim
index 8d114f200..74e34c6a4 100644
--- a/tests/vm/toverflowopcsubint.nim
+++ b/tests/vm/toverflowopcsubint.nim
@@ -8,5 +8,5 @@ static:
       x = int64.low
       y = 1
     discard x - y
-    assert false
+    doAssert false
   p()
diff --git a/tests/vm/tquadplus.nim b/tests/vm/tquadplus.nim
index 552e8fef7..acf20cd96 100644
--- a/tests/vm/tquadplus.nim
+++ b/tests/vm/tquadplus.nim
@@ -1,8 +1,5 @@
 # bug #1023
 
-discard """
-  output: "1 == 1"
-"""
 
 type Quadruple = tuple[a, b, c, d: int]
 
@@ -14,4 +11,4 @@ const
   B = (a: 0, b: -2, c: 1, d: 0)
   C = A + B
 
-echo C.d, " == ", (A+B).d
+doAssert $C.d & " == " & $(A+B).d == "1 == 1"
diff --git a/tests/vm/tref.nim b/tests/vm/tref.nim
index 517a67fb0..e70305225 100644
--- a/tests/vm/tref.nim
+++ b/tests/vm/tref.nim
@@ -9,4 +9,63 @@ static:
 
   b[5] = 'c'
   doAssert a[] == "Hellocworld"
-  doAssert b[] == "Hellocworld"
\ No newline at end of file
+  doAssert b[] == "Hellocworld"
+
+  proc notGlobal() =
+    var
+      a: ref string
+      b: ref string
+    new a
+
+    a[] = "Hello world"
+    b = a
+
+    b[5] = 'c'
+    doAssert a[] == "Hellocworld"
+    doAssert b[] == "Hellocworld"
+  notGlobal()
+
+static: # bug 6081
+  block:
+    type Obj = object
+      field: ref int
+    var i: ref int
+    new(i)
+    var r = Obj(field: i)
+    var rr = r
+    r.field = nil
+    doAssert rr.field != nil
+
+  proc foo() = # Proc to avoid special global logic
+    var s: seq[ref int]
+    var i: ref int
+    new(i)
+    s.add(i)
+    var head = s[0]
+    s[0] = nil
+    doAssert head != nil
+
+  foo()
+
+static:
+
+  block: # global alias
+    var s: ref int
+    new(s)
+    var ss = s
+    s[] = 1
+    doAssert ss[] == 1
+
+static: # bug #8402
+  type R = ref object
+  var empty: R
+  let otherEmpty = empty
+
+block:
+  # fix https://github.com/timotheecour/Nim/issues/88
+  template fun() =
+    var s = @[10,11,12]
+    var a = s[0].addr
+    a[] += 100 # was giving SIGSEGV
+    doAssert a[] == 110
+  static: fun()
diff --git a/tests/vm/treset.nim b/tests/vm/treset.nim
new file mode 100644
index 000000000..32fbc7f04
--- /dev/null
+++ b/tests/vm/treset.nim
@@ -0,0 +1,50 @@
+static:
+  type Obj = object
+    field: int
+  var o = Obj(field: 1)
+  reset(o)
+  doAssert o.field == 0
+
+  var x = 4
+  reset(x)
+  doAssert x == 0
+
+static:
+  type ObjB = object
+    field: int
+  var o = ObjB(field: 1)
+  o = default(ObjB)
+  doAssert o.field == 0
+
+static:
+  var i = 2
+  reset(i)
+  doAssert i == 0
+
+static:
+  var i = new int
+  reset(i)
+  doAssert i.isNil
+
+static:
+  var s = @[1, 2, 3]
+  reset(s)
+  doAssert s == @[]
+
+static:
+  proc f() =
+    var i = 2
+    reset(i)
+    doAssert i == 0
+  f()
+
+proc main =
+  var y = [1, 2, 3, 4]
+  y = default(array[4, int])
+  for a in y: doAssert(a == 0)
+
+  var x = 4
+  x = default(int)
+  doAssert x == 0
+
+main()
diff --git a/tests/vm/trgba.nim b/tests/vm/trgba.nim
deleted file mode 100644
index 923ea1b2e..000000000
--- a/tests/vm/trgba.nim
+++ /dev/null
@@ -1,36 +0,0 @@
-discard """
-  output: '''[127, 127, 0, 255]
-[127, 127, 0, 255]
-'''
-"""
-
-#bug #1009
-type
-  TAggRgba8* = array[4, byte]
-
-template R*(self: TAggRgba8): byte = self[0]
-template G*(self: TAggRgba8): byte = self[1]
-template B*(self: TAggRgba8): byte = self[2]
-template A*(self: TAggRgba8): byte = self[3]
-
-template `R=`*(self: TAggRgba8, val: byte) =
-  self[0] = val
-template `G=`*(self: TAggRgba8, val: byte) =
-  self[1] = val
-template `B=`*(self: TAggRgba8, val: byte) =
-  self[2] = val
-template `A=`*(self: TAggRgba8, val: byte) =
-  self[3] = val
-
-proc ABGR*(val: int| int64): TAggRgba8 =
-  var V = val
-  result.R = byte(V and 0xFF)
-  V = V shr 8
-  result.G = byte(V and 0xFF)
-  V = V shr 8
-  result.B = byte(V and 0xFF)
-  result.A = byte((V shr 8) and 0xFF)
-
-const
-  c1 = ABGR(0xFF007F7F)
-echo ABGR(0xFF007F7F).repr, c1.repr
diff --git a/tests/vm/triangle_array.nim b/tests/vm/triangle_array.nim
index 054c66f22..0704239c6 100644
--- a/tests/vm/triangle_array.nim
+++ b/tests/vm/triangle_array.nim
@@ -1,7 +1,3 @@
-discard """
-  output: "56"
-"""
-
 # bug #1781
 
 proc initCombinations: array[11, array[11, int]] =
@@ -14,4 +10,4 @@ proc initCombinations: array[11, array[11, int]] =
   result[6][6 .. 10] =             [52,53,54,55,56]
 
 const combinations = initCombinations()
-echo combinations[6][10]
+doAssert combinations[6][10] == 56
diff --git a/tests/vm/tscriptcompiletime.nims b/tests/vm/tscriptcompiletime.nims
new file mode 100644
index 000000000..daec54bf7
--- /dev/null
+++ b/tests/vm/tscriptcompiletime.nims
@@ -0,0 +1,9 @@
+discard """
+  cmd: "nim e $file"
+"""
+
+import mscriptcompiletime
+
+macro foo =
+  doAssert bar == 2
+foo()
diff --git a/tests/vm/tseq_badinit.nim b/tests/vm/tseq_badinit.nim
index 15889d60e..5fa223c85 100644
--- a/tests/vm/tseq_badinit.nim
+++ b/tests/vm/tseq_badinit.nim
@@ -22,14 +22,14 @@ template test(typename, default: untyped) =
     result = newSeq[typename]()
     result.add(default)
     result.setLen(3)
-    for i in 0 .. <2:
+    for i in 0 ..< 2:
       result[i] = default
 
   const constval = `abc typename`()
   doAssert(constval == `abc typename`())
 
   proc `arr typename`(): array[4, typename] =
-    for i in 0 .. <2:
+    for i in 0 ..< 2:
       result[i] = default
   const constarr = `arr typename`()
   doAssert(constarr == `arr typename`())
diff --git a/tests/vm/tsetlen.nim b/tests/vm/tsetlen.nim
new file mode 100644
index 000000000..9fd30f331
--- /dev/null
+++ b/tests/vm/tsetlen.nim
@@ -0,0 +1,30 @@
+type Foo = object
+  index: int
+
+block:
+  proc fun[T]() =
+    var foo: T
+    var n = 10
+
+    var foos: seq[T]
+    foos.setLen n
+
+    n.inc
+    foos.setLen n
+
+    for i in 0 ..< n:
+      let temp = foos[i]
+      when T is object:
+        doAssert temp.index == 0
+      when T is ref object:
+        doAssert temp == nil
+      doAssert temp == foo
+
+  static:
+    fun[Foo]()
+    fun[int]()
+    fun[float]()
+    fun[string]()
+    fun[(int, string)]()
+    fun[ref Foo]()
+    fun[seq[int]]()
diff --git a/tests/vm/tsignaturehash.nim b/tests/vm/tsignaturehash.nim
new file mode 100644
index 000000000..972ec6fb0
--- /dev/null
+++ b/tests/vm/tsignaturehash.nim
@@ -0,0 +1,20 @@
+# test sym digest is computable at compile time
+
+import macros, algorithm
+import ../../dist/checksums/src/checksums/md5
+
+macro testmacro(s: typed{nkSym}): string =
+  let s = getMD5(signaturehash(s) & " - " & symBodyHash(s))
+  result = newStrLitNode(s)
+
+macro testmacro(s: typed{nkOpenSymChoice|nkClosedSymChoice}): string =
+  var str = ""
+  for sym in s:
+    str &= symBodyHash(sym)
+  result = newStrLitNode(getMD5(str))
+
+# something recursive and/or generic
+discard testmacro(testmacro)
+discard testmacro(`[]`)
+discard testmacro(binarySearch)
+discard testmacro(sort)
diff --git a/tests/vm/tsimpleglobals.nim b/tests/vm/tsimpleglobals.nim
index 27bfdce50..7ab665070 100644
--- a/tests/vm/tsimpleglobals.nim
+++ b/tests/vm/tsimpleglobals.nim
@@ -1,5 +1,5 @@
 discard """
-  msg: "abc xyz bb"
+  nimout: "abc xyz bb"
 """
 
 # bug #2473
diff --git a/tests/vm/tslow_tables.nim b/tests/vm/tslow_tables.nim
new file mode 100644
index 000000000..e40187f18
--- /dev/null
+++ b/tests/vm/tslow_tables.nim
@@ -0,0 +1,30 @@
+discard """
+  timeout: "7"
+  action: "compile"
+  nimout: '''create
+search
+done'''
+"""
+
+# bug #12195
+
+import tables
+
+type Flop = object
+  a: array[128, int]  # <-- compile time is proportional to array size
+
+proc hop(): bool =
+  var v: Table[int, Flop]
+
+  echo "create"
+  for i in 1..1000:
+    v.add i, Flop()
+
+  echo "search"
+  for i in 1..1000:
+    discard contains(v, i)
+
+  echo "done"
+
+const r {.used.} = hop()
+
diff --git a/tests/vm/tslurp.nim b/tests/vm/tslurp.nim
index 027db45d6..d762eb079 100644
--- a/tests/vm/tslurp.nim
+++ b/tests/vm/tslurp.nim
@@ -4,9 +4,9 @@ template getScriptDir(): string =
   parentDir(instantiationInfo(-1, true).filename)
 
 const
-  relRes = slurp"../../readme.txt"
-  absRes = slurp(parentDir(parentDir(getScriptDir())) / "readme.txt")
-
-echo relRes
-echo absRes
+  relRes = slurp"./tslurp.nim"
+  absRes = slurp(getScriptDir() / "tslurp.nim")
 
+doAssert relRes.len > 200
+doAssert absRes.len > 200
+doAssert relRes == absRes
diff --git a/tests/vm/tstaticprintseq.nim b/tests/vm/tstaticprintseq.nim
index 246a0211b..f4aab6b7e 100644
--- a/tests/vm/tstaticprintseq.nim
+++ b/tests/vm/tstaticprintseq.nim
@@ -1,5 +1,5 @@
 discard """
-  msg: '''1
+  nimout: '''1
 2
 3
 1
@@ -24,7 +24,7 @@ bb
 
 const s = @[1,2,3]
 
-macro foo: typed =
+macro foo() =
   for e in s:
     echo e
 
@@ -55,7 +55,7 @@ static:
   var m2: TData = data
   for x in m2.numbers: echo x
 
-macro ff(d: static[TData]): typed =
+macro ff(d: static[TData]) =
   for x in d.letters:
     echo x
 
diff --git a/tests/vm/tstring_openarray.nim b/tests/vm/tstring_openarray.nim
index 1b8a1304c..9318344f8 100644
--- a/tests/vm/tstring_openarray.nim
+++ b/tests/vm/tstring_openarray.nim
@@ -12,16 +12,16 @@ proc set_all[T](s: var openArray[T]; val: T) =
   for i in 0..<s.len:
     s[i] = val
 
-proc test() =
-    var a0 = "hello_world"
-    var a1 = [1,2,3,4,5,6,7,8,9]
-    var a2 = @[1,2,3,4,5,6,7,8,9]
-    a0.set_all('i')
-    a1.set_all(4)
-    a2.set_all(4)
-    doAssert a0 == "iiiiiiiiiii"
-    doAssert a1 == [4,4,4,4,4,4,4,4,4]
-    doAssert a2 == @[4,4,4,4,4,4,4,4,4]
+proc main() =
+  var a0 = "hello_world"
+  var a1 = [1,2,3,4,5,6,7,8,9]
+  var a2 = @[1,2,3,4,5,6,7,8,9]
+  a0.set_all('i')
+  a1.set_all(4)
+  a2.set_all(4)
+  doAssert a0 == "iiiiiiiiiii"
+  doAssert a1 == [4,4,4,4,4,4,4,4,4]
+  doAssert a2 == @[4,4,4,4,4,4,4,4,4]
 
 const constval0 = "hello".map(proc(x: char): char = x)
 const constval1 = [1,2,3,4].map(proc(x: int): int = x)
@@ -29,6 +29,5 @@ const constval1 = [1,2,3,4].map(proc(x: int): int = x)
 doAssert("hello".map(proc(x: char): char = x) == constval0)
 doAssert([1,2,3,4].map(proc(x: int): int = x) == constval1)
 
-test()
-static:
-    test()
+static: main()
+main()
diff --git a/tests/vm/tstringnil.nim b/tests/vm/tstringnil.nim
index 39e4040dc..d5dd4f4c9 100644
--- a/tests/vm/tstringnil.nim
+++ b/tests/vm/tstringnil.nim
@@ -20,16 +20,16 @@ proc buildSuiteContents(suiteName, suiteDesc, suiteBloc: NimNode): tuple[tests:
 
       var testObj = SuiteTest()
       if suiteName.kind == nnkNilLit:
-        testObj.suiteName = nil
+        testObj.suiteName = ""
       else:
         testObj.suiteName = $suiteName
       if suiteDesc.kind == nnkNilLit:
-        testObj.suiteDesc = nil
+        testObj.suiteDesc = ""
       else:
         testObj.suiteDesc = suiteDesc.strVal
       testObj.testName = $child[1] # should not ever be nil
       if child[2].kind == nnkNilLit:
-        testObj.testDesc = nil
+        testObj.testDesc = ""
       else:
         testObj.testDesc = child[2].strVal
       testObj.testBlock = child[1]
@@ -46,5 +46,5 @@ macro suite(suiteName, suiteDesc, suiteBloc: untyped): typed =
 
 # Test above
 suite basics, "Description of such":
-  test(t5, nil):
-    assert false
+  test(t5, ""):
+    doAssert false
diff --git a/tests/vm/tswap.nim b/tests/vm/tswap.nim
index 2219be9ca..bdbe5528c 100644
--- a/tests/vm/tswap.nim
+++ b/tests/vm/tswap.nim
@@ -1,9 +1,11 @@
 discard """
-msg: '''
+nimout: '''
 x.data = @[10]
 y = @[11]
 x.data = @[11]
-y = @[10]'''
+y = @[10]
+@[3, 2, 1]
+'''
 """
 
 # bug #2946
@@ -22,3 +24,11 @@ proc testSwap(): int {.compiletime.} =
   result = 99
 
 const something = testSwap()
+
+# bug #15463
+block:
+  static:
+    var s = @[1, 2, 3]
+    swap(s[0], s[2])
+
+    echo s
diff --git a/tests/vm/ttouintconv.nim b/tests/vm/ttouintconv.nim
index 5f8884e80..8c43a3adb 100644
--- a/tests/vm/ttouintconv.nim
+++ b/tests/vm/ttouintconv.nim
@@ -1,7 +1,7 @@
 import macros
 
 discard """
-msg: '''
+nimout: '''
 8 9 17
 239 255
 61439 65534 65535
@@ -20,7 +20,7 @@ msg: '''
 
 #bug #2514
 
-macro foo(): typed =
+macro foo() =
   var x = 8'u8
   var y = 9'u16
   var z = 17'u32
@@ -58,7 +58,7 @@ macro foo(): typed =
   var zz = 0x7FFFFFFF'u32
   echo zz
 
-macro foo2(): typed =
+macro foo2() =
   var xx = 0x7FFFFFFFFFFFFFFF
   echo xx
 
@@ -69,9 +69,16 @@ macro foo2(): typed =
   echo zz
 
   var ww = -9
-  var vv = ww.uint
-  var kk = vv.uint32
+  var vv = cast[uint](ww)
+  var kk = cast[uint32](vv)
   echo kk
 
 foo()
 foo2()
+
+block:
+  const neg5VM = block:
+    let x = -5'i8
+    uint64(x)
+  let y = -5'i8
+  doAssert uint64(y) == neg5VM
diff --git a/tests/vm/ttypedesc.nim b/tests/vm/ttypedesc.nim
new file mode 100644
index 000000000..d799e5adb
--- /dev/null
+++ b/tests/vm/ttypedesc.nim
@@ -0,0 +1,31 @@
+block: # issue #15760
+  type
+    Banana = object
+    SpecialBanana = object
+    
+  proc getName(_: type Banana): string = "Banana"
+  proc getName(_: type SpecialBanana): string = "SpecialBanana"
+
+  proc x[T](): string = 
+    const n = getName(T) # this one works
+    result = n
+    
+  proc y(T: type): string =
+    const n = getName(T) # this one failed to compile
+    result = n
+
+  doAssert x[SpecialBanana]() == "SpecialBanana"
+  doAssert y(SpecialBanana) == "SpecialBanana"
+
+import macros
+
+block: # issue #23112
+  type Container = object
+    foo: string
+
+  proc canBeImplicit(t: typedesc) {.compileTime.} =
+    let tDesc = getType(t)
+    doAssert tDesc.kind == nnkObjectTy
+
+  static:
+    canBeImplicit(Container)
diff --git a/tests/vm/tunsupportedintfloatcast.nim b/tests/vm/tunsupportedintfloatcast.nim
new file mode 100644
index 000000000..d65f10d86
--- /dev/null
+++ b/tests/vm/tunsupportedintfloatcast.nim
@@ -0,0 +1,3 @@
+static:
+  echo cast[int32](12.0) #[tt.Error
+       ^ VM does not support 'cast' from tyFloat with size 8 to tyInt32 with size 4 due to different sizes]#
diff --git a/tests/vm/tvarsection.nim b/tests/vm/tvarsection.nim
new file mode 100644
index 000000000..cd34bd02e
--- /dev/null
+++ b/tests/vm/tvarsection.nim
@@ -0,0 +1,11 @@
+var
+  a {.compileTime.} = 2
+  b = -1
+  c {.compileTime.} = 3
+  d = "abc"
+
+static:
+  doAssert a == 2
+  doAssert c == 3
+
+doAssert ($b & $d) == "-1abc"
diff --git a/tests/vm/tvmmisc.nim b/tests/vm/tvmmisc.nim
index 4af824cf4..6aeac5529 100644
--- a/tests/vm/tvmmisc.nim
+++ b/tests/vm/tvmmisc.nim
@@ -1,9 +1,7 @@
-# bug #4462
 import macros
 import os
-import ospaths
-import strutils
 
+# bug #4462
 block:
   proc foo(t: typedesc) {.compileTime.} =
     assert sameType(getType(t), getType(int))
@@ -11,27 +9,27 @@ block:
   static:
     foo(int)
 
-# #4412
+# bug #4412
 block:
   proc default[T](t: typedesc[T]): T {.inline.} = discard
 
   static:
     var x = default(type(0))
 
-# #6379
-static:
-  import algorithm
+# bug #6379
+import algorithm
 
+static:
   var numArray = [1, 2, 3, 4, -1]
   numArray.sort(cmp)
-  assert numArray == [-1, 1, 2, 3, 4]
+  doAssert numArray == [-1, 1, 2, 3, 4]
 
   var str = "cba"
   str.sort(cmp)
-  assert str == "abc"
+  doAssert str == "abc"
 
-# #6086
-import math, sequtils, future
+# bug #6086
+import math, sequtils, sugar
 
 block:
   proc f: int =
@@ -44,7 +42,7 @@ block:
   var a = f()
   const b = f()
 
-  assert a == b
+  doAssert a == b
 
 block:
   proc f(): seq[char] =
@@ -52,7 +50,7 @@ block:
 
   var runTime = f()
   const compTime = f()
-  assert runTime == compTime
+  doAssert runTime == compTime
 
 # #6083
 block:
@@ -66,27 +64,733 @@ block:
       result[i] = tmp
 
   const fact1000 = abc()
-  assert fact1000 == @[1, 2]
+  doAssert fact1000 == @[1, 2]
 
 # Tests for VM ops
 block:
   static:
-    assert "vm" in getProjectPath()
+    # for joint test, the project path is different, so I disabled it:
+    when false:
+      doAssert "vm" in getProjectPath()
 
     let b = getEnv("UNSETENVVAR")
-    assert b == ""
-    assert existsEnv("UNSERENVVAR") == false
+    doAssert b == ""
+    doAssert existsEnv("UNSERENVVAR") == false
     putEnv("UNSETENVVAR", "VALUE")
-    assert getEnv("UNSETENVVAR") == "VALUE"
-    assert existsEnv("UNSETENVVAR") == true
+    doAssert getEnv("UNSETENVVAR") == "VALUE"
+    doAssert existsEnv("UNSETENVVAR") == true
 
-    assert fileExists("MISSINGFILE") == false
-    assert dirExists("MISSINGDIR") == false
+    doAssert fileExists("MISSINGFILE") == false
+    doAssert dirExists("MISSINGDIR") == false
+    doAssert fileExists(currentSourcePath())
+    doAssert dirExists(currentSourcePath().parentDir)
 
-# #7210
+# bug #7210
 block:
   static:
     proc f(size: int): int =
       var some = newStringOfCap(size)
       result = size
-    doAssert f(4) == 4
\ No newline at end of file
+    doAssert f(4) == 4
+
+# bug #6689
+block:
+  static:
+    proc foo(): int = 0
+    var f: proc(): int
+    doAssert f.isNil
+    f = foo
+    doAssert(not f.isNil)
+
+block:
+  static:
+    var x: ref ref int
+    new(x)
+    doAssert(not x.isNil)
+
+# bug #7871
+static:
+  type Obj = object
+    field: int
+  var s = newSeq[Obj](1)
+  var o = Obj()
+  s[0] = o
+  o.field = 2
+  doAssert s[0].field == 0
+
+# bug #8125
+static:
+   let def_iter_var = ident("it")
+
+# bug #8142
+static:
+  type Obj = object
+    names: string
+
+  proc pushName(o: var Obj) =
+    var s = ""
+    s.add("FOOBAR")
+    o.names.add(s)
+
+  var o = Obj()
+  o.names = ""
+  o.pushName()
+  o.pushName()
+  doAssert o.names == "FOOBARFOOBAR"
+
+# bug #8154
+import parseutils
+
+static:
+  type Obj = object
+    i: int
+
+  proc foo(): Obj =
+    discard parseInt("1", result.i, 0)
+
+  static:
+    doAssert foo().i == 1
+
+# bug #10333
+block:
+  const
+    encoding: auto = [
+      ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"],
+      ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"],
+      ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"],
+      ["", "M", "MM", "MMM", "--", "-", "--", "---", "----", "--"],
+    ]
+  doAssert encoding.len == 4
+
+# bug #10886
+
+proc tor(): bool =
+  result = true
+  result = false or result
+
+proc tand(): bool =
+  result = false
+  result = true and result
+
+const
+  ctor = tor()
+  ctand = not tand()
+
+static:
+  doAssert ctor
+  doAssert ctand
+
+block: # bug #13081
+  type Kind = enum
+    k0, k1, k2, k3
+
+  type Foo = object
+    x0: float
+    case kind: Kind
+    of k0: discard
+    of k1: x1: int
+    of k2: x2: string
+    of k3: x3: string
+
+  const j1 = Foo(x0: 1.2, kind: k1, x1: 12)
+  const j2 = Foo(x0: 1.3, kind: k2, x2: "abc")
+  const j3 = Foo(x0: 1.3, kind: k3, x3: "abc2")
+  static:
+    doAssert $j1 == "(x0: 1.2, kind: k1, x1: 12)"
+    doAssert $j2 == """(x0: 1.3, kind: k2, x2: "abc")"""
+    doAssert $j3 == """(x0: 1.3, kind: k3, x3: "abc2")"""
+  doAssert $j1 == "(x0: 1.2, kind: k1, x1: 12)"
+  doAssert $j2 == """(x0: 1.3, kind: k2, x2: "abc")"""
+  doAssert $j3 == """(x0: 1.3, kind: k3, x3: "abc2")"""
+
+  doAssert j1.x1 == 12
+  static:
+    doAssert j1.x1 == 12
+
+block: # bug #15595
+  proc fn0()=echo 0
+  proc fn1()=discard
+  proc main=
+    var local = 0
+    proc fn2()=echo local
+    var a0 = fn0
+    var a1 = fn1
+    var a2 = fn2
+    var a3: proc()
+    var a4: proc()
+    doAssert a0 == fn0 # bugfix
+    doAssert a1 == fn1 # ditto
+    doAssert a2 == fn2 # ditto
+
+    doAssert fn0 != fn1
+
+    doAssert a2 != nil
+    doAssert a3 == nil # bugfix
+
+    doAssert a3 == a4 # bugfix
+  static: main()
+  main()
+
+block: # issue #20543
+  type F = proc()
+  const myArray = block:
+    var r: array[1, F]
+    r[0] = nil
+    r
+  doAssert isNil(myArray[0])
+
+# bug #15363
+import sequtils
+
+block:
+  func identity(a: bool): bool = a
+
+  var a: seq[bool] = static:
+      newSeq[bool](0).mapIt(it) # segfaults
+  var b: seq[bool] = static:
+      newSeq[bool](0).filterIt(it) # does not segfault
+  var c: seq[bool] = static:
+      newSeq[bool](0).map(identity) # does not segfault
+  var d: seq[bool] = static:
+      newSeq[bool](0).map(proc (a: bool): bool = false) # segfaults
+  var e: seq[bool] = static:
+      newSeq[bool](0).filter(identity) # does not segfault
+  var f: seq[bool] = static:
+      newSeq[bool](0).filter(proc (a: bool): bool = false) # segfaults
+
+  doAssert a == @[]
+  doAssert b == @[]
+  doAssert c == @[]
+  doAssert d == @[]
+  doAssert e == @[]
+  doAssert f == @[]
+
+
+block: # bug #18310
+  macro t() : untyped =
+    let
+      x = nnkTupleConstr.newTree(newLit(1))
+      y = nnkTupleConstr.newTree(newLit(2))
+    doAssert not (x == y) # not using != intentionally
+    doAssert not(cast[int](x) == cast[int](y))
+    doAssert not(system.`==`(x, y))
+    doAssert system.`==`(x, x)
+  t()
+
+block: # bug #10815
+  type
+    Opcode = enum
+      iChar, iSet
+
+    Inst = object
+      case code: Opcode
+        of iChar:
+          c: char
+        of iSet:
+          cs: set[char]
+
+    Patt = seq[Inst]
+
+
+  proc `$`(p: Patt): string =
+    discard
+
+  proc P(): Patt =
+    result.add Inst(code: iSet)
+
+  const a = P()
+  doAssert $a == ""
+
+import tables
+
+block: # bug #8007
+  type
+    CostKind = enum
+      Fixed,
+      Dynamic
+
+    Cost = object
+      case kind*: CostKind
+      of Fixed:
+        cost*: int
+      of Dynamic:
+        handler*: proc(value: int): int {.nimcall.}
+
+  proc foo(value: int): int {.nimcall.} =
+    sizeof(value)
+
+  const a: array[2, Cost] =[
+    Cost(kind: Fixed, cost: 999),
+    Cost(kind: Dynamic, handler: foo)
+  ]
+
+  # OK with arrays & object variants
+  doAssert $a == "[(kind: Fixed, cost: 999), (kind: Dynamic, handler: ...)]"
+
+  const b: Table[int, Cost] = {
+    0: Cost(kind: Fixed, cost: 999),
+    1: Cost(kind: Dynamic, handler: foo)
+  }.toTable
+
+  # KO with Tables & object variants
+  # echo b # {0: (kind: Fixed, cost: 0), 1: (kind: Dynamic, handler: ...)} # <----- wrong behaviour
+  doAssert $b == "{0: (kind: Fixed, cost: 999), 1: (kind: Dynamic, handler: ...)}"
+
+  const c: Table[int, int] = {
+    0: 100,
+    1: 999
+  }.toTable
+
+  # OK with Tables and primitive int
+  doAssert $c == "{0: 100, 1: 999}"
+
+  # For some reason the following gives
+  #    Error: invalid type for const: Cost
+  const d0 = Cost(kind: Fixed, cost: 999)
+
+  # OK with seq & object variants
+  const d = @[Cost(kind: Fixed, cost: 999), Cost(kind: Dynamic, handler: foo)]
+  doAssert $d == "@[(kind: Fixed, cost: 999), (kind: Dynamic, handler: ...)]"
+
+block: # bug #14340
+  block:
+    proc opl3EnvelopeCalcSin0() = discard
+    type EnvelopeSinfunc = proc() {.nimcall.} # todo: fixme 
+    # const EnvelopeCalcSin0 = opl3EnvelopeCalcSin0 # ok
+    const EnvelopeCalcSin0: EnvelopeSinfunc = opl3EnvelopeCalcSin0 # was bug
+    const envelopeSin = [EnvelopeCalcSin0]
+    var a = 0
+    envelopeSin[a]()
+
+  block:
+    type Mutator = proc() {.noSideEffect, gcsafe.}
+    proc mutator0() = discard
+    const mTable = [Mutator(mutator0)]
+    var i=0
+    mTable[i]()
+
+block: # VM wrong register free causes errors in unrelated code
+  block: # bug #15597
+    #[
+    Error: unhandled exception: 'sym' is not accessible using discriminant 'kind' of type 'TNode' [FieldDefect]
+    in /Users/timothee/git_clone/nim/Nim_prs/compiler/vm.nim(1176) rawExecute
+    in opcIndCall
+    in let prc = if not isClosure: bb.sym else: bb[0].sym
+    ]#
+    proc bar2(head: string): string = "asdf"
+    proc zook(u1: int) = discard
+
+    type PathEntry = object
+      kind: int
+      path: string
+
+    iterator globOpt(): int =
+      var u1: int
+
+      zook(u1)
+      zook(u1)
+      zook(u1)
+      zook(u1)
+      zook(u1)
+      zook(u1)
+      zook(u1)
+      zook(u1)
+      zook(u1)
+      zook(u1)
+      zook(u1)
+      zook(u1)
+      zook(u1)
+      zook(u1)
+
+      var entry = PathEntry()
+      entry.path = bar2("")
+      if false:
+        echo "here2"
+
+    proc processAux(a: float) = discard
+
+    template bar(iter: untyped): untyped =
+      var ret: float
+      for x in iter: break
+      ret
+
+    proc main() =
+      processAux(bar(globOpt()))
+    static: main()
+
+  block: # ditto
+    # D20201024T133245
+    type Deque = object
+    proc initDeque2(initialSize: int = 4): Deque = Deque()
+    proc len2(a: Deque): int = 2
+    proc baz(dir: string): bool = true
+    proc bar2(head: string): string = "asdf"
+    proc bar3(path: var string) = path = path
+
+    type PathEntry = object
+      kind: int
+      path: string
+
+    proc initGlobOpt(dir: string, a1=false,a2=false,a3=false,a4=false): string = dir
+
+    iterator globOpt(dir: string): int =
+      var stack = initDeque2()
+      doAssert baz("")
+      let z = stack.len2
+      if stack.len2 >= 0:
+        var entry = PathEntry()
+        let current = if true: stack.len2 else: stack.len2
+        entry.path = bar2("")
+        bar3(entry.path)
+      if false:
+        echo "here2" # comment here => you get same error as https://github.com/nim-lang/Nim/issues/15704
+
+    proc processAux(a: float) = discard
+
+    template bar(iter: untyped): untyped =
+      var ret: float
+      for x in iter: break
+      ret
+    proc main() =
+      processAux(bar(globOpt(initGlobOpt("."))))
+    static: main()
+
+  block: # bug #15704
+    #[
+    Error: attempt to access a nil address kind: rkFloat
+    ]#
+    type Deque = object
+    proc initDeque2(initialSize: int = 4): Deque = Deque()
+    proc len2(a: Deque): int = 2
+
+    proc baz(dir: string): bool = true
+    proc bar2(head: string): string = "asdf"
+    proc bar3(path: var string) = path = path
+
+    type PathEntry = object
+      kind: int
+      path: string
+      depth: int
+
+    proc initGlobOpt(dir: string, a1=false,a2=false,a3=false,a4=false): string =
+      dir
+
+    iterator globOpt(dir: string): int =
+      var stack = initDeque2()
+      doAssert baz("")
+      let z = stack.len2
+      var a5: int
+      if stack.len2 >= 0:
+        var entry = PathEntry()
+        if false:
+          echo "here"
+        let current = if true: stack.len2 else: stack.len2
+        entry.depth = 1
+        entry.path = bar2("")
+        bar3(entry.path)
+    proc processAux(a: float) = discard
+    template bar(iter: untyped): untyped =
+      var ret: float
+      for x in iter:
+        break
+      ret
+    const dir = "."
+    proc main() =
+      processAux(bar(globOpt(initGlobOpt(dir))))
+    static: main()
+
+block: # bug #8015
+  block:
+    type Foo = object
+      case b: bool
+      of false: v1: int
+      of true: v2: int
+    const t = [Foo(b: false, v1: 1), Foo(b: true, v2: 2)]
+    doAssert $t == "[(b: false, v1: 1), (b: true, v2: 2)]"
+    doAssert $t[0] == "(b: false, v1: 1)" # was failing
+
+  block:
+    type
+      CostKind = enum
+        Fixed,
+        Dynamic
+
+      Cost = object
+        case kind*: CostKind
+        of Fixed:
+          cost*: int
+        of Dynamic:
+          handler*: proc(): int {.nimcall.}
+
+    proc foo1(): int {.nimcall.} =
+      100
+
+    proc foo2(): int {.nimcall.} =
+      200
+
+    # Change to `let` and it doesn't crash
+    const costTable = [
+      0: Cost(kind: Fixed, cost: 999),
+      1: Cost(kind: Dynamic, handler: foo1),
+      2: Cost(kind: Dynamic, handler: foo2)
+    ]
+
+    doAssert $costTable[0] == "(kind: Fixed, cost: 999)"
+    doAssert costTable[1].handler() == 100
+    doAssert costTable[2].handler() == 200
+
+    # Now trying to carry the table as an object field
+    type
+      Wrapper = object
+        table: array[3, Cost]
+
+    proc procNewWrapper(): Wrapper =
+      result.table = costTable
+
+    # Alternatively, change to `const` and it doesn't crash
+    let viaProc = procNewWrapper()
+
+    doAssert viaProc.table[1].handler != nil
+    doAssert viaProc.table[2].handler != nil
+    doAssert $viaProc.table[0] == "(kind: Fixed, cost: 999)"
+    doAssert viaProc.table[1].handler() == 100
+    doAssert viaProc.table[2].handler() == 200
+
+
+# bug #19198
+
+block:
+  type
+    Foo[n: static int] = int
+
+block:
+  static:
+    let x = int 1
+    doAssert $(x.type) == "int"  # Foo
+
+block:
+  static:
+    let x = int 1
+    let y = x + 1
+    # Error: unhandled exception: value out of range: -8 notin 0 .. 65535 [RangeDefect]
+    doAssert y == 2
+
+
+type Atom* = object
+  bar: int
+
+proc main() = # bug #12994
+  var s: seq[Atom]
+  var atom: Atom
+  var checked = 0
+  for i in 0..<2:
+    atom.bar = 5
+    s.add atom
+    atom.reset
+    if i == 0:
+      checked += 1
+      doAssert $s == "@[(bar: 5)]"
+    else:
+      checked += 1
+      doAssert $s == "@[(bar: 5), (bar: 5)]"
+  doAssert checked == 2
+
+static: main()
+main()
+
+# bug #19201
+proc foo(s: sink string) = doAssert s.len == 3
+
+static:
+  foo("abc")
+
+
+static:
+  for i in '1' .. '2': # bug #10938
+    var s: set[char]
+    doAssert s == {}
+    incl(s, i)
+
+  for _ in 0 ..< 3: # bug #13312
+    var s: string
+    s.add("foo")
+    doAssert s == "foo"
+
+  for i in 1 .. 5: # bug #13918
+    var arr: array[3, int]
+    var val: int
+    doAssert arr == [0, 0, 0] and val == 0
+    for j in 0 ..< len(arr):
+      arr[j] = i
+      val = i
+
+# bug #20985
+let a = block:
+  var groups: seq[seq[int]]
+  for i in 0 ..< 3:
+    var group: seq[int]
+    for j in 0 ..< 3:
+      group.add j
+    groups.add group
+  groups
+
+const b = block:
+  var groups: seq[seq[int]]
+  for i in 0 ..< 3:
+    var group: seq[int]
+    for j in 0 ..< 3:
+      group.add j
+    groups.add group
+  groups
+
+doAssert a == @[@[0, 1, 2], @[0, 1, 2], @[0, 1, 2]]
+doAssert b == @[@[0, 1, 2], @[0, 1, 2], @[0, 1, 2]]
+
+macro m1(s: string): int =
+  var ProcID {.global, compileTime.}: int
+  inc(ProcID)
+  result = newLit(ProcID)
+
+proc macroGlobal =
+  doAssert m1("Macro argument") == 1
+  doAssert m1("Macro argument") == 2
+  doAssert m1("Macro argument") == 3
+
+static: macroGlobal()
+macroGlobal()
+
+block: # bug #10108
+  template reject(x) =
+    static: doAssert(not compiles(x))
+
+  static:
+    let x: int = 2
+    proc deliver_x(): int = x
+    var y2 = deliver_x()
+    discard y2
+    reject:
+      const c5 = deliver_x()
+
+block: # bug #7590
+  proc doInit[T]():auto=
+    var a: T
+    return a
+
+  proc fun2[T](tup1:T)=
+    const tup0=doInit[T]()
+
+    # var tup=tup0 #ok
+    const tup=tup0 #causes bug
+
+    doAssert tup is tuple
+    doAssert tup[0] is tuple
+    for ai in tup.fields:
+      doAssert ai is tuple, "BUG2"
+
+  # const c=(foo:(bar1: 0.0))
+  const c=(foo:(bar1:"foo1"))
+  fun2(c)
+
+block: # bug #21708
+  type
+    Tup = tuple[name: string]
+
+  const X: array[2, Tup] = [(name: "foo",), (name: "bar",)]
+
+  static:
+    let s = X[0]
+    doAssert s[0] == "foo"
+
+block:
+  proc swap[T](x: var T): T =
+    result = x
+    x = default(T)
+
+  proc merge[T](a, b: var openArray[T]) =
+    a[0] = swap b[0]
+
+  static:
+    var x = "abc"
+    var y = "356"
+    merge(x, y)
+    doAssert x == "3bc"
+
+block: # bug #22190
+  type
+    EVMFork = enum
+      Berlin
+      Istanbul
+      Shanghai
+
+  const
+    Vm2OpAllForks =
+      {EVMFork.low .. EVMFork.high}
+
+    vm2OpExecBlockData = [(forks: Vm2OpAllForks)]
+
+  proc mkOpTable(selected: EVMFork): bool =
+    selected notin vm2OpExecBlockData[0].forks
+
+  const
+    tab = mkOpTable(Berlin)
+
+  doAssert not tab
+
+block: # issue #22524
+  const cnst = cstring(nil)
+  doAssert cnst.isNil
+  doAssert cnst == nil
+  let b = cnst
+  doAssert b.isNil
+  doAssert b == nil
+
+  let a = static: cstring(nil)
+  doAssert a.isNil
+
+  static:
+    var x: cstring
+    doAssert x.isNil
+    doAssert x == nil
+    doAssert x != ""
+
+block: # issue #15730
+  const s: cstring = ""
+  doAssert s != nil
+
+  static:
+    let s: cstring = ""
+    doAssert not s.isNil
+    doAssert s != nil
+    doAssert s == ""
+
+static: # more nil cstring issues
+  let x = cstring(nil)
+  doAssert x.len == 0
+
+block: # bug #23925
+  type Foo = enum A = -1
+  proc foo =
+    doAssert cast[Foo](-1) == A
+    doAssert ord(A) == -1
+
+  static: foo()
+  foo()
+
+  type E = enum
+    e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 e10 e11 e12 e13 e14 e15 e16 e17 e18 e19 e20
+    e21 e22 e23 e24 e25 e26 e27 e28 e29 e30 e31 e32 e33 e34 e35 e36 e37 e38
+    e39 e40 e41 e42 e43 e44 e45 e46 e47 e48 e49 e50 e51 e52 e53 e54 e55 e56
+    e57 e58 e59 e60 e61 e62 e63 e64 e65 e66 e67 e68 e69 e70 e71 e72 e73 e74
+    e75 e76 e77 e78 e79 e80 e81 e82 e83 e84 e85 e86 e87 e88 e89 e90 e91 e92
+    e93 e94 e95 e96 e97 e98 e99 e100 e101 e102 e103 e104 e105 e106 e107 e108
+    e109 e110 e111 e112 e113 e114 e115 e116 e117 e118 e119 e120 e121 e122
+    e123 e124 e125 e126 e127 e128
+  proc bar =
+    doAssert cast[E](int(e128)) == e128
+
+  static: bar()
+  bar()
+
+static: # bug #21353
+  var s: proc () = default(proc ())
+  doAssert s == nil
diff --git a/tests/vm/tvmops.nim b/tests/vm/tvmops.nim
new file mode 100644
index 000000000..3d8d5a9ac
--- /dev/null
+++ b/tests/vm/tvmops.nim
@@ -0,0 +1,46 @@
+discard """
+  targets: "c cpp js"
+"""
+
+#[
+test for vmops.nim
+]#
+import os
+import math
+import strutils
+
+static:
+  # TODO: add more tests
+  block: #getAppFilename, gorgeEx, gorge
+    const nim = getCurrentCompilerExe()
+    let ret = gorgeEx(nim & " --version")
+    doAssert ret.exitCode == 0
+    doAssert ret.output.contains "Nim Compiler"
+    let ret2 = gorgeEx(nim & " --nonxistent")
+    doAssert ret2.exitCode != 0
+    let output3 = gorge(nim & " --version")
+    doAssert output3.contains "Nim Compiler"
+
+  block:
+    const key = "D20181210T175037"
+    const val = "foo"
+    putEnv(key, val)
+    doAssert existsEnv(key)
+    doAssert getEnv(key) == val
+
+  block:
+    # sanity check (we probably don't need to test for all ops)
+    const a1 = arcsin 0.3
+    let a2 = arcsin 0.3
+    doAssert a1 == a2
+
+  block bitxor:
+    let x = -1'i32
+    let y = 1'i32
+    doAssert (x xor y) == -2
+
+block:
+  # Check against bugs like #9176
+  doAssert getCurrentCompilerExe() == getCurrentCompilerExe().static
+  if false: #pending #9176
+    doAssert gorgeEx("nonxistent") == gorgeEx("nonxistent").static
diff --git a/tests/vm/tvmopsDanger.nim b/tests/vm/tvmopsDanger.nim
new file mode 100644
index 000000000..966feffe6
--- /dev/null
+++ b/tests/vm/tvmopsDanger.nim
@@ -0,0 +1,13 @@
+discard """
+  cmd: "nim c --experimental:vmopsDanger -r $file"
+"""
+when defined(nimPreviewSlimSystem):
+  import std/assertions
+import std/[times, os]
+
+const foo = getTime()
+let bar = foo
+doAssert bar > low(Time)
+
+static: # bug #23932
+  doAssert getCurrentDir().len > 0
diff --git a/tests/vm/twrong_concat.nim b/tests/vm/twrong_concat.nim
index 538ea2527..59a10bdb9 100644
--- a/tests/vm/twrong_concat.nim
+++ b/tests/vm/twrong_concat.nim
@@ -1,7 +1,3 @@
-discard """
-  output: '''success'''
-"""
-
 # bug #3804
 
 #import sequtils
@@ -23,6 +19,4 @@ static:
   sameBug(objs)
   # sameBug(objs)
   echo objs[0].field
-  assert(objs[0].field == "hello") # fails, because (objs[0].field == "hello bug") - mutated!
-
-echo "success"
+  doAssert(objs[0].field == "hello") # fails, because (objs[0].field == "hello bug") - mutated!
diff --git a/tests/vm/twrongarray.nim b/tests/vm/twrongarray.nim
index c1514d0e9..7f24290e2 100644
--- a/tests/vm/twrongarray.nim
+++ b/tests/vm/twrongarray.nim
@@ -14,4 +14,4 @@ when false:
 
 proc two(dummy: int, size: int) =
   var x: array[size * 1, int] # compiles, but shouldn't?
-  #assert(x.len == size) # just for fun
+  # doAssert(x.len == size) # just for fun
diff --git a/tests/vm/tyaytypedesc.nim b/tests/vm/tyaytypedesc.nim
index a3ad9b707..8cb402bff 100644
--- a/tests/vm/tyaytypedesc.nim
+++ b/tests/vm/tyaytypedesc.nim
@@ -1,7 +1,3 @@
-discard """
-  output: "ntWhitespace"
-"""
-
 # bug #3357
 
 type NodeType* = enum
@@ -10,7 +6,7 @@ type NodeType* = enum
 type TokenType* = enum
   ttWhitespace
 
-proc enumTable*[A, B, C](a: openarray[tuple[key: A, val: B]], ret: typedesc[C]): C =
+proc enumTable*[A, B, C](a: openArray[tuple[key: A, val: B]], ret: typedesc[C]): C =
   for item in a:
     result[item.key] = item.val
 
@@ -18,4 +14,4 @@ const tokenTypeToNodeType = {
   ttWhitespace: ntWhitespace,
 }.enumTable(array[ttWhitespace..ttWhitespace, NodeType])
 
-echo tokenTypeToNodeType[ttWhitespace]
+doAssert tokenTypeToNodeType[ttWhitespace] == ntWhitespace
diff --git a/tests/vm/tzero_extend.nim b/tests/vm/tzero_extend.nim
index a79105531..418dbc486 100644
--- a/tests/vm/tzero_extend.nim
+++ b/tests/vm/tzero_extend.nim
@@ -5,22 +5,22 @@ proc get_values(): (seq[int8], seq[int16], seq[int32]) =
   let i8 = -3'i8
   let i16 = -3'i16
   let i32 = -3'i32
-  doAssert i8.ze == 0xFD
-  doAssert i8.ze64 == 0xFD
-  doAssert i16.ze == 0xFFFD
-  doAssert i16.ze64 == 0xFFFD
+  doAssert int(cast[uint8](i8)) == 0xFD
+  doAssert int64(cast[uint8](i8)) == 0xFD
+  doAssert int(cast[uint16](i16)) == 0xFFFD
+  doAssert int64(cast[uint16](i16)) == 0xFFFD
 
   result[0] = @[]; result[1] = @[]; result[2] = @[]
 
   for offset in RANGE:
-    let i8 = -(1 shl 9) + offset
-    let i16 = -(1 shl 17) + offset
-    let i32 = -(1 shl 33) + offset
+    let i8  = -(1'i64 shl  9) + offset
+    let i16 = -(1'i64 shl 17) + offset
+    let i32 = -(1'i64 shl 33) + offset
 
     # higher bits are masked. these should be exactly equal to offset.
-    result[0].add i8.toU8
-    result[1].add i16.toU16
-    result[2].add i32.toU32
+    result[0].add cast[int8](cast[uint64](i8))
+    result[1].add cast[int16](cast[uint64](i16))
+    result[2].add cast[int32](cast[uint64](i32))
 
 
 # these values this computed by VM