diff -urN a/deps/v8/test/torque/test-torque.tq b/deps/v8/test/torque/test-torque.tq
--- /dev/null
+++ deps/v8/test/torque/test-torque.tq
@@ -0,0 +1,1010 @@
+// Copyright 2018 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+namespace test {
+  macro ElementsKindTestHelper1(kind: constexpr ElementsKind): bool {
+    if constexpr ((kind == UINT8_ELEMENTS) || (kind == UINT16_ELEMENTS)) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  macro ElementsKindTestHelper2(kind: constexpr ElementsKind): constexpr bool {
+    return ((kind == UINT8_ELEMENTS) || (kind == UINT16_ELEMENTS));
+  }
+
+  macro LabelTestHelper1(): never
+      labels Label1 {
+    goto Label1;
+  }
+
+  macro LabelTestHelper2(): never
+      labels Label2(Smi) {
+    goto Label2(42);
+  }
+
+  macro LabelTestHelper3(): never
+      labels Label3(Oddball, Smi) {
+    goto Label3(Null, 7);
+  }
+
+  @export
+  macro TestConstexpr1() {
+    check(FromConstexpr<bool>(IsFastElementsKind(PACKED_SMI_ELEMENTS)));
+  }
+
+  @export
+  macro TestConstexprIf() {
+    check(ElementsKindTestHelper1(UINT8_ELEMENTS));
+    check(ElementsKindTestHelper1(UINT16_ELEMENTS));
+    check(!ElementsKindTestHelper1(UINT32_ELEMENTS));
+  }
+
+  @export
+  macro TestConstexprReturn() {
+    check(FromConstexpr<bool>(ElementsKindTestHelper2(UINT8_ELEMENTS)));
+    check(FromConstexpr<bool>(ElementsKindTestHelper2(UINT16_ELEMENTS)));
+    check(!FromConstexpr<bool>(ElementsKindTestHelper2(UINT32_ELEMENTS)));
+    check(FromConstexpr<bool>(!ElementsKindTestHelper2(UINT32_ELEMENTS)));
+  }
+
+  @export
+  macro TestGotoLabel(): Boolean {
+    try {
+      LabelTestHelper1() otherwise Label1;
+    }
+    label Label1 {
+      return True;
+    }
+  }
+
+  @export
+  macro TestGotoLabelWithOneParameter(): Boolean {
+    try {
+      LabelTestHelper2() otherwise Label2;
+    }
+    label Label2(smi: Smi) {
+      check(smi == 42);
+      return True;
+    }
+  }
+
+  @export
+  macro TestGotoLabelWithTwoParameters(): Boolean {
+    try {
+      LabelTestHelper3() otherwise Label3;
+    }
+    label Label3(o: Oddball, smi: Smi) {
+      check(o == Null);
+      check(smi == 7);
+      return True;
+    }
+  }
+
+  builtin GenericBuiltinTest<T: type>(_c: Context, _param: T): Object {
+    return Null;
+  }
+
+  GenericBuiltinTest<Object>(_c: Context, param: Object): Object {
+    return param;
+  }
+
+  @export
+  macro TestBuiltinSpecialization(c: Context) {
+    check(GenericBuiltinTest<Smi>(c, 0) == Null);
+    check(GenericBuiltinTest<Smi>(c, 1) == Null);
+    check(GenericBuiltinTest<Object>(c, Undefined) == Undefined);
+    check(GenericBuiltinTest<Object>(c, Undefined) == Undefined);
+  }
+
+  macro LabelTestHelper4(flag: constexpr bool): never
+      labels Label4, Label5 {
+    if constexpr (flag) {
+      goto Label4;
+    } else {
+      goto Label5;
+    }
+  }
+
+  macro CallLabelTestHelper4(flag: constexpr bool): bool {
+    try {
+      LabelTestHelper4(flag) otherwise Label4, Label5;
+    }
+    label Label4 {
+      return true;
+    }
+    label Label5 {
+      return false;
+    }
+  }
+
+  @export
+  macro TestPartiallyUnusedLabel(): Boolean {
+    const r1: bool = CallLabelTestHelper4(true);
+    const r2: bool = CallLabelTestHelper4(false);
+
+    if (r1 && !r2) {
+      return True;
+    } else {
+      return False;
+    }
+  }
+
+  macro GenericMacroTest<T: type>(_param: T): Object {
+    return Undefined;
+  }
+
+  GenericMacroTest<Object>(param2: Object): Object {
+    return param2;
+  }
+
+  macro GenericMacroTestWithLabels<T: type>(_param: T): Object
+  labels _X {
+    return Undefined;
+  }
+
+  GenericMacroTestWithLabels<Object>(param2: Object): Object
+      labels Y {
+    return Cast<Smi>(param2) otherwise Y;
+  }
+
+  @export
+  macro TestMacroSpecialization() {
+    try {
+      const _smi0: Smi = 0;
+      check(GenericMacroTest<Smi>(0) == Undefined);
+      check(GenericMacroTest<Smi>(1) == Undefined);
+      check(GenericMacroTest<Object>(Null) == Null);
+      check(GenericMacroTest<Object>(False) == False);
+      check(GenericMacroTest<Object>(True) == True);
+      check((GenericMacroTestWithLabels<Smi>(0) otherwise Fail) == Undefined);
+      check((GenericMacroTestWithLabels<Smi>(0) otherwise Fail) == Undefined);
+      try {
+        GenericMacroTestWithLabels<Object>(False) otherwise Expected;
+      }
+      label Expected {}
+    }
+    label Fail {
+      unreachable;
+    }
+  }
+
+  builtin TestHelperPlus1(_context: Context, x: Smi): Smi {
+    return x + 1;
+  }
+  builtin TestHelperPlus2(_context: Context, x: Smi): Smi {
+    return x + 2;
+  }
+
+  @export
+  macro TestFunctionPointers(implicit context: Context)(): Boolean {
+    let fptr: builtin(Context, Smi) => Smi = TestHelperPlus1;
+    check(fptr(context, 42) == 43);
+    fptr = TestHelperPlus2;
+    check(fptr(context, 42) == 44);
+    return True;
+  }
+
+  @export
+  macro TestVariableRedeclaration(implicit context: Context)(): Boolean {
+    let _var1: int31 = FromConstexpr<bool>(42 == 0) ? 0 : 1;
+    let _var2: int31 = FromConstexpr<bool>(42 == 0) ? 1 : 0;
+    return True;
+  }
+
+  @export
+  macro TestTernaryOperator(x: Smi): Smi {
+    const b: bool = x < 0 ? true : false;
+    return b ? x - 10 : x + 100;
+  }
+
+  @export
+  macro TestFunctionPointerToGeneric(c: Context) {
+    const fptr1: builtin(Context, Smi) => Object = GenericBuiltinTest<Smi>;
+    const fptr2: builtin(Context, Object) => Object =
+        GenericBuiltinTest<Object>;
+
+    check(fptr1(c, 0) == Null);
+    check(fptr1(c, 1) == Null);
+    check(fptr2(c, Undefined) == Undefined);
+    check(fptr2(c, Undefined) == Undefined);
+  }
+
+  type ObjectToObject = builtin(Context, Object) => Object;
+  @export
+  macro TestTypeAlias(x: ObjectToObject): BuiltinPtr {
+    return x;
+  }
+
+  @export
+  macro TestUnsafeCast(implicit context: Context)(n: Number): Boolean {
+    if (TaggedIsSmi(n)) {
+      const m: Smi = UnsafeCast<Smi>(n);
+
+      check(TestHelperPlus1(context, m) == 11);
+      return True;
+    }
+    return False;
+  }
+
+  @export
+  macro TestHexLiteral() {
+    check(Convert<intptr>(0xffff) + 1 == 0x10000);
+    check(Convert<intptr>(-0xffff) == -65535);
+  }
+
+  @export
+  macro TestLargeIntegerLiterals(implicit c: Context)() {
+    let _x: int32 = 0x40000000;
+    let _y: int32 = 0x7fffffff;
+  }
+
+  @export
+  macro TestMultilineAssert() {
+    const someVeryLongVariableNameThatWillCauseLineBreaks: Smi = 5;
+    check(
+        someVeryLongVariableNameThatWillCauseLineBreaks > 0 &&
+        someVeryLongVariableNameThatWillCauseLineBreaks < 10);
+  }
+
+  @export
+  macro TestNewlineInString() {
+    Print('Hello, World!\n');
+  }
+
+  const kConstexprConst: constexpr int31 = 5;
+  const kIntptrConst: intptr = 4;
+  const kSmiConst: Smi = 3;
+
+  @export
+  macro TestModuleConstBindings() {
+    check(kConstexprConst == Int32Constant(5));
+    check(kIntptrConst == 4);
+    check(kSmiConst == 3);
+  }
+
+  @export
+  macro TestLocalConstBindings() {
+    const x: constexpr int31 = 3;
+    const xSmi: Smi = x;
+    {
+      const x: Smi = x + FromConstexpr<Smi>(1);
+      check(x == xSmi + 1);
+      const xSmi: Smi = x;
+      check(x == xSmi);
+      check(x == 4);
+    }
+    check(xSmi == 3);
+    check(x == xSmi);
+  }
+
+  struct TestStructA {
+    indexes: FixedArray;
+    i: Smi;
+    k: Number;
+  }
+
+  struct TestStructB {
+    x: TestStructA;
+    y: Smi;
+  }
+
+  @export
+  macro TestStruct1(i: TestStructA): Smi {
+    return i.i;
+  }
+
+  @export
+  macro TestStruct2(implicit context: Context)(): TestStructA {
+    return TestStructA{
+      indexes: UnsafeCast<FixedArray>(kEmptyFixedArray),
+      i: 27,
+      k: 31
+    };
+  }
+
+  @export
+  macro TestStruct3(implicit context: Context)(): TestStructA {
+    let a: TestStructA =
+    TestStructA{indexes: UnsafeCast<FixedArray>(kEmptyFixedArray), i: 13, k: 5};
+    let _b: TestStructA = a;
+    const c: TestStructA = TestStruct2();
+    a.i = TestStruct1(c);
+    a.k = a.i;
+    let d: TestStructB;
+    d.x = a;
+    d = TestStructB{x: a, y: 7};
+    let _e: TestStructA = d.x;
+    let f: Smi = TestStructA{
+      indexes: UnsafeCast<FixedArray>(kEmptyFixedArray),
+      i: 27,
+      k: 31
+    }.i;
+    f = TestStruct2().i;
+    return a;
+  }
+
+  struct TestStructC {
+    x: TestStructA;
+    y: TestStructA;
+  }
+
+  @export
+  macro TestStruct4(implicit context: Context)(): TestStructC {
+    return TestStructC{x: TestStruct2(), y: TestStruct2()};
+  }
+
+  macro TestStructInLabel(implicit context: Context)(): never labels
+  Foo(TestStructA) {
+    goto Foo(TestStruct2());
+  }
+  @export  // Silence unused warning.
+  macro CallTestStructInLabel(implicit context: Context)() {
+    try {
+      TestStructInLabel() otherwise Foo;
+    }
+    label Foo(_s: TestStructA) {}
+  }
+
+  // This macro tests different versions of the for-loop where some parts
+  // are (not) present.
+  @export
+  macro TestForLoop() {
+    let sum: Smi = 0;
+    for (let i: Smi = 0; i < 5; ++i) sum += i;
+    check(sum == 10);
+
+    sum = 0;
+    let j: Smi = 0;
+    for (; j < 5; ++j) sum += j;
+    check(sum == 10);
+
+    sum = 0;
+    j = 0;
+    for (; j < 5;) sum += j++;
+    check(sum == 10);
+
+    // Check that break works. No test expression.
+    sum = 0;
+    for (let i: Smi = 0;; ++i) {
+      if (i == 5) break;
+      sum += i;
+    }
+    check(sum == 10);
+
+    sum = 0;
+    j = 0;
+    for (;;) {
+      if (j == 5) break;
+      sum += j;
+      j++;
+    }
+    check(sum == 10);
+
+    // The following tests are the same as above, but use continue to skip
+    // index 3.
+    sum = 0;
+    for (let i: Smi = 0; i < 5; ++i) {
+      if (i == 3) continue;
+      sum += i;
+    }
+    check(sum == 7);
+
+    sum = 0;
+    j = 0;
+    for (; j < 5; ++j) {
+      if (j == 3) continue;
+      sum += j;
+    }
+    check(sum == 7);
+
+    sum = 0;
+    j = 0;
+    for (; j < 5;) {
+      if (j == 3) {
+        j++;
+        continue;
+      }
+      sum += j;
+      j++;
+    }
+    check(sum == 7);
+
+    sum = 0;
+    for (let i: Smi = 0;; ++i) {
+      if (i == 3) continue;
+      if (i == 5) break;
+      sum += i;
+    }
+    check(sum == 7);
+
+    sum = 0;
+    j = 0;
+    for (;;) {
+      if (j == 3) {
+        j++;
+        continue;
+      }
+
+      if (j == 5) break;
+      sum += j;
+      j++;
+    }
+    check(sum == 7);
+
+    j = 0;
+    try {
+      for (;;) {
+        if (++j == 10) goto Exit;
+      }
+    }
+    label Exit {
+      check(j == 10);
+    }
+
+    // Test if we can handle uninitialized values on the stack.
+    let _i: Smi;
+    for (let j: Smi = 0; j < 10; ++j) {
+    }
+  }
+
+  @export
+  macro TestSubtyping(x: Smi) {
+    const _foo: Object = x;
+  }
+
+  macro IncrementIfSmi<A: type>(x: A): A {
+    typeswitch (x) {
+      case (x: Smi): {
+        return x + 1;
+      }
+      case (o: A): {
+        return o;
+      }
+    }
+  }
+
+  type NumberOrFixedArray = Number | FixedArray;
+  macro TypeswitchExample(implicit context: Context)(x: NumberOrFixedArray):
+      int32 {
+    let result: int32 = 0;
+    typeswitch (IncrementIfSmi(x)) {
+      case (_x: FixedArray): {
+        result = result + 1;
+      }
+      case (Number): {
+        result = result + 2;
+      }
+    }
+
+    result = result * 10;
+
+    typeswitch (IncrementIfSmi(x)) {
+      case (x: Smi): {
+        result = result + Convert<int32>(x);
+      }
+      case (a: FixedArray): {
+        result = result + Convert<int32>(a.length);
+      }
+      case (_x: HeapNumber): {
+        result = result + 7;
+      }
+    }
+
+    return result;
+  }
+
+  @export
+  macro TestTypeswitch(implicit context: Context)() {
+    check(TypeswitchExample(FromConstexpr<Smi>(5)) == 26);
+    const a: FixedArray = AllocateZeroedFixedArray(3);
+    check(TypeswitchExample(a) == 13);
+    check(TypeswitchExample(FromConstexpr<Number>(0.5)) == 27);
+  }
+
+  @export
+  macro TestTypeswitchAsanLsanFailure(implicit context: Context)(obj: Object) {
+    typeswitch (obj) {
+      case (_o: Smi): {
+      }
+      case (_o: JSTypedArray): {
+      }
+      case (_o: JSReceiver): {
+      }
+      case (_o: HeapObject): {
+      }
+    }
+  }
+
+  macro ExampleGenericOverload<A: type>(o: Object): A {
+    return o;
+  }
+  macro ExampleGenericOverload<A: type>(o: Smi): A {
+    return o + 1;
+  }
+
+  @export
+  macro TestGenericOverload(implicit context: Context)() {
+    const xSmi: Smi = 5;
+    const xObject: Object = xSmi;
+    check(ExampleGenericOverload<Smi>(xSmi) == 6);
+    check(UnsafeCast<Smi>(ExampleGenericOverload<Object>(xObject)) == 5);
+  }
+
+  @export
+  macro TestEquality(implicit context: Context)() {
+    const notEqual: bool =
+        AllocateHeapNumberWithValue(0.5) != AllocateHeapNumberWithValue(0.5);
+    check(!notEqual);
+    const equal: bool =
+        AllocateHeapNumberWithValue(0.5) == AllocateHeapNumberWithValue(0.5);
+    check(equal);
+  }
+
+  macro BoolToBranch(x: bool): never
+      labels Taken, NotTaken {
+    if (x) {
+      goto Taken;
+    } else {
+      goto NotTaken;
+    }
+  }
+
+  @export
+  macro TestOrAnd1(x: bool, y: bool, z: bool): bool {
+    return BoolToBranch(x) || y && z ? true : false;
+  }
+
+  @export
+  macro TestOrAnd2(x: bool, y: bool, z: bool): bool {
+    return x || BoolToBranch(y) && z ? true : false;
+  }
+
+  @export
+  macro TestOrAnd3(x: bool, y: bool, z: bool): bool {
+    return x || y && BoolToBranch(z) ? true : false;
+  }
+
+  @export
+  macro TestAndOr1(x: bool, y: bool, z: bool): bool {
+    return BoolToBranch(x) && y || z ? true : false;
+  }
+
+  @export
+  macro TestAndOr2(x: bool, y: bool, z: bool): bool {
+    return x && BoolToBranch(y) || z ? true : false;
+  }
+
+  @export
+  macro TestAndOr3(x: bool, y: bool, z: bool): bool {
+    return x && y || BoolToBranch(z) ? true : false;
+  }
+
+  @export
+  macro TestLogicalOperators() {
+    check(TestAndOr1(true, true, true));
+    check(TestAndOr2(true, true, true));
+    check(TestAndOr3(true, true, true));
+    check(TestAndOr1(true, true, false));
+    check(TestAndOr2(true, true, false));
+    check(TestAndOr3(true, true, false));
+    check(TestAndOr1(true, false, true));
+    check(TestAndOr2(true, false, true));
+    check(TestAndOr3(true, false, true));
+    check(!TestAndOr1(true, false, false));
+    check(!TestAndOr2(true, false, false));
+    check(!TestAndOr3(true, false, false));
+    check(TestAndOr1(false, true, true));
+    check(TestAndOr2(false, true, true));
+    check(TestAndOr3(false, true, true));
+    check(!TestAndOr1(false, true, false));
+    check(!TestAndOr2(false, true, false));
+    check(!TestAndOr3(false, true, false));
+    check(TestAndOr1(false, false, true));
+    check(TestAndOr2(false, false, true));
+    check(TestAndOr3(false, false, true));
+    check(!TestAndOr1(false, false, false));
+    check(!TestAndOr2(false, false, false));
+    check(!TestAndOr3(false, false, false));
+    check(TestOrAnd1(true, true, true));
+    check(TestOrAnd2(true, true, true));
+    check(TestOrAnd3(true, true, true));
+    check(TestOrAnd1(true, true, false));
+    check(TestOrAnd2(true, true, false));
+    check(TestOrAnd3(true, true, false));
+    check(TestOrAnd1(true, false, true));
+    check(TestOrAnd2(true, false, true));
+    check(TestOrAnd3(true, false, true));
+    check(TestOrAnd1(true, false, false));
+    check(TestOrAnd2(true, false, false));
+    check(TestOrAnd3(true, false, false));
+    check(TestOrAnd1(false, true, true));
+    check(TestOrAnd2(false, true, true));
+    check(TestOrAnd3(false, true, true));
+    check(!TestOrAnd1(false, true, false));
+    check(!TestOrAnd2(false, true, false));
+    check(!TestOrAnd3(false, true, false));
+    check(!TestOrAnd1(false, false, true));
+    check(!TestOrAnd2(false, false, true));
+    check(!TestOrAnd3(false, false, true));
+    check(!TestOrAnd1(false, false, false));
+    check(!TestOrAnd2(false, false, false));
+    check(!TestOrAnd3(false, false, false));
+  }
+
+  @export
+  macro TestCall(i: Smi): Smi labels A {
+    if (i < 5) return i;
+    goto A;
+  }
+
+  @export
+  macro TestOtherwiseWithCode1() {
+    let v: Smi = 0;
+    let s: Smi = 1;
+    try {
+      TestCall(10) otherwise goto B(++s);
+    }
+    label B(v1: Smi) {
+      v = v1;
+    }
+    assert(v == 2);
+  }
+
+  @export
+  macro TestOtherwiseWithCode2() {
+    let s: Smi = 0;
+    for (let i: Smi = 0; i < 10; ++i) {
+      TestCall(i) otherwise break;
+      ++s;
+    }
+    assert(s == 5);
+  }
+
+  @export
+  macro TestOtherwiseWithCode3() {
+    let s: Smi = 0;
+    for (let i: Smi = 0; i < 10; ++i) {
+      s += TestCall(i) otherwise break;
+    }
+    assert(s == 10);
+  }
+
+  @export
+  macro TestForwardLabel() {
+    try {
+      goto A;
+    }
+    label A {
+      goto B(5);
+    }
+    label B(b: Smi) {
+      assert(b == 5);
+    }
+  }
+
+  @export
+  macro TestQualifiedAccess(implicit context: Context)() {
+    const s: Smi = 0;
+    check(!array::IsJSArray(s));
+  }
+
+  @export
+  macro TestCatch1(implicit context: Context)(): Smi {
+    let r: Smi = 0;
+    try {
+      ThrowTypeError(kInvalidArrayLength);
+    } catch (_e) {
+      r = 1;
+      return r;
+    }
+  }
+
+  @export
+  macro TestCatch2Wrapper(implicit context: Context)(): never {
+    ThrowTypeError(kInvalidArrayLength);
+  }
+
+  @export
+  macro TestCatch2(implicit context: Context)(): Smi {
+    let r: Smi = 0;
+    try {
+      TestCatch2Wrapper();
+    } catch (_e) {
+      r = 2;
+      return r;
+    }
+  }
+
+  @export
+  macro TestCatch3WrapperWithLabel(implicit context: Context)():
+      never labels _Abort {
+    ThrowTypeError(kInvalidArrayLength);
+  }
+
+  @export
+  macro TestCatch3(implicit context: Context)(): Smi {
+    let r: Smi = 0;
+    try {
+      TestCatch3WrapperWithLabel() otherwise Abort;
+    }
+    label Abort {
+      return -1;
+    }
+    catch (_e) {
+      r = 2;
+      return r;
+    }
+  }
+
+  // This test doesn't actually test the functionality of iterators,
+  // it's only purpose is to make sure tha the CSA macros in the
+  // IteratorBuiltinsAssembler match the signatures provided in
+  // iterator.tq.
+  @export
+  macro TestIterator(implicit context: Context)(o: JSReceiver, map: Map) {
+    try {
+      const t1: Object = iterator::GetIteratorMethod(o);
+      const t2: iterator::IteratorRecord = iterator::GetIterator(o);
+
+      const _t3: Object = iterator::IteratorStep(t2) otherwise Fail;
+      const _t4: Object = iterator::IteratorStep(t2, map) otherwise Fail;
+
+      const t5: Object = iterator::IteratorValue(o);
+      const _t6: Object = iterator::IteratorValue(o, map);
+
+      const _t7: JSArray = iterator::IterableToList(t1, t1);
+
+      iterator::IteratorCloseOnException(t2, t5);
+    }
+    label Fail {}
+  }
+
+  @export
+  macro TestFrame1(implicit context: Context)() {
+    const f: Frame = LoadFramePointer();
+    const frameType: FrameType =
+        Cast<FrameType>(f.context_or_frame_type) otherwise unreachable;
+    assert(frameType == STUB_FRAME);
+    assert(f.caller == LoadParentFramePointer());
+    typeswitch (f) {
+      case (_f: StandardFrame): {
+        unreachable;
+      }
+      case (_f: ArgumentsAdaptorFrame): {
+        unreachable;
+      }
+      case (_f: StubFrame): {
+      }
+    }
+  }
+
+  @export
+  macro TestNew(implicit context: Context)() {
+    const f: JSArray = NewJSArray();
+    check(f.IsEmpty());
+    f.length = 0;
+  }
+
+  struct TestInner {
+    SetX(newValue: int32) {
+      this.x = newValue;
+    }
+    GetX(): int32 {
+      return this.x;
+    }
+    x: int32;
+    y: int32;
+  }
+
+  struct TestOuter {
+    a: int32;
+    b: TestInner;
+    c: int32;
+  }
+
+  @export
+  macro TestStructConstructor(implicit context: Context)() {
+    // Test default constructor
+    let a: TestOuter = TestOuter{a: 5, b: TestInner{x: 6, y: 7}, c: 8};
+    check(a.a == 5);
+    check(a.b.x == 6);
+    check(a.b.y == 7);
+    check(a.c == 8);
+    a.b.x = 1;
+    check(a.b.x == 1);
+    a.b.SetX(2);
+    check(a.b.x == 2);
+    check(a.b.GetX() == 2);
+  }
+
+  class InternalClass extends Struct {
+    Flip() labels NotASmi {
+      const tmp = Cast<Smi>(this.b) otherwise NotASmi;
+      this.b = this.a;
+      this.a = tmp;
+    }
+    a: Smi;
+    b: Number;
+  }
+
+  macro NewInternalClass(x: Smi): InternalClass {
+    return new InternalClass{a: x, b: x + 1};
+  }
+
+  @export
+  macro TestInternalClass(implicit context: Context)() {
+    const o = NewInternalClass(5);
+    o.Flip() otherwise unreachable;
+    check(o.a == 6);
+    check(o.b == 5);
+  }
+
+  struct StructWithConst {
+    TestMethod1(): int32 {
+      return this.b;
+    }
+    TestMethod2(): Object {
+      return this.a;
+    }
+    a: Object;
+    const b: int32;
+  }
+
+  @export
+  macro TestConstInStructs() {
+    const x = StructWithConst{a: Null, b: 1};
+    let y = StructWithConst{a: Null, b: 1};
+    y.a = Undefined;
+    const _copy = x;
+
+    check(x.TestMethod1() == 1);
+    check(x.TestMethod2() == Null);
+  }
+
+  struct TestIterator {
+    Next(): Object labels NoMore {
+      if (this.count-- == 0) goto NoMore;
+      return TheHole;
+    }
+    count: Smi;
+  }
+
+  @export
+  macro TestNewFixedArrayFromSpread(implicit context: Context)(): Object {
+    let i = TestIterator{count: 5};
+    return new FixedArray{map: kFixedArrayMap, length: 5, objects: ...i};
+  }
+
+  class SmiPair extends Struct {
+    GetA():&Smi {
+      return & this.a;
+    }
+    a: Smi;
+    b: Smi;
+  }
+
+  macro Swap<T: type>(a:&T, b:&T) {
+    const tmp = * a;
+    * a = * b;
+    * b = tmp;
+  }
+
+  @export
+  macro TestReferences() {
+    const array = new SmiPair{a: 7, b: 2};
+    const ref:&Smi = & array.a;
+    * ref = 3 + * ref;
+    -- * ref;
+    Swap(& array.b, array.GetA());
+    check(array.a == 2);
+    check(array.b == 9);
+  }
+
+  @export
+  macro TestStaticAssert() {
+    StaticAssert(1 + 2 == 3);
+  }
+
+  class SmiBox extends Struct {
+    value: Smi;
+    unrelated: Smi;
+  }
+
+  builtin NewSmiBox(implicit context: Context)(value: Smi): SmiBox {
+    return new SmiBox{value, unrelated: 0};
+  }
+
+  @export
+  macro TestLoadEliminationFixed(implicit context: Context)() {
+    const box = NewSmiBox(123);
+    const v1 = box.value;
+    box.unrelated = 999;
+    const v2 = (box.unrelated == 0) ? box.value : box.value;
+    StaticAssert(WordEqual(v1, v2));
+
+    box.value = 11;
+    const v3 = box.value;
+    const eleven: Smi = 11;
+    StaticAssert(WordEqual(v3, eleven));
+  }
+
+  @export
+  macro TestLoadEliminationVariable(implicit context: Context)() {
+    const a = UnsafeCast<FixedArray>(kEmptyFixedArray);
+    const box = NewSmiBox(1);
+    const v1 = a.objects[box.value];
+    const u1 = a.objects[box.value + 2];
+    const v2 = a.objects[box.value];
+    const u2 = a.objects[box.value + 2];
+    StaticAssert(WordEqual(v1, v2));
+    StaticAssert(WordEqual(u1, u2));
+  }
+
+  @export
+  macro TestRedundantArrayElementCheck(implicit context: Context)(): Smi {
+    const a = kEmptyFixedArray;
+    for (let i: Smi = 0; i < a.length; i++) {
+      if (a.objects[i] == TheHole) {
+        if (a.objects[i] == TheHole) {
+          return -1;
+        } else {
+          StaticAssert(false);
+        }
+      }
+    }
+    return 1;
+  }
+
+  @export
+  macro TestRedundantSmiCheck(implicit context: Context)(): Smi {
+    const a = kEmptyFixedArray;
+    const x = a.objects[1];
+    typeswitch (x) {
+      case (Smi): {
+        Cast<Smi>(x) otherwise VerifiedUnreachable();
+        return -1;
+      }
+      case (Object): {
+      }
+    }
+    return 1;
+  }
+
+  struct SBox<T: type> {
+    value: T;
+  }
+
+  @export
+  macro TestGenericStruct1(): intptr {
+    const i: intptr = 123;
+    let box = SBox<intptr>{value: i};
+    let boxbox = SBox<SBox<intptr>>{value: box};
+    check(box.value == 123);
+    boxbox.value.value *= 2;
+    check(boxbox.value.value == 246);
+    return boxbox.value.value;
+  }
+
+  struct TestTuple<T1: type, T2: type> {
+    const fst: T1;
+    const snd: T2;
+  }
+
+  macro Swap<T1: type, T2: type>(tuple: TestTuple<T1, T2>):
+      TestTuple<T2, T1> {
+    return TestTuple<T2, T1>{fst: tuple.snd, snd: tuple.fst};
+  }
+
+  @export
+  macro TestGenericStruct2(): TestTuple<Smi, intptr> {
+    const intptrAndSmi = TestTuple<intptr, Smi>{fst: 1, snd: 2};
+    const smiAndIntptr = Swap<intptr, Smi>(intptrAndSmi);
+    check(intptrAndSmi.fst == smiAndIntptr.snd);
+    check(intptrAndSmi.snd == smiAndIntptr.fst);
+    return smiAndIntptr;
+  }
+
+}