11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci// Test line comment
61cb0ef41Sopenharmony_ci/* Test mulitline
71cb0ef41Sopenharmony_ci   comment
81cb0ef41Sopenharmony_ci*/
91cb0ef41Sopenharmony_ci/*multiline_without_whitespace*/
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_cinamespace test {
121cb0ef41Sopenharmony_cimacro ElementsKindTestHelper1(kind: constexpr ElementsKind): bool {
131cb0ef41Sopenharmony_ci  if constexpr (
141cb0ef41Sopenharmony_ci      kind == ElementsKind::UINT8_ELEMENTS ||
151cb0ef41Sopenharmony_ci      kind == ElementsKind::UINT16_ELEMENTS) {
161cb0ef41Sopenharmony_ci    return true;
171cb0ef41Sopenharmony_ci  } else {
181cb0ef41Sopenharmony_ci    return false;
191cb0ef41Sopenharmony_ci  }
201cb0ef41Sopenharmony_ci}
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_cimacro ElementsKindTestHelper2(kind: constexpr ElementsKind): constexpr bool {
231cb0ef41Sopenharmony_ci  return kind == ElementsKind::UINT8_ELEMENTS ||
241cb0ef41Sopenharmony_ci      kind == ElementsKind::UINT16_ELEMENTS;
251cb0ef41Sopenharmony_ci}
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_cimacro LabelTestHelper1(): never
281cb0ef41Sopenharmony_ci    labels Label1 {
291cb0ef41Sopenharmony_ci  goto Label1;
301cb0ef41Sopenharmony_ci}
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_cimacro LabelTestHelper2(): never
331cb0ef41Sopenharmony_ci    labels Label2(Smi) {
341cb0ef41Sopenharmony_ci  goto Label2(42);
351cb0ef41Sopenharmony_ci}
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_cimacro LabelTestHelper3(): never
381cb0ef41Sopenharmony_ci    labels Label3(Oddball, Smi) {
391cb0ef41Sopenharmony_ci  goto Label3(Null, 7);
401cb0ef41Sopenharmony_ci}
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci@export
431cb0ef41Sopenharmony_cimacro TestConstexpr1(): void {
441cb0ef41Sopenharmony_ci  check(FromConstexpr<bool>(
451cb0ef41Sopenharmony_ci      IsFastElementsKind(ElementsKind::PACKED_SMI_ELEMENTS)));
461cb0ef41Sopenharmony_ci}
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci@export
491cb0ef41Sopenharmony_cimacro TestConstexprIf(): void {
501cb0ef41Sopenharmony_ci  check(ElementsKindTestHelper1(ElementsKind::UINT8_ELEMENTS));
511cb0ef41Sopenharmony_ci  check(ElementsKindTestHelper1(ElementsKind::UINT16_ELEMENTS));
521cb0ef41Sopenharmony_ci  check(!ElementsKindTestHelper1(ElementsKind::UINT32_ELEMENTS));
531cb0ef41Sopenharmony_ci}
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci@export
561cb0ef41Sopenharmony_cimacro TestConstexprReturn(): void {
571cb0ef41Sopenharmony_ci  check(FromConstexpr<bool>(
581cb0ef41Sopenharmony_ci      ElementsKindTestHelper2(ElementsKind::UINT8_ELEMENTS)));
591cb0ef41Sopenharmony_ci  check(FromConstexpr<bool>(
601cb0ef41Sopenharmony_ci      ElementsKindTestHelper2(ElementsKind::UINT16_ELEMENTS)));
611cb0ef41Sopenharmony_ci  check(!FromConstexpr<bool>(
621cb0ef41Sopenharmony_ci      ElementsKindTestHelper2(ElementsKind::UINT32_ELEMENTS)));
631cb0ef41Sopenharmony_ci  check(FromConstexpr<bool>(
641cb0ef41Sopenharmony_ci      !ElementsKindTestHelper2(ElementsKind::UINT32_ELEMENTS)));
651cb0ef41Sopenharmony_ci}
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci@export
681cb0ef41Sopenharmony_cimacro TestGotoLabel(): Boolean {
691cb0ef41Sopenharmony_ci  try {
701cb0ef41Sopenharmony_ci    LabelTestHelper1() otherwise Label1;
711cb0ef41Sopenharmony_ci  } label Label1 {
721cb0ef41Sopenharmony_ci    return True;
731cb0ef41Sopenharmony_ci  }
741cb0ef41Sopenharmony_ci}
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci@export
771cb0ef41Sopenharmony_cimacro TestGotoLabelWithOneParameter(): Boolean {
781cb0ef41Sopenharmony_ci  try {
791cb0ef41Sopenharmony_ci    LabelTestHelper2() otherwise Label2;
801cb0ef41Sopenharmony_ci  } label Label2(smi: Smi) {
811cb0ef41Sopenharmony_ci    check(smi == 42);
821cb0ef41Sopenharmony_ci    return True;
831cb0ef41Sopenharmony_ci  }
841cb0ef41Sopenharmony_ci}
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci@export
871cb0ef41Sopenharmony_cimacro TestGotoLabelWithTwoParameters(): Boolean {
881cb0ef41Sopenharmony_ci  try {
891cb0ef41Sopenharmony_ci    LabelTestHelper3() otherwise Label3;
901cb0ef41Sopenharmony_ci  } label Label3(o: Oddball, smi: Smi) {
911cb0ef41Sopenharmony_ci    check(o == Null);
921cb0ef41Sopenharmony_ci    check(smi == 7);
931cb0ef41Sopenharmony_ci    return True;
941cb0ef41Sopenharmony_ci  }
951cb0ef41Sopenharmony_ci}
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_cibuiltin GenericBuiltinTest<T: type>(_param: T): JSAny {
981cb0ef41Sopenharmony_ci  return Null;
991cb0ef41Sopenharmony_ci}
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ciGenericBuiltinTest<JSAny>(param: JSAny): JSAny {
1021cb0ef41Sopenharmony_ci  return param;
1031cb0ef41Sopenharmony_ci}
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci@export
1061cb0ef41Sopenharmony_cimacro TestBuiltinSpecialization(): void {
1071cb0ef41Sopenharmony_ci  check(GenericBuiltinTest<Smi>(0) == Null);
1081cb0ef41Sopenharmony_ci  check(GenericBuiltinTest<Smi>(1) == Null);
1091cb0ef41Sopenharmony_ci  check(GenericBuiltinTest<JSAny>(Undefined) == Undefined);
1101cb0ef41Sopenharmony_ci  check(GenericBuiltinTest<JSAny>(Undefined) == Undefined);
1111cb0ef41Sopenharmony_ci}
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_cimacro LabelTestHelper4(flag: constexpr bool): never
1141cb0ef41Sopenharmony_ci    labels Label4, Label5 {
1151cb0ef41Sopenharmony_ci  if constexpr (flag) {
1161cb0ef41Sopenharmony_ci    goto Label4;
1171cb0ef41Sopenharmony_ci  } else {
1181cb0ef41Sopenharmony_ci    goto Label5;
1191cb0ef41Sopenharmony_ci  }
1201cb0ef41Sopenharmony_ci}
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_cimacro CallLabelTestHelper4(flag: constexpr bool): bool {
1231cb0ef41Sopenharmony_ci  try {
1241cb0ef41Sopenharmony_ci    LabelTestHelper4(flag) otherwise Label4, Label5;
1251cb0ef41Sopenharmony_ci  } label Label4 {
1261cb0ef41Sopenharmony_ci    return true;
1271cb0ef41Sopenharmony_ci  } label Label5 {
1281cb0ef41Sopenharmony_ci    return false;
1291cb0ef41Sopenharmony_ci  }
1301cb0ef41Sopenharmony_ci}
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci@export
1331cb0ef41Sopenharmony_cimacro TestPartiallyUnusedLabel(): Boolean {
1341cb0ef41Sopenharmony_ci  const r1: bool = CallLabelTestHelper4(true);
1351cb0ef41Sopenharmony_ci  const r2: bool = CallLabelTestHelper4(false);
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci  if (r1 && !r2) {
1381cb0ef41Sopenharmony_ci    return True;
1391cb0ef41Sopenharmony_ci  } else {
1401cb0ef41Sopenharmony_ci    return False;
1411cb0ef41Sopenharmony_ci  }
1421cb0ef41Sopenharmony_ci}
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_cimacro GenericMacroTest<T: type>(_param: T): Object {
1451cb0ef41Sopenharmony_ci  return Undefined;
1461cb0ef41Sopenharmony_ci}
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ciGenericMacroTest<Object>(param2: Object): Object {
1491cb0ef41Sopenharmony_ci  return param2;
1501cb0ef41Sopenharmony_ci}
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_cimacro GenericMacroTestWithLabels<T: type>(_param: T): Object
1531cb0ef41Sopenharmony_cilabels _X {
1541cb0ef41Sopenharmony_ci  return Undefined;
1551cb0ef41Sopenharmony_ci}
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_ciGenericMacroTestWithLabels<Object>(param2: Object): Object
1581cb0ef41Sopenharmony_ci    labels Y {
1591cb0ef41Sopenharmony_ci  return Cast<Smi>(param2) otherwise Y;
1601cb0ef41Sopenharmony_ci}
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci@export
1631cb0ef41Sopenharmony_cimacro TestMacroSpecialization(): void {
1641cb0ef41Sopenharmony_ci  try {
1651cb0ef41Sopenharmony_ci    const _smi0: Smi = 0;
1661cb0ef41Sopenharmony_ci    check(GenericMacroTest<Smi>(0) == Undefined);
1671cb0ef41Sopenharmony_ci    check(GenericMacroTest<Smi>(1) == Undefined);
1681cb0ef41Sopenharmony_ci    check(GenericMacroTest<Object>(Null) == Null);
1691cb0ef41Sopenharmony_ci    check(GenericMacroTest<Object>(False) == False);
1701cb0ef41Sopenharmony_ci    check(GenericMacroTest<Object>(True) == True);
1711cb0ef41Sopenharmony_ci    check((GenericMacroTestWithLabels<Smi>(0) otherwise Fail) == Undefined);
1721cb0ef41Sopenharmony_ci    check((GenericMacroTestWithLabels<Smi>(0) otherwise Fail) == Undefined);
1731cb0ef41Sopenharmony_ci    try {
1741cb0ef41Sopenharmony_ci      GenericMacroTestWithLabels<Object>(False) otherwise Expected;
1751cb0ef41Sopenharmony_ci    } label Expected {}
1761cb0ef41Sopenharmony_ci  } label Fail {
1771cb0ef41Sopenharmony_ci    unreachable;
1781cb0ef41Sopenharmony_ci  }
1791cb0ef41Sopenharmony_ci}
1801cb0ef41Sopenharmony_ci
1811cb0ef41Sopenharmony_cibuiltin TestHelperPlus1(x: Smi): Smi {
1821cb0ef41Sopenharmony_ci  return x + 1;
1831cb0ef41Sopenharmony_ci}
1841cb0ef41Sopenharmony_cibuiltin TestHelperPlus2(x: Smi): Smi {
1851cb0ef41Sopenharmony_ci  return x + 2;
1861cb0ef41Sopenharmony_ci}
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_ci@export
1891cb0ef41Sopenharmony_cimacro TestFunctionPointers(implicit context: Context)(): Boolean {
1901cb0ef41Sopenharmony_ci  let fptr: builtin(Smi) => Smi = TestHelperPlus1;
1911cb0ef41Sopenharmony_ci  check(fptr(42) == 43);
1921cb0ef41Sopenharmony_ci  fptr = TestHelperPlus2;
1931cb0ef41Sopenharmony_ci  check(fptr(42) == 44);
1941cb0ef41Sopenharmony_ci  return True;
1951cb0ef41Sopenharmony_ci}
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_ci@export
1981cb0ef41Sopenharmony_cimacro TestVariableRedeclaration(implicit context: Context)(): Boolean {
1991cb0ef41Sopenharmony_ci  let _var1: int31 = FromConstexpr<bool>(42 == 0) ? FromConstexpr<int31>(0) : 1;
2001cb0ef41Sopenharmony_ci  let _var2: int31 = FromConstexpr<bool>(42 == 0) ? FromConstexpr<int31>(1) : 0;
2011cb0ef41Sopenharmony_ci  return True;
2021cb0ef41Sopenharmony_ci}
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_ci@export
2051cb0ef41Sopenharmony_cimacro TestTernaryOperator(x: Smi): Smi {
2061cb0ef41Sopenharmony_ci  const b: bool = x < 0 ? true : false;
2071cb0ef41Sopenharmony_ci  return b ? x - 10 : x + 100;
2081cb0ef41Sopenharmony_ci}
2091cb0ef41Sopenharmony_ci
2101cb0ef41Sopenharmony_ci@export
2111cb0ef41Sopenharmony_cimacro TestFunctionPointerToGeneric(): void {
2121cb0ef41Sopenharmony_ci  const fptr1: builtin(Smi) => JSAny = GenericBuiltinTest<Smi>;
2131cb0ef41Sopenharmony_ci  const fptr2: builtin(JSAny) => JSAny = GenericBuiltinTest<JSAny>;
2141cb0ef41Sopenharmony_ci
2151cb0ef41Sopenharmony_ci  check(fptr1(0) == Null);
2161cb0ef41Sopenharmony_ci  check(fptr1(1) == Null);
2171cb0ef41Sopenharmony_ci  check(fptr2(Undefined) == Undefined);
2181cb0ef41Sopenharmony_ci  check(fptr2(Undefined) == Undefined);
2191cb0ef41Sopenharmony_ci}
2201cb0ef41Sopenharmony_ci
2211cb0ef41Sopenharmony_citype ObjectToObject = builtin(Context, JSAny) => JSAny;
2221cb0ef41Sopenharmony_ci@export
2231cb0ef41Sopenharmony_cimacro TestTypeAlias(x: ObjectToObject): BuiltinPtr {
2241cb0ef41Sopenharmony_ci  return x;
2251cb0ef41Sopenharmony_ci}
2261cb0ef41Sopenharmony_ci
2271cb0ef41Sopenharmony_ci@export
2281cb0ef41Sopenharmony_cimacro TestUnsafeCast(implicit context: Context)(n: Number): Boolean {
2291cb0ef41Sopenharmony_ci  if (TaggedIsSmi(n)) {
2301cb0ef41Sopenharmony_ci    const m: Smi = UnsafeCast<Smi>(n);
2311cb0ef41Sopenharmony_ci
2321cb0ef41Sopenharmony_ci    check(TestHelperPlus1(m) == 11);
2331cb0ef41Sopenharmony_ci    return True;
2341cb0ef41Sopenharmony_ci  }
2351cb0ef41Sopenharmony_ci  return False;
2361cb0ef41Sopenharmony_ci}
2371cb0ef41Sopenharmony_ci
2381cb0ef41Sopenharmony_ci@export
2391cb0ef41Sopenharmony_cimacro TestHexLiteral(): void {
2401cb0ef41Sopenharmony_ci  check(Convert<intptr>(0xffff) + 1 == 0x10000);
2411cb0ef41Sopenharmony_ci  check(Convert<intptr>(-0xffff) == -65535);
2421cb0ef41Sopenharmony_ci}
2431cb0ef41Sopenharmony_ci
2441cb0ef41Sopenharmony_ci@export
2451cb0ef41Sopenharmony_cimacro TestLargeIntegerLiterals(implicit c: Context)(): void {
2461cb0ef41Sopenharmony_ci  let _x: int32 = 0x40000000;
2471cb0ef41Sopenharmony_ci  let _y: int32 = 0x7fffffff;
2481cb0ef41Sopenharmony_ci}
2491cb0ef41Sopenharmony_ci
2501cb0ef41Sopenharmony_ci@export
2511cb0ef41Sopenharmony_cimacro TestMultilineAssert(): void {
2521cb0ef41Sopenharmony_ci  const someVeryLongVariableNameThatWillCauseLineBreaks: Smi = 5;
2531cb0ef41Sopenharmony_ci  check(
2541cb0ef41Sopenharmony_ci      someVeryLongVariableNameThatWillCauseLineBreaks > 0 &&
2551cb0ef41Sopenharmony_ci      someVeryLongVariableNameThatWillCauseLineBreaks < 10);
2561cb0ef41Sopenharmony_ci}
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_ci@export
2591cb0ef41Sopenharmony_cimacro TestNewlineInString(): void {
2601cb0ef41Sopenharmony_ci  Print('Hello, World!\n');
2611cb0ef41Sopenharmony_ci}
2621cb0ef41Sopenharmony_ci
2631cb0ef41Sopenharmony_ciconst kConstexprConst: constexpr int31 = 5;
2641cb0ef41Sopenharmony_ciconst kIntptrConst: intptr = 4;
2651cb0ef41Sopenharmony_ciconst kSmiConst: Smi = 3;
2661cb0ef41Sopenharmony_ci
2671cb0ef41Sopenharmony_ci@export
2681cb0ef41Sopenharmony_cimacro TestModuleConstBindings(): void {
2691cb0ef41Sopenharmony_ci  check(kConstexprConst == Int32Constant(5));
2701cb0ef41Sopenharmony_ci  check(kIntptrConst == 4);
2711cb0ef41Sopenharmony_ci  check(kSmiConst == 3);
2721cb0ef41Sopenharmony_ci}
2731cb0ef41Sopenharmony_ci
2741cb0ef41Sopenharmony_ci@export
2751cb0ef41Sopenharmony_cimacro TestLocalConstBindings(): void {
2761cb0ef41Sopenharmony_ci  const x: constexpr int31 = 3;
2771cb0ef41Sopenharmony_ci  const xSmi: Smi = x;
2781cb0ef41Sopenharmony_ci  {
2791cb0ef41Sopenharmony_ci    const x: Smi = x + FromConstexpr<Smi>(1);
2801cb0ef41Sopenharmony_ci    check(x == xSmi + 1);
2811cb0ef41Sopenharmony_ci    const xSmi: Smi = x;
2821cb0ef41Sopenharmony_ci    check(x == xSmi);
2831cb0ef41Sopenharmony_ci    check(x == 4);
2841cb0ef41Sopenharmony_ci  }
2851cb0ef41Sopenharmony_ci  check(xSmi == 3);
2861cb0ef41Sopenharmony_ci  check(x == xSmi);
2871cb0ef41Sopenharmony_ci}
2881cb0ef41Sopenharmony_ci
2891cb0ef41Sopenharmony_cistruct TestStructA {
2901cb0ef41Sopenharmony_ci  indexes: FixedArray;
2911cb0ef41Sopenharmony_ci  i: Smi;
2921cb0ef41Sopenharmony_ci  k: Number;
2931cb0ef41Sopenharmony_ci}
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_cistruct TestStructB {
2961cb0ef41Sopenharmony_ci  x: TestStructA;
2971cb0ef41Sopenharmony_ci  y: Smi;
2981cb0ef41Sopenharmony_ci}
2991cb0ef41Sopenharmony_ci
3001cb0ef41Sopenharmony_ci@export
3011cb0ef41Sopenharmony_cimacro TestStruct1(i: TestStructA): Smi {
3021cb0ef41Sopenharmony_ci  return i.i;
3031cb0ef41Sopenharmony_ci}
3041cb0ef41Sopenharmony_ci
3051cb0ef41Sopenharmony_ci@export
3061cb0ef41Sopenharmony_cimacro TestStruct2(implicit context: Context)(): TestStructA {
3071cb0ef41Sopenharmony_ci  return TestStructA{
3081cb0ef41Sopenharmony_ci    indexes: UnsafeCast<FixedArray>(kEmptyFixedArray),
3091cb0ef41Sopenharmony_ci    i: 27,
3101cb0ef41Sopenharmony_ci    k: 31
3111cb0ef41Sopenharmony_ci  };
3121cb0ef41Sopenharmony_ci}
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_ci@export
3151cb0ef41Sopenharmony_cimacro TestStruct3(implicit context: Context)(): TestStructA {
3161cb0ef41Sopenharmony_ci  let a: TestStructA =
3171cb0ef41Sopenharmony_ci  TestStructA{indexes: UnsafeCast<FixedArray>(kEmptyFixedArray), i: 13, k: 5};
3181cb0ef41Sopenharmony_ci  let _b: TestStructA = a;
3191cb0ef41Sopenharmony_ci  const c: TestStructA = TestStruct2();
3201cb0ef41Sopenharmony_ci  a.i = TestStruct1(c);
3211cb0ef41Sopenharmony_ci  a.k = a.i;
3221cb0ef41Sopenharmony_ci  let d: TestStructB;
3231cb0ef41Sopenharmony_ci  d.x = a;
3241cb0ef41Sopenharmony_ci  d = TestStructB{x: a, y: 7};
3251cb0ef41Sopenharmony_ci  let _e: TestStructA = d.x;
3261cb0ef41Sopenharmony_ci  let f: Smi = TestStructA{
3271cb0ef41Sopenharmony_ci    indexes: UnsafeCast<FixedArray>(kEmptyFixedArray),
3281cb0ef41Sopenharmony_ci    i: 27,
3291cb0ef41Sopenharmony_ci    k: 31
3301cb0ef41Sopenharmony_ci  }.i;
3311cb0ef41Sopenharmony_ci  f = TestStruct2().i;
3321cb0ef41Sopenharmony_ci  return a;
3331cb0ef41Sopenharmony_ci}
3341cb0ef41Sopenharmony_ci
3351cb0ef41Sopenharmony_cistruct TestStructC {
3361cb0ef41Sopenharmony_ci  x: TestStructA;
3371cb0ef41Sopenharmony_ci  y: TestStructA;
3381cb0ef41Sopenharmony_ci}
3391cb0ef41Sopenharmony_ci
3401cb0ef41Sopenharmony_ci@export
3411cb0ef41Sopenharmony_cimacro TestStruct4(implicit context: Context)(): TestStructC {
3421cb0ef41Sopenharmony_ci  return TestStructC{x: TestStruct2(), y: TestStruct2()};
3431cb0ef41Sopenharmony_ci}
3441cb0ef41Sopenharmony_ci
3451cb0ef41Sopenharmony_cimacro TestStructInLabel(implicit context: Context)(): never labels
3461cb0ef41Sopenharmony_ciFoo(TestStructA) {
3471cb0ef41Sopenharmony_ci  goto Foo(TestStruct2());
3481cb0ef41Sopenharmony_ci}
3491cb0ef41Sopenharmony_ci@export  // Silence unused warning.
3501cb0ef41Sopenharmony_cimacro CallTestStructInLabel(implicit context: Context)(): void {
3511cb0ef41Sopenharmony_ci  try {
3521cb0ef41Sopenharmony_ci    TestStructInLabel() otherwise Foo;
3531cb0ef41Sopenharmony_ci  } label Foo(_s: TestStructA) {}
3541cb0ef41Sopenharmony_ci}
3551cb0ef41Sopenharmony_ci
3561cb0ef41Sopenharmony_ci// This macro tests different versions of the for-loop where some parts
3571cb0ef41Sopenharmony_ci// are (not) present.
3581cb0ef41Sopenharmony_ci@export
3591cb0ef41Sopenharmony_cimacro TestForLoop(): void {
3601cb0ef41Sopenharmony_ci  let sum: Smi = 0;
3611cb0ef41Sopenharmony_ci  for (let i: Smi = 0; i < 5; ++i) sum += i;
3621cb0ef41Sopenharmony_ci  check(sum == 10);
3631cb0ef41Sopenharmony_ci
3641cb0ef41Sopenharmony_ci  sum = 0;
3651cb0ef41Sopenharmony_ci  let j: Smi = 0;
3661cb0ef41Sopenharmony_ci  for (; j < 5; ++j) sum += j;
3671cb0ef41Sopenharmony_ci  check(sum == 10);
3681cb0ef41Sopenharmony_ci
3691cb0ef41Sopenharmony_ci  sum = 0;
3701cb0ef41Sopenharmony_ci  j = 0;
3711cb0ef41Sopenharmony_ci  for (; j < 5;) sum += j++;
3721cb0ef41Sopenharmony_ci  check(sum == 10);
3731cb0ef41Sopenharmony_ci
3741cb0ef41Sopenharmony_ci  // Check that break works. No test expression.
3751cb0ef41Sopenharmony_ci  sum = 0;
3761cb0ef41Sopenharmony_ci  for (let i: Smi = 0;; ++i) {
3771cb0ef41Sopenharmony_ci    if (i == 5) break;
3781cb0ef41Sopenharmony_ci    sum += i;
3791cb0ef41Sopenharmony_ci  }
3801cb0ef41Sopenharmony_ci  check(sum == 10);
3811cb0ef41Sopenharmony_ci
3821cb0ef41Sopenharmony_ci  sum = 0;
3831cb0ef41Sopenharmony_ci  j = 0;
3841cb0ef41Sopenharmony_ci  for (;;) {
3851cb0ef41Sopenharmony_ci    if (j == 5) break;
3861cb0ef41Sopenharmony_ci    sum += j;
3871cb0ef41Sopenharmony_ci    j++;
3881cb0ef41Sopenharmony_ci  }
3891cb0ef41Sopenharmony_ci  check(sum == 10);
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ci  // The following tests are the same as above, but use continue to skip
3921cb0ef41Sopenharmony_ci  // index 3.
3931cb0ef41Sopenharmony_ci  sum = 0;
3941cb0ef41Sopenharmony_ci  for (let i: Smi = 0; i < 5; ++i) {
3951cb0ef41Sopenharmony_ci    if (i == 3) continue;
3961cb0ef41Sopenharmony_ci    sum += i;
3971cb0ef41Sopenharmony_ci  }
3981cb0ef41Sopenharmony_ci  check(sum == 7);
3991cb0ef41Sopenharmony_ci
4001cb0ef41Sopenharmony_ci  sum = 0;
4011cb0ef41Sopenharmony_ci  j = 0;
4021cb0ef41Sopenharmony_ci  for (; j < 5; ++j) {
4031cb0ef41Sopenharmony_ci    if (j == 3) continue;
4041cb0ef41Sopenharmony_ci    sum += j;
4051cb0ef41Sopenharmony_ci  }
4061cb0ef41Sopenharmony_ci  check(sum == 7);
4071cb0ef41Sopenharmony_ci
4081cb0ef41Sopenharmony_ci  sum = 0;
4091cb0ef41Sopenharmony_ci  j = 0;
4101cb0ef41Sopenharmony_ci  for (; j < 5;) {
4111cb0ef41Sopenharmony_ci    if (j == 3) {
4121cb0ef41Sopenharmony_ci      j++;
4131cb0ef41Sopenharmony_ci      continue;
4141cb0ef41Sopenharmony_ci    }
4151cb0ef41Sopenharmony_ci    sum += j;
4161cb0ef41Sopenharmony_ci    j++;
4171cb0ef41Sopenharmony_ci  }
4181cb0ef41Sopenharmony_ci  check(sum == 7);
4191cb0ef41Sopenharmony_ci
4201cb0ef41Sopenharmony_ci  sum = 0;
4211cb0ef41Sopenharmony_ci  for (let i: Smi = 0;; ++i) {
4221cb0ef41Sopenharmony_ci    if (i == 3) continue;
4231cb0ef41Sopenharmony_ci    if (i == 5) break;
4241cb0ef41Sopenharmony_ci    sum += i;
4251cb0ef41Sopenharmony_ci  }
4261cb0ef41Sopenharmony_ci  check(sum == 7);
4271cb0ef41Sopenharmony_ci
4281cb0ef41Sopenharmony_ci  sum = 0;
4291cb0ef41Sopenharmony_ci  j = 0;
4301cb0ef41Sopenharmony_ci  for (;;) {
4311cb0ef41Sopenharmony_ci    if (j == 3) {
4321cb0ef41Sopenharmony_ci      j++;
4331cb0ef41Sopenharmony_ci      continue;
4341cb0ef41Sopenharmony_ci    }
4351cb0ef41Sopenharmony_ci
4361cb0ef41Sopenharmony_ci    if (j == 5) break;
4371cb0ef41Sopenharmony_ci    sum += j;
4381cb0ef41Sopenharmony_ci    j++;
4391cb0ef41Sopenharmony_ci  }
4401cb0ef41Sopenharmony_ci  check(sum == 7);
4411cb0ef41Sopenharmony_ci
4421cb0ef41Sopenharmony_ci  j = 0;
4431cb0ef41Sopenharmony_ci  try {
4441cb0ef41Sopenharmony_ci    for (;;) {
4451cb0ef41Sopenharmony_ci      if (++j == 10) goto Exit;
4461cb0ef41Sopenharmony_ci    }
4471cb0ef41Sopenharmony_ci  } label Exit {
4481cb0ef41Sopenharmony_ci    check(j == 10);
4491cb0ef41Sopenharmony_ci  }
4501cb0ef41Sopenharmony_ci
4511cb0ef41Sopenharmony_ci  // Test if we can handle uninitialized values on the stack.
4521cb0ef41Sopenharmony_ci  let _i: Smi;
4531cb0ef41Sopenharmony_ci  for (let j: Smi = 0; j < 10; ++j) {
4541cb0ef41Sopenharmony_ci  }
4551cb0ef41Sopenharmony_ci}
4561cb0ef41Sopenharmony_ci
4571cb0ef41Sopenharmony_ci@export
4581cb0ef41Sopenharmony_cimacro TestSubtyping(x: Smi): void {
4591cb0ef41Sopenharmony_ci  const _foo: JSAny = x;
4601cb0ef41Sopenharmony_ci}
4611cb0ef41Sopenharmony_ci
4621cb0ef41Sopenharmony_cimacro IncrementIfSmi<A: type>(x: A): A {
4631cb0ef41Sopenharmony_ci  typeswitch (x) {
4641cb0ef41Sopenharmony_ci    case (x: Smi): {
4651cb0ef41Sopenharmony_ci      return x + 1;
4661cb0ef41Sopenharmony_ci    }
4671cb0ef41Sopenharmony_ci    case (o: A): {
4681cb0ef41Sopenharmony_ci      return o;
4691cb0ef41Sopenharmony_ci    }
4701cb0ef41Sopenharmony_ci  }
4711cb0ef41Sopenharmony_ci}
4721cb0ef41Sopenharmony_ci
4731cb0ef41Sopenharmony_citype NumberOrFixedArray = Number|FixedArray;
4741cb0ef41Sopenharmony_cimacro TypeswitchExample(implicit context: Context)(x: NumberOrFixedArray):
4751cb0ef41Sopenharmony_ci    int32 {
4761cb0ef41Sopenharmony_ci  let result: int32 = 0;
4771cb0ef41Sopenharmony_ci  typeswitch (IncrementIfSmi(x)) {
4781cb0ef41Sopenharmony_ci    case (_x: FixedArray): {
4791cb0ef41Sopenharmony_ci      result = result + 1;
4801cb0ef41Sopenharmony_ci    }
4811cb0ef41Sopenharmony_ci    case (Number): {
4821cb0ef41Sopenharmony_ci      result = result + 2;
4831cb0ef41Sopenharmony_ci    }
4841cb0ef41Sopenharmony_ci  }
4851cb0ef41Sopenharmony_ci
4861cb0ef41Sopenharmony_ci  result = result * 10;
4871cb0ef41Sopenharmony_ci
4881cb0ef41Sopenharmony_ci  typeswitch (IncrementIfSmi(x)) {
4891cb0ef41Sopenharmony_ci    case (x: Smi): {
4901cb0ef41Sopenharmony_ci      result = result + Convert<int32>(x);
4911cb0ef41Sopenharmony_ci    }
4921cb0ef41Sopenharmony_ci    case (a: FixedArray): {
4931cb0ef41Sopenharmony_ci      result = result + Convert<int32>(a.length);
4941cb0ef41Sopenharmony_ci    }
4951cb0ef41Sopenharmony_ci    case (_x: HeapNumber): {
4961cb0ef41Sopenharmony_ci      result = result + 7;
4971cb0ef41Sopenharmony_ci    }
4981cb0ef41Sopenharmony_ci  }
4991cb0ef41Sopenharmony_ci
5001cb0ef41Sopenharmony_ci  return result;
5011cb0ef41Sopenharmony_ci}
5021cb0ef41Sopenharmony_ci
5031cb0ef41Sopenharmony_ci@export
5041cb0ef41Sopenharmony_cimacro TestTypeswitch(implicit context: Context)(): void {
5051cb0ef41Sopenharmony_ci  check(TypeswitchExample(FromConstexpr<Smi>(5)) == 26);
5061cb0ef41Sopenharmony_ci  const a: FixedArray = AllocateZeroedFixedArray(3);
5071cb0ef41Sopenharmony_ci  check(TypeswitchExample(a) == 13);
5081cb0ef41Sopenharmony_ci  check(TypeswitchExample(FromConstexpr<Number>(0.5)) == 27);
5091cb0ef41Sopenharmony_ci}
5101cb0ef41Sopenharmony_ci
5111cb0ef41Sopenharmony_ci@export
5121cb0ef41Sopenharmony_cimacro TestTypeswitchAsanLsanFailure(implicit context: Context)(obj: Object):
5131cb0ef41Sopenharmony_ci    void {
5141cb0ef41Sopenharmony_ci  typeswitch (obj) {
5151cb0ef41Sopenharmony_ci    case (_o: Smi): {
5161cb0ef41Sopenharmony_ci    }
5171cb0ef41Sopenharmony_ci    case (_o: JSTypedArray): {
5181cb0ef41Sopenharmony_ci    }
5191cb0ef41Sopenharmony_ci    case (_o: JSReceiver): {
5201cb0ef41Sopenharmony_ci    }
5211cb0ef41Sopenharmony_ci    case (_o: HeapObject): {
5221cb0ef41Sopenharmony_ci    }
5231cb0ef41Sopenharmony_ci  }
5241cb0ef41Sopenharmony_ci}
5251cb0ef41Sopenharmony_ci
5261cb0ef41Sopenharmony_cimacro ExampleGenericOverload<A: type>(o: Object): A {
5271cb0ef41Sopenharmony_ci  return o;
5281cb0ef41Sopenharmony_ci}
5291cb0ef41Sopenharmony_cimacro ExampleGenericOverload<A: type>(o: Smi): A {
5301cb0ef41Sopenharmony_ci  return o + 1;
5311cb0ef41Sopenharmony_ci}
5321cb0ef41Sopenharmony_ci
5331cb0ef41Sopenharmony_ci@export
5341cb0ef41Sopenharmony_cimacro TestGenericOverload(implicit context: Context)(): void {
5351cb0ef41Sopenharmony_ci  const xSmi: Smi = 5;
5361cb0ef41Sopenharmony_ci  const xObject: Object = xSmi;
5371cb0ef41Sopenharmony_ci  check(ExampleGenericOverload<Smi>(xSmi) == 6);
5381cb0ef41Sopenharmony_ci  check(UnsafeCast<Smi>(ExampleGenericOverload<Object>(xObject)) == 5);
5391cb0ef41Sopenharmony_ci}
5401cb0ef41Sopenharmony_ci
5411cb0ef41Sopenharmony_ci@export
5421cb0ef41Sopenharmony_cimacro TestEquality(implicit context: Context)(): void {
5431cb0ef41Sopenharmony_ci  const notEqual: bool =
5441cb0ef41Sopenharmony_ci      AllocateHeapNumberWithValue(0.5) != AllocateHeapNumberWithValue(0.5);
5451cb0ef41Sopenharmony_ci  check(!notEqual);
5461cb0ef41Sopenharmony_ci  const equal: bool =
5471cb0ef41Sopenharmony_ci      AllocateHeapNumberWithValue(0.5) == AllocateHeapNumberWithValue(0.5);
5481cb0ef41Sopenharmony_ci  check(equal);
5491cb0ef41Sopenharmony_ci}
5501cb0ef41Sopenharmony_ci
5511cb0ef41Sopenharmony_ci@export
5521cb0ef41Sopenharmony_cimacro TestOrAnd(x: bool, y: bool, z: bool): bool {
5531cb0ef41Sopenharmony_ci  return x || y && z ? true : false;
5541cb0ef41Sopenharmony_ci}
5551cb0ef41Sopenharmony_ci
5561cb0ef41Sopenharmony_ci@export
5571cb0ef41Sopenharmony_cimacro TestAndOr(x: bool, y: bool, z: bool): bool {
5581cb0ef41Sopenharmony_ci  return x && y || z ? true : false;
5591cb0ef41Sopenharmony_ci}
5601cb0ef41Sopenharmony_ci
5611cb0ef41Sopenharmony_ci@export
5621cb0ef41Sopenharmony_cimacro TestLogicalOperators(): void {
5631cb0ef41Sopenharmony_ci  check(TestAndOr(true, true, true));
5641cb0ef41Sopenharmony_ci  check(TestAndOr(true, true, false));
5651cb0ef41Sopenharmony_ci  check(TestAndOr(true, false, true));
5661cb0ef41Sopenharmony_ci  check(!TestAndOr(true, false, false));
5671cb0ef41Sopenharmony_ci  check(TestAndOr(false, true, true));
5681cb0ef41Sopenharmony_ci  check(!TestAndOr(false, true, false));
5691cb0ef41Sopenharmony_ci  check(TestAndOr(false, false, true));
5701cb0ef41Sopenharmony_ci  check(!TestAndOr(false, false, false));
5711cb0ef41Sopenharmony_ci  check(TestOrAnd(true, true, true));
5721cb0ef41Sopenharmony_ci  check(TestOrAnd(true, true, false));
5731cb0ef41Sopenharmony_ci  check(TestOrAnd(true, false, true));
5741cb0ef41Sopenharmony_ci  check(TestOrAnd(true, false, false));
5751cb0ef41Sopenharmony_ci  check(TestOrAnd(false, true, true));
5761cb0ef41Sopenharmony_ci  check(!TestOrAnd(false, true, false));
5771cb0ef41Sopenharmony_ci  check(!TestOrAnd(false, false, true));
5781cb0ef41Sopenharmony_ci  check(!TestOrAnd(false, false, false));
5791cb0ef41Sopenharmony_ci}
5801cb0ef41Sopenharmony_ci
5811cb0ef41Sopenharmony_ci@export
5821cb0ef41Sopenharmony_cimacro TestCall(i: Smi): Smi labels A {
5831cb0ef41Sopenharmony_ci  if (i < 5) return i;
5841cb0ef41Sopenharmony_ci  goto A;
5851cb0ef41Sopenharmony_ci}
5861cb0ef41Sopenharmony_ci
5871cb0ef41Sopenharmony_ci@export
5881cb0ef41Sopenharmony_cimacro TestOtherwiseWithCode1(): void {
5891cb0ef41Sopenharmony_ci  let v: Smi = 0;
5901cb0ef41Sopenharmony_ci  let s: Smi = 1;
5911cb0ef41Sopenharmony_ci  try {
5921cb0ef41Sopenharmony_ci    TestCall(10) otherwise goto B(++s);
5931cb0ef41Sopenharmony_ci  } label B(v1: Smi) {
5941cb0ef41Sopenharmony_ci    v = v1;
5951cb0ef41Sopenharmony_ci  }
5961cb0ef41Sopenharmony_ci  dcheck(v == 2);
5971cb0ef41Sopenharmony_ci}
5981cb0ef41Sopenharmony_ci
5991cb0ef41Sopenharmony_ci@export
6001cb0ef41Sopenharmony_cimacro TestOtherwiseWithCode2(): void {
6011cb0ef41Sopenharmony_ci  let s: Smi = 0;
6021cb0ef41Sopenharmony_ci  for (let i: Smi = 0; i < 10; ++i) {
6031cb0ef41Sopenharmony_ci    TestCall(i) otherwise break;
6041cb0ef41Sopenharmony_ci    ++s;
6051cb0ef41Sopenharmony_ci  }
6061cb0ef41Sopenharmony_ci  dcheck(s == 5);
6071cb0ef41Sopenharmony_ci}
6081cb0ef41Sopenharmony_ci
6091cb0ef41Sopenharmony_ci@export
6101cb0ef41Sopenharmony_cimacro TestOtherwiseWithCode3(): void {
6111cb0ef41Sopenharmony_ci  let s: Smi = 0;
6121cb0ef41Sopenharmony_ci  for (let i: Smi = 0; i < 10; ++i) {
6131cb0ef41Sopenharmony_ci    s += TestCall(i) otherwise break;
6141cb0ef41Sopenharmony_ci  }
6151cb0ef41Sopenharmony_ci  dcheck(s == 10);
6161cb0ef41Sopenharmony_ci}
6171cb0ef41Sopenharmony_ci
6181cb0ef41Sopenharmony_ci@export
6191cb0ef41Sopenharmony_cimacro TestForwardLabel(): void {
6201cb0ef41Sopenharmony_ci  try {
6211cb0ef41Sopenharmony_ci    goto A;
6221cb0ef41Sopenharmony_ci  } label A {
6231cb0ef41Sopenharmony_ci    goto B(5);
6241cb0ef41Sopenharmony_ci  } label B(b: Smi) {
6251cb0ef41Sopenharmony_ci    dcheck(b == 5);
6261cb0ef41Sopenharmony_ci  }
6271cb0ef41Sopenharmony_ci}
6281cb0ef41Sopenharmony_ci
6291cb0ef41Sopenharmony_ci@export
6301cb0ef41Sopenharmony_cimacro TestQualifiedAccess(implicit context: Context)(): void {
6311cb0ef41Sopenharmony_ci  const s: Smi = 0;
6321cb0ef41Sopenharmony_ci  check(!Is<JSArray>(s));
6331cb0ef41Sopenharmony_ci}
6341cb0ef41Sopenharmony_ci
6351cb0ef41Sopenharmony_ci@export
6361cb0ef41Sopenharmony_cimacro TestCatch1(implicit context: Context)(): Smi {
6371cb0ef41Sopenharmony_ci  let r: Smi = 0;
6381cb0ef41Sopenharmony_ci  try {
6391cb0ef41Sopenharmony_ci    ThrowTypeError(MessageTemplate::kInvalidArrayLength);
6401cb0ef41Sopenharmony_ci  } catch (_e, _message) {
6411cb0ef41Sopenharmony_ci    r = 1;
6421cb0ef41Sopenharmony_ci    return r;
6431cb0ef41Sopenharmony_ci  }
6441cb0ef41Sopenharmony_ci}
6451cb0ef41Sopenharmony_ci
6461cb0ef41Sopenharmony_ci@export
6471cb0ef41Sopenharmony_cimacro TestCatch2Wrapper(implicit context: Context)(): never {
6481cb0ef41Sopenharmony_ci  ThrowTypeError(MessageTemplate::kInvalidArrayLength);
6491cb0ef41Sopenharmony_ci}
6501cb0ef41Sopenharmony_ci
6511cb0ef41Sopenharmony_ci@export
6521cb0ef41Sopenharmony_cimacro TestCatch2(implicit context: Context)(): Smi {
6531cb0ef41Sopenharmony_ci  let r: Smi = 0;
6541cb0ef41Sopenharmony_ci  try {
6551cb0ef41Sopenharmony_ci    TestCatch2Wrapper();
6561cb0ef41Sopenharmony_ci  } catch (_e, _message) {
6571cb0ef41Sopenharmony_ci    r = 2;
6581cb0ef41Sopenharmony_ci    return r;
6591cb0ef41Sopenharmony_ci  }
6601cb0ef41Sopenharmony_ci}
6611cb0ef41Sopenharmony_ci
6621cb0ef41Sopenharmony_ci@export
6631cb0ef41Sopenharmony_cimacro TestCatch3WrapperWithLabel(implicit context: Context)():
6641cb0ef41Sopenharmony_ci    never labels _Abort {
6651cb0ef41Sopenharmony_ci  ThrowTypeError(MessageTemplate::kInvalidArrayLength);
6661cb0ef41Sopenharmony_ci}
6671cb0ef41Sopenharmony_ci
6681cb0ef41Sopenharmony_ci@export
6691cb0ef41Sopenharmony_cimacro TestCatch3(implicit context: Context)(): Smi {
6701cb0ef41Sopenharmony_ci  let r: Smi = 0;
6711cb0ef41Sopenharmony_ci  try {
6721cb0ef41Sopenharmony_ci    TestCatch3WrapperWithLabel() otherwise Abort;
6731cb0ef41Sopenharmony_ci  } catch (_e, _message) {
6741cb0ef41Sopenharmony_ci    r = 2;
6751cb0ef41Sopenharmony_ci    return r;
6761cb0ef41Sopenharmony_ci  } label Abort {
6771cb0ef41Sopenharmony_ci    return -1;
6781cb0ef41Sopenharmony_ci  }
6791cb0ef41Sopenharmony_ci}
6801cb0ef41Sopenharmony_ci
6811cb0ef41Sopenharmony_ci// This test doesn't actually test the functionality of iterators,
6821cb0ef41Sopenharmony_ci// it's only purpose is to make sure tha the CSA macros in the
6831cb0ef41Sopenharmony_ci// IteratorBuiltinsAssembler match the signatures provided in
6841cb0ef41Sopenharmony_ci// iterator.tq.
6851cb0ef41Sopenharmony_ci@export
6861cb0ef41Sopenharmony_citransitioning macro TestIterator(implicit context: Context)(
6871cb0ef41Sopenharmony_ci    o: JSReceiver, map: Map): void {
6881cb0ef41Sopenharmony_ci  try {
6891cb0ef41Sopenharmony_ci    const t1: JSAny = iterator::GetIteratorMethod(o);
6901cb0ef41Sopenharmony_ci    const t2: iterator::IteratorRecord = iterator::GetIterator(o);
6911cb0ef41Sopenharmony_ci
6921cb0ef41Sopenharmony_ci    const _t3: JSAny = iterator::IteratorStep(t2) otherwise Fail;
6931cb0ef41Sopenharmony_ci    const _t4: JSAny = iterator::IteratorStep(t2, map) otherwise Fail;
6941cb0ef41Sopenharmony_ci
6951cb0ef41Sopenharmony_ci    const _t5: JSAny = iterator::IteratorValue(o);
6961cb0ef41Sopenharmony_ci    const _t6: JSAny = iterator::IteratorValue(o, map);
6971cb0ef41Sopenharmony_ci
6981cb0ef41Sopenharmony_ci    const _t7: JSArray = iterator::IterableToList(t1, t1);
6991cb0ef41Sopenharmony_ci
7001cb0ef41Sopenharmony_ci    iterator::IteratorCloseOnException(t2);
7011cb0ef41Sopenharmony_ci  } label Fail {}
7021cb0ef41Sopenharmony_ci}
7031cb0ef41Sopenharmony_ci
7041cb0ef41Sopenharmony_ci@export
7051cb0ef41Sopenharmony_cimacro TestFrame1(implicit context: Context)(): void {
7061cb0ef41Sopenharmony_ci  const f: Frame = LoadFramePointer();
7071cb0ef41Sopenharmony_ci  const frameType: FrameType =
7081cb0ef41Sopenharmony_ci      Cast<FrameType>(f.context_or_frame_type) otherwise unreachable;
7091cb0ef41Sopenharmony_ci  dcheck(frameType == STUB_FRAME);
7101cb0ef41Sopenharmony_ci  dcheck(f.caller == LoadParentFramePointer());
7111cb0ef41Sopenharmony_ci  typeswitch (f) {
7121cb0ef41Sopenharmony_ci    case (_f: StandardFrame): {
7131cb0ef41Sopenharmony_ci      unreachable;
7141cb0ef41Sopenharmony_ci    }
7151cb0ef41Sopenharmony_ci    case (_f: StubFrame): {
7161cb0ef41Sopenharmony_ci    }
7171cb0ef41Sopenharmony_ci  }
7181cb0ef41Sopenharmony_ci}
7191cb0ef41Sopenharmony_ci
7201cb0ef41Sopenharmony_ci@export
7211cb0ef41Sopenharmony_cimacro TestNew(implicit context: Context)(): void {
7221cb0ef41Sopenharmony_ci  const f: JSArray = NewJSArray();
7231cb0ef41Sopenharmony_ci  check(f.IsEmpty());
7241cb0ef41Sopenharmony_ci  f.length = 0;
7251cb0ef41Sopenharmony_ci}
7261cb0ef41Sopenharmony_ci
7271cb0ef41Sopenharmony_cistruct TestInner {
7281cb0ef41Sopenharmony_ci  macro SetX(newValue: int32): void {
7291cb0ef41Sopenharmony_ci    this.x = newValue;
7301cb0ef41Sopenharmony_ci  }
7311cb0ef41Sopenharmony_ci  macro GetX(): int32 {
7321cb0ef41Sopenharmony_ci    return this.x;
7331cb0ef41Sopenharmony_ci  }
7341cb0ef41Sopenharmony_ci  x: int32;
7351cb0ef41Sopenharmony_ci  y: int32;
7361cb0ef41Sopenharmony_ci}
7371cb0ef41Sopenharmony_ci
7381cb0ef41Sopenharmony_cistruct TestOuter {
7391cb0ef41Sopenharmony_ci  a: int32;
7401cb0ef41Sopenharmony_ci  b: TestInner;
7411cb0ef41Sopenharmony_ci  c: int32;
7421cb0ef41Sopenharmony_ci}
7431cb0ef41Sopenharmony_ci
7441cb0ef41Sopenharmony_ci@export
7451cb0ef41Sopenharmony_cimacro TestStructConstructor(implicit context: Context)(): void {
7461cb0ef41Sopenharmony_ci  // Test default constructor
7471cb0ef41Sopenharmony_ci  let a: TestOuter = TestOuter{a: 5, b: TestInner{x: 6, y: 7}, c: 8};
7481cb0ef41Sopenharmony_ci  check(a.a == 5);
7491cb0ef41Sopenharmony_ci  check(a.b.x == 6);
7501cb0ef41Sopenharmony_ci  check(a.b.y == 7);
7511cb0ef41Sopenharmony_ci  check(a.c == 8);
7521cb0ef41Sopenharmony_ci  a.b.x = 1;
7531cb0ef41Sopenharmony_ci  check(a.b.x == 1);
7541cb0ef41Sopenharmony_ci  a.b.SetX(2);
7551cb0ef41Sopenharmony_ci  check(a.b.x == 2);
7561cb0ef41Sopenharmony_ci  check(a.b.GetX() == 2);
7571cb0ef41Sopenharmony_ci}
7581cb0ef41Sopenharmony_ci
7591cb0ef41Sopenharmony_ciclass InternalClass extends HeapObject {
7601cb0ef41Sopenharmony_ci  macro Flip(): void labels NotASmi {
7611cb0ef41Sopenharmony_ci    const tmp = Cast<Smi>(this.b) otherwise NotASmi;
7621cb0ef41Sopenharmony_ci    this.b = this.a;
7631cb0ef41Sopenharmony_ci    this.a = tmp;
7641cb0ef41Sopenharmony_ci  }
7651cb0ef41Sopenharmony_ci  a: Smi;
7661cb0ef41Sopenharmony_ci  b: Number;
7671cb0ef41Sopenharmony_ci}
7681cb0ef41Sopenharmony_ci
7691cb0ef41Sopenharmony_cimacro NewInternalClass(x: Smi): InternalClass {
7701cb0ef41Sopenharmony_ci  return new InternalClass{a: x, b: x + 1};
7711cb0ef41Sopenharmony_ci}
7721cb0ef41Sopenharmony_ci
7731cb0ef41Sopenharmony_ci@export
7741cb0ef41Sopenharmony_cimacro TestInternalClass(implicit context: Context)(): void {
7751cb0ef41Sopenharmony_ci  const o = NewInternalClass(5);
7761cb0ef41Sopenharmony_ci  o.Flip() otherwise unreachable;
7771cb0ef41Sopenharmony_ci  check(o.a == 6);
7781cb0ef41Sopenharmony_ci  check(o.b == 5);
7791cb0ef41Sopenharmony_ci}
7801cb0ef41Sopenharmony_ci
7811cb0ef41Sopenharmony_cistruct StructWithConst {
7821cb0ef41Sopenharmony_ci  macro TestMethod1(): int32 {
7831cb0ef41Sopenharmony_ci    return this.b;
7841cb0ef41Sopenharmony_ci  }
7851cb0ef41Sopenharmony_ci  macro TestMethod2(): Object {
7861cb0ef41Sopenharmony_ci    return this.a;
7871cb0ef41Sopenharmony_ci  }
7881cb0ef41Sopenharmony_ci  a: Object;
7891cb0ef41Sopenharmony_ci  const b: int32;
7901cb0ef41Sopenharmony_ci}
7911cb0ef41Sopenharmony_ci
7921cb0ef41Sopenharmony_ci@export
7931cb0ef41Sopenharmony_cimacro TestConstInStructs(): void {
7941cb0ef41Sopenharmony_ci  const x = StructWithConst{a: Null, b: 1};
7951cb0ef41Sopenharmony_ci  let y = StructWithConst{a: Null, b: 1};
7961cb0ef41Sopenharmony_ci  y.a = Undefined;
7971cb0ef41Sopenharmony_ci  const _copy = x;
7981cb0ef41Sopenharmony_ci
7991cb0ef41Sopenharmony_ci  check(x.TestMethod1() == 1);
8001cb0ef41Sopenharmony_ci  check(x.TestMethod2() == Null);
8011cb0ef41Sopenharmony_ci}
8021cb0ef41Sopenharmony_ci
8031cb0ef41Sopenharmony_ci@export
8041cb0ef41Sopenharmony_cimacro TestParentFrameArguments(implicit context: Context)(): void {
8051cb0ef41Sopenharmony_ci  const parentFrame = LoadParentFramePointer();
8061cb0ef41Sopenharmony_ci  const castFrame = Cast<StandardFrame>(parentFrame) otherwise unreachable;
8071cb0ef41Sopenharmony_ci  const arguments = GetFrameArguments(castFrame, 1);
8081cb0ef41Sopenharmony_ci  ArgumentsIterator{arguments, current: 0};
8091cb0ef41Sopenharmony_ci}
8101cb0ef41Sopenharmony_ci
8111cb0ef41Sopenharmony_cistruct TestIterator {
8121cb0ef41Sopenharmony_ci  macro Next(): Object labels NoMore {
8131cb0ef41Sopenharmony_ci    if (this.count-- == 0) goto NoMore;
8141cb0ef41Sopenharmony_ci    return TheHole;
8151cb0ef41Sopenharmony_ci  }
8161cb0ef41Sopenharmony_ci  count: Smi;
8171cb0ef41Sopenharmony_ci}
8181cb0ef41Sopenharmony_ci
8191cb0ef41Sopenharmony_ci@export
8201cb0ef41Sopenharmony_cimacro TestNewFixedArrayFromSpread(implicit context: Context)(): Object {
8211cb0ef41Sopenharmony_ci  let i = TestIterator{count: 5};
8221cb0ef41Sopenharmony_ci  return new FixedArray{map: kFixedArrayMap, length: 5, objects: ...i};
8231cb0ef41Sopenharmony_ci}
8241cb0ef41Sopenharmony_ci
8251cb0ef41Sopenharmony_ciclass SmiPair extends HeapObject {
8261cb0ef41Sopenharmony_ci  macro GetA():&Smi {
8271cb0ef41Sopenharmony_ci    return &this.a;
8281cb0ef41Sopenharmony_ci  }
8291cb0ef41Sopenharmony_ci  a: Smi;
8301cb0ef41Sopenharmony_ci  b: Smi;
8311cb0ef41Sopenharmony_ci}
8321cb0ef41Sopenharmony_ci
8331cb0ef41Sopenharmony_cimacro Swap<T: type>(a:&T, b:&T): void {
8341cb0ef41Sopenharmony_ci  const tmp = *a;
8351cb0ef41Sopenharmony_ci  *a = *b;
8361cb0ef41Sopenharmony_ci  *b = tmp;
8371cb0ef41Sopenharmony_ci}
8381cb0ef41Sopenharmony_ci
8391cb0ef41Sopenharmony_ci@export
8401cb0ef41Sopenharmony_cimacro TestReferences(): void {
8411cb0ef41Sopenharmony_ci  const array = new SmiPair{a: 7, b: 2};
8421cb0ef41Sopenharmony_ci  const ref:&Smi = &array.a;
8431cb0ef41Sopenharmony_ci  *ref = 3 + *ref;
8441cb0ef41Sopenharmony_ci  -- *ref;
8451cb0ef41Sopenharmony_ci  Swap(&array.b, array.GetA());
8461cb0ef41Sopenharmony_ci  check(array.a == 2);
8471cb0ef41Sopenharmony_ci  check(array.b == 9);
8481cb0ef41Sopenharmony_ci}
8491cb0ef41Sopenharmony_ci
8501cb0ef41Sopenharmony_ci@export
8511cb0ef41Sopenharmony_cimacro TestSlices(): void {
8521cb0ef41Sopenharmony_ci  const it = TestIterator{count: 3};
8531cb0ef41Sopenharmony_ci  const a = new FixedArray{map: kFixedArrayMap, length: 3, objects: ...it};
8541cb0ef41Sopenharmony_ci  check(a.length == 3);
8551cb0ef41Sopenharmony_ci
8561cb0ef41Sopenharmony_ci  const oneTwoThree = Convert<Smi>(123);
8571cb0ef41Sopenharmony_ci  a.objects[0] = oneTwoThree;
8581cb0ef41Sopenharmony_ci  const firstRef:&Object = &a.objects[0];
8591cb0ef41Sopenharmony_ci  check(TaggedEqual(*firstRef, oneTwoThree));
8601cb0ef41Sopenharmony_ci
8611cb0ef41Sopenharmony_ci  const slice: MutableSlice<Object> = &a.objects;
8621cb0ef41Sopenharmony_ci  const firstRefAgain:&Object = slice.TryAtIndex(0) otherwise unreachable;
8631cb0ef41Sopenharmony_ci  check(TaggedEqual(*firstRefAgain, oneTwoThree));
8641cb0ef41Sopenharmony_ci
8651cb0ef41Sopenharmony_ci  const threeTwoOne = Convert<Smi>(321);
8661cb0ef41Sopenharmony_ci  *firstRefAgain = threeTwoOne;
8671cb0ef41Sopenharmony_ci  check(TaggedEqual(a.objects[0], threeTwoOne));
8681cb0ef41Sopenharmony_ci
8691cb0ef41Sopenharmony_ci  // *slice;             // error, not allowed
8701cb0ef41Sopenharmony_ci  // a.objects;          // error, not allowed
8711cb0ef41Sopenharmony_ci  // a.objects = slice;  // error, not allowed
8721cb0ef41Sopenharmony_ci
8731cb0ef41Sopenharmony_ci  // TODO(gsps): Currently errors, but should be allowed:
8741cb0ef41Sopenharmony_ci  // const _sameSlice: MutableSlice<Object> = &(*slice);
8751cb0ef41Sopenharmony_ci  // (*slice)[0] : Smi
8761cb0ef41Sopenharmony_ci}
8771cb0ef41Sopenharmony_ci
8781cb0ef41Sopenharmony_ci@export
8791cb0ef41Sopenharmony_cimacro TestSliceEnumeration(implicit context: Context)(): Undefined {
8801cb0ef41Sopenharmony_ci  const fixedArray: FixedArray = AllocateZeroedFixedArray(3);
8811cb0ef41Sopenharmony_ci  for (let i: intptr = 0; i < 3; i++) {
8821cb0ef41Sopenharmony_ci    check(UnsafeCast<Smi>(fixedArray.objects[i]) == 0);
8831cb0ef41Sopenharmony_ci    fixedArray.objects[i] = Convert<Smi>(i) + 3;
8841cb0ef41Sopenharmony_ci  }
8851cb0ef41Sopenharmony_ci
8861cb0ef41Sopenharmony_ci  let slice = &fixedArray.objects;
8871cb0ef41Sopenharmony_ci  for (let i: intptr = 0; i < slice.length; i++) {
8881cb0ef41Sopenharmony_ci    let ref = slice.TryAtIndex(i) otherwise unreachable;
8891cb0ef41Sopenharmony_ci    const value = UnsafeCast<Smi>(*ref);
8901cb0ef41Sopenharmony_ci    check(value == Convert<Smi>(i) + 3);
8911cb0ef41Sopenharmony_ci    *ref = value + 4;
8921cb0ef41Sopenharmony_ci  }
8931cb0ef41Sopenharmony_ci
8941cb0ef41Sopenharmony_ci  let it = slice.Iterator();
8951cb0ef41Sopenharmony_ci  let count: Smi = 0;
8961cb0ef41Sopenharmony_ci  while (true) {
8971cb0ef41Sopenharmony_ci    const value = UnsafeCast<Smi>(it.Next() otherwise break);
8981cb0ef41Sopenharmony_ci    check(value == count + 7);
8991cb0ef41Sopenharmony_ci    count++;
9001cb0ef41Sopenharmony_ci  }
9011cb0ef41Sopenharmony_ci  check(count == 3);
9021cb0ef41Sopenharmony_ci  check(it.Empty());
9031cb0ef41Sopenharmony_ci
9041cb0ef41Sopenharmony_ci  return Undefined;
9051cb0ef41Sopenharmony_ci}
9061cb0ef41Sopenharmony_ci
9071cb0ef41Sopenharmony_ci@export
9081cb0ef41Sopenharmony_cimacro TestStaticAssert(): void {
9091cb0ef41Sopenharmony_ci  static_assert(1 + 2 == 3);
9101cb0ef41Sopenharmony_ci
9111cb0ef41Sopenharmony_ci  static_assert(Convert<uintptr>(5) < Convert<uintptr>(6));
9121cb0ef41Sopenharmony_ci  static_assert(!(Convert<uintptr>(5) < Convert<uintptr>(5)));
9131cb0ef41Sopenharmony_ci  static_assert(!(Convert<uintptr>(6) < Convert<uintptr>(5)));
9141cb0ef41Sopenharmony_ci  static_assert(Convert<uintptr>(5) <= Convert<uintptr>(5));
9151cb0ef41Sopenharmony_ci  static_assert(Convert<uintptr>(5) <= Convert<uintptr>(6));
9161cb0ef41Sopenharmony_ci  static_assert(!(Convert<uintptr>(6) <= Convert<uintptr>(5)));
9171cb0ef41Sopenharmony_ci
9181cb0ef41Sopenharmony_ci  static_assert(Convert<intptr>(-6) < Convert<intptr>(-5));
9191cb0ef41Sopenharmony_ci  static_assert(!(Convert<intptr>(-5) < Convert<intptr>(-5)));
9201cb0ef41Sopenharmony_ci  static_assert(!(Convert<intptr>(-5) < Convert<intptr>(-6)));
9211cb0ef41Sopenharmony_ci  static_assert(Convert<intptr>(-5) <= Convert<intptr>(-5));
9221cb0ef41Sopenharmony_ci  static_assert(Convert<intptr>(-6) <= Convert<intptr>(-5));
9231cb0ef41Sopenharmony_ci  static_assert(!(Convert<intptr>(-5) <= Convert<intptr>(-6)));
9241cb0ef41Sopenharmony_ci}
9251cb0ef41Sopenharmony_ci
9261cb0ef41Sopenharmony_ciclass SmiBox extends HeapObject {
9271cb0ef41Sopenharmony_ci  value: Smi;
9281cb0ef41Sopenharmony_ci  unrelated: Smi;
9291cb0ef41Sopenharmony_ci}
9301cb0ef41Sopenharmony_ci
9311cb0ef41Sopenharmony_cibuiltin NewSmiBox(implicit context: Context)(value: Smi): SmiBox {
9321cb0ef41Sopenharmony_ci  return new SmiBox{value, unrelated: 0};
9331cb0ef41Sopenharmony_ci}
9341cb0ef41Sopenharmony_ci
9351cb0ef41Sopenharmony_ci@export
9361cb0ef41Sopenharmony_cimacro TestLoadEliminationFixed(implicit context: Context)(): void {
9371cb0ef41Sopenharmony_ci  const box = NewSmiBox(123);
9381cb0ef41Sopenharmony_ci  const v1 = box.value;
9391cb0ef41Sopenharmony_ci  box.unrelated = 999;
9401cb0ef41Sopenharmony_ci  const v2 = (box.unrelated == 0) ? box.value : box.value;
9411cb0ef41Sopenharmony_ci  static_assert(TaggedEqual(v1, v2));
9421cb0ef41Sopenharmony_ci
9431cb0ef41Sopenharmony_ci  box.value = 11;
9441cb0ef41Sopenharmony_ci  const v3 = box.value;
9451cb0ef41Sopenharmony_ci  const eleven: Smi = 11;
9461cb0ef41Sopenharmony_ci  static_assert(TaggedEqual(v3, eleven));
9471cb0ef41Sopenharmony_ci}
9481cb0ef41Sopenharmony_ci
9491cb0ef41Sopenharmony_ci@export
9501cb0ef41Sopenharmony_cimacro TestLoadEliminationVariable(implicit context: Context)(): void {
9511cb0ef41Sopenharmony_ci  const a = UnsafeCast<FixedArray>(kEmptyFixedArray);
9521cb0ef41Sopenharmony_ci  const box = NewSmiBox(1);
9531cb0ef41Sopenharmony_ci  const v1 = a.objects[box.value];
9541cb0ef41Sopenharmony_ci  const u1 = a.objects[box.value + 2];
9551cb0ef41Sopenharmony_ci  const v2 = a.objects[box.value];
9561cb0ef41Sopenharmony_ci  const u2 = a.objects[box.value + 2];
9571cb0ef41Sopenharmony_ci  static_assert(TaggedEqual(v1, v2));
9581cb0ef41Sopenharmony_ci  static_assert(TaggedEqual(u1, u2));
9591cb0ef41Sopenharmony_ci}
9601cb0ef41Sopenharmony_ci
9611cb0ef41Sopenharmony_ci@export
9621cb0ef41Sopenharmony_cimacro TestRedundantArrayElementCheck(implicit context: Context)(): Smi {
9631cb0ef41Sopenharmony_ci  const a = kEmptyFixedArray;
9641cb0ef41Sopenharmony_ci  for (let i: Smi = 0; i < a.length; i++) {
9651cb0ef41Sopenharmony_ci    if (a.objects[i] == TheHole) {
9661cb0ef41Sopenharmony_ci      if (a.objects[i] == TheHole) {
9671cb0ef41Sopenharmony_ci        return -1;
9681cb0ef41Sopenharmony_ci      } else {
9691cb0ef41Sopenharmony_ci        static_assert(false);
9701cb0ef41Sopenharmony_ci      }
9711cb0ef41Sopenharmony_ci    }
9721cb0ef41Sopenharmony_ci  }
9731cb0ef41Sopenharmony_ci  return 1;
9741cb0ef41Sopenharmony_ci}
9751cb0ef41Sopenharmony_ci
9761cb0ef41Sopenharmony_ci@export
9771cb0ef41Sopenharmony_cimacro TestRedundantSmiCheck(implicit context: Context)(): Smi {
9781cb0ef41Sopenharmony_ci  const a = kEmptyFixedArray;
9791cb0ef41Sopenharmony_ci  const x = a.objects[1];
9801cb0ef41Sopenharmony_ci  typeswitch (x) {
9811cb0ef41Sopenharmony_ci    case (Smi): {
9821cb0ef41Sopenharmony_ci      Cast<Smi>(x) otherwise VerifiedUnreachable();
9831cb0ef41Sopenharmony_ci      return -1;
9841cb0ef41Sopenharmony_ci    }
9851cb0ef41Sopenharmony_ci    case (Object): {
9861cb0ef41Sopenharmony_ci    }
9871cb0ef41Sopenharmony_ci  }
9881cb0ef41Sopenharmony_ci  return 1;
9891cb0ef41Sopenharmony_ci}
9901cb0ef41Sopenharmony_ci
9911cb0ef41Sopenharmony_cistruct SBox<T: type> {
9921cb0ef41Sopenharmony_ci  value: T;
9931cb0ef41Sopenharmony_ci}
9941cb0ef41Sopenharmony_ci
9951cb0ef41Sopenharmony_ci@export
9961cb0ef41Sopenharmony_cimacro TestGenericStruct1(): intptr {
9971cb0ef41Sopenharmony_ci  const i: intptr = 123;
9981cb0ef41Sopenharmony_ci  let box = SBox{value: i};
9991cb0ef41Sopenharmony_ci  let boxbox: SBox<SBox<intptr>> = SBox{value: box};
10001cb0ef41Sopenharmony_ci  check(box.value == 123);
10011cb0ef41Sopenharmony_ci  boxbox.value.value *= 2;
10021cb0ef41Sopenharmony_ci  check(boxbox.value.value == 246);
10031cb0ef41Sopenharmony_ci  return boxbox.value.value;
10041cb0ef41Sopenharmony_ci}
10051cb0ef41Sopenharmony_ci
10061cb0ef41Sopenharmony_cistruct TestTuple<T1: type, T2: type> {
10071cb0ef41Sopenharmony_ci  const fst: T1;
10081cb0ef41Sopenharmony_ci  const snd: T2;
10091cb0ef41Sopenharmony_ci}
10101cb0ef41Sopenharmony_ci
10111cb0ef41Sopenharmony_cimacro TupleSwap<T1: type, T2: type>(tuple: TestTuple<T1, T2>):
10121cb0ef41Sopenharmony_ci    TestTuple<T2, T1> {
10131cb0ef41Sopenharmony_ci  return TestTuple{fst: tuple.snd, snd: tuple.fst};
10141cb0ef41Sopenharmony_ci}
10151cb0ef41Sopenharmony_ci
10161cb0ef41Sopenharmony_ci@export
10171cb0ef41Sopenharmony_cimacro TestGenericStruct2():
10181cb0ef41Sopenharmony_ci    TestTuple<TestTuple<intptr, Smi>, TestTuple<Smi, intptr>> {
10191cb0ef41Sopenharmony_ci  const intptrAndSmi = TestTuple<intptr, Smi>{fst: 1, snd: 2};
10201cb0ef41Sopenharmony_ci  const smiAndIntptr = TupleSwap(intptrAndSmi);
10211cb0ef41Sopenharmony_ci  check(intptrAndSmi.fst == smiAndIntptr.snd);
10221cb0ef41Sopenharmony_ci  check(intptrAndSmi.snd == smiAndIntptr.fst);
10231cb0ef41Sopenharmony_ci  const tupleTuple =
10241cb0ef41Sopenharmony_ci      TestTuple<TestTuple<intptr, Smi>>{fst: intptrAndSmi, snd: smiAndIntptr};
10251cb0ef41Sopenharmony_ci  return tupleTuple;
10261cb0ef41Sopenharmony_ci}
10271cb0ef41Sopenharmony_ci
10281cb0ef41Sopenharmony_cimacro BranchAndWriteResult(x: Smi, box: SmiBox): bool {
10291cb0ef41Sopenharmony_ci  if (x > 5 || x < 0) {
10301cb0ef41Sopenharmony_ci    box.value = 1;
10311cb0ef41Sopenharmony_ci    return true;
10321cb0ef41Sopenharmony_ci  } else {
10331cb0ef41Sopenharmony_ci    box.value = 2;
10341cb0ef41Sopenharmony_ci    return false;
10351cb0ef41Sopenharmony_ci  }
10361cb0ef41Sopenharmony_ci}
10371cb0ef41Sopenharmony_ci
10381cb0ef41Sopenharmony_ci@export
10391cb0ef41Sopenharmony_cimacro TestBranchOnBoolOptimization(implicit context: Context)(input: Smi):
10401cb0ef41Sopenharmony_ci    void {
10411cb0ef41Sopenharmony_ci  const box = NewSmiBox(1);
10421cb0ef41Sopenharmony_ci  // If the two branches get combined into one, we should be able to determine
10431cb0ef41Sopenharmony_ci  // the value of {box} statically.
10441cb0ef41Sopenharmony_ci  if (BranchAndWriteResult(input, box)) {
10451cb0ef41Sopenharmony_ci    static_assert(box.value == 1);
10461cb0ef41Sopenharmony_ci  } else {
10471cb0ef41Sopenharmony_ci    static_assert(box.value == 2);
10481cb0ef41Sopenharmony_ci  }
10491cb0ef41Sopenharmony_ci}
10501cb0ef41Sopenharmony_ci
10511cb0ef41Sopenharmony_cibitfield struct TestBitFieldStruct extends uint8 {
10521cb0ef41Sopenharmony_ci  a: bool: 1 bit;
10531cb0ef41Sopenharmony_ci  b: uint16: 3 bit;
10541cb0ef41Sopenharmony_ci  c: uint32: 3 bit;
10551cb0ef41Sopenharmony_ci  d: bool: 1 bit;
10561cb0ef41Sopenharmony_ci}
10571cb0ef41Sopenharmony_ci
10581cb0ef41Sopenharmony_ci@export
10591cb0ef41Sopenharmony_cimacro TestBitFieldLoad(
10601cb0ef41Sopenharmony_ci    val: TestBitFieldStruct, expectedA: bool, expectedB: uint16,
10611cb0ef41Sopenharmony_ci    expectedC: uint32, expectedD: bool): void {
10621cb0ef41Sopenharmony_ci  check(val.a == expectedA);
10631cb0ef41Sopenharmony_ci  check(val.b == expectedB);
10641cb0ef41Sopenharmony_ci  check(val.c == expectedC);
10651cb0ef41Sopenharmony_ci  check(val.d == expectedD);
10661cb0ef41Sopenharmony_ci}
10671cb0ef41Sopenharmony_ci
10681cb0ef41Sopenharmony_ci@export
10691cb0ef41Sopenharmony_cimacro TestBitFieldStore(val: TestBitFieldStruct): void {
10701cb0ef41Sopenharmony_ci  let val: TestBitFieldStruct = val;  // Get a mutable local copy.
10711cb0ef41Sopenharmony_ci  const a: bool = val.a;
10721cb0ef41Sopenharmony_ci  const b: uint16 = val.b;
10731cb0ef41Sopenharmony_ci  let c: uint32 = val.c;
10741cb0ef41Sopenharmony_ci  const d: bool = val.d;
10751cb0ef41Sopenharmony_ci
10761cb0ef41Sopenharmony_ci  val.a = !a;
10771cb0ef41Sopenharmony_ci  TestBitFieldLoad(val, !a, b, c, d);
10781cb0ef41Sopenharmony_ci
10791cb0ef41Sopenharmony_ci  c = Unsigned(7 - Signed(val.c));
10801cb0ef41Sopenharmony_ci  val.c = c;
10811cb0ef41Sopenharmony_ci  TestBitFieldLoad(val, !a, b, c, d);
10821cb0ef41Sopenharmony_ci
10831cb0ef41Sopenharmony_ci  val.d = val.b == val.c;
10841cb0ef41Sopenharmony_ci  TestBitFieldLoad(val, !a, b, c, b == c);
10851cb0ef41Sopenharmony_ci}
10861cb0ef41Sopenharmony_ci
10871cb0ef41Sopenharmony_ci@export
10881cb0ef41Sopenharmony_cimacro TestBitFieldInit(a: bool, b: uint16, c: uint32, d: bool): void {
10891cb0ef41Sopenharmony_ci  const val: TestBitFieldStruct = TestBitFieldStruct{a: a, b: b, c: c, d: d};
10901cb0ef41Sopenharmony_ci  TestBitFieldLoad(val, a, b, c, d);
10911cb0ef41Sopenharmony_ci}
10921cb0ef41Sopenharmony_ci
10931cb0ef41Sopenharmony_ci// Some other bitfield structs, to verify getting uintptr values out of word32
10941cb0ef41Sopenharmony_ci// structs and vice versa.
10951cb0ef41Sopenharmony_cibitfield struct TestBitFieldStruct2 extends uint32 {
10961cb0ef41Sopenharmony_ci  a: uintptr: 5 bit;
10971cb0ef41Sopenharmony_ci  b: uintptr: 6 bit;
10981cb0ef41Sopenharmony_ci}
10991cb0ef41Sopenharmony_cibitfield struct TestBitFieldStruct3 extends uintptr {
11001cb0ef41Sopenharmony_ci  c: bool: 1 bit;
11011cb0ef41Sopenharmony_ci  d: uint32: 9 bit;
11021cb0ef41Sopenharmony_ci  e: uintptr: 17 bit;
11031cb0ef41Sopenharmony_ci}
11041cb0ef41Sopenharmony_ci
11051cb0ef41Sopenharmony_ci@export
11061cb0ef41Sopenharmony_cimacro TestBitFieldUintptrOps(
11071cb0ef41Sopenharmony_ci    val2: TestBitFieldStruct2, val3: TestBitFieldStruct3): void {
11081cb0ef41Sopenharmony_ci  let val2: TestBitFieldStruct2 = val2;  // Get a mutable local copy.
11091cb0ef41Sopenharmony_ci  let val3: TestBitFieldStruct3 = val3;  // Get a mutable local copy.
11101cb0ef41Sopenharmony_ci
11111cb0ef41Sopenharmony_ci  // Caller is expected to provide these exact values, so we can verify
11121cb0ef41Sopenharmony_ci  // reading values before starting to write anything.
11131cb0ef41Sopenharmony_ci  check(val2.a == 3);
11141cb0ef41Sopenharmony_ci  check(val2.b == 61);
11151cb0ef41Sopenharmony_ci  check(val3.c);
11161cb0ef41Sopenharmony_ci  check(val3.d == 500);
11171cb0ef41Sopenharmony_ci  check(val3.e == 0x1cc);
11181cb0ef41Sopenharmony_ci
11191cb0ef41Sopenharmony_ci  val2.b = 16;
11201cb0ef41Sopenharmony_ci  check(val2.a == 3);
11211cb0ef41Sopenharmony_ci  check(val2.b == 16);
11221cb0ef41Sopenharmony_ci
11231cb0ef41Sopenharmony_ci  val2.b++;
11241cb0ef41Sopenharmony_ci  check(val2.a == 3);
11251cb0ef41Sopenharmony_ci  check(val2.b == 17);
11261cb0ef41Sopenharmony_ci
11271cb0ef41Sopenharmony_ci  val3.d = 99;
11281cb0ef41Sopenharmony_ci  val3.e = 1234;
11291cb0ef41Sopenharmony_ci  check(val3.c);
11301cb0ef41Sopenharmony_ci  check(val3.d == 99);
11311cb0ef41Sopenharmony_ci  check(val3.e == 1234);
11321cb0ef41Sopenharmony_ci}
11331cb0ef41Sopenharmony_ci
11341cb0ef41Sopenharmony_cibitfield struct TestBitFieldStruct4 extends uint31 {
11351cb0ef41Sopenharmony_ci  a: bool: 1 bit;
11361cb0ef41Sopenharmony_ci  b: int32: 3 bit;
11371cb0ef41Sopenharmony_ci  c: bool: 1 bit;
11381cb0ef41Sopenharmony_ci}
11391cb0ef41Sopenharmony_ci
11401cb0ef41Sopenharmony_cibitfield struct TestBitFieldStruct5 extends uint31 {
11411cb0ef41Sopenharmony_ci  b: int32: 19 bit;
11421cb0ef41Sopenharmony_ci  a: bool: 1 bit;
11431cb0ef41Sopenharmony_ci  c: bool: 1 bit;
11441cb0ef41Sopenharmony_ci}
11451cb0ef41Sopenharmony_ci
11461cb0ef41Sopenharmony_ci@export
11471cb0ef41Sopenharmony_cimacro TestBitFieldMultipleFlags(a: bool, b: int32, c: bool): void {
11481cb0ef41Sopenharmony_ci  const f = TestBitFieldStruct4{a: a, b: b, c: c};
11491cb0ef41Sopenharmony_ci  let simpleExpression = f.a & f.b == 3 & !f.c;
11501cb0ef41Sopenharmony_ci  let expectedReduction = (Signed(f) & 0x1f) == Convert<int32>(1 | 3 << 1);
11511cb0ef41Sopenharmony_ci  static_assert(simpleExpression == expectedReduction);
11521cb0ef41Sopenharmony_ci  simpleExpression = !f.a & f.b == 4 & f.c;
11531cb0ef41Sopenharmony_ci  expectedReduction = (Signed(f) & 0x1f) == Convert<int32>(4 << 1 | 1 << 4);
11541cb0ef41Sopenharmony_ci  static_assert(simpleExpression == expectedReduction);
11551cb0ef41Sopenharmony_ci  simpleExpression = f.b == 0 & f.c;
11561cb0ef41Sopenharmony_ci  expectedReduction = (Signed(f) & 0x1e) == Convert<int32>(1 << 4);
11571cb0ef41Sopenharmony_ci  static_assert(simpleExpression == expectedReduction);
11581cb0ef41Sopenharmony_ci  simpleExpression = f.a & f.c;
11591cb0ef41Sopenharmony_ci  expectedReduction = (Signed(f) & 0x11) == Convert<int32>(1 | 1 << 4);
11601cb0ef41Sopenharmony_ci  static_assert(simpleExpression == expectedReduction);
11611cb0ef41Sopenharmony_ci  const f2 = TestBitFieldStruct5{b: b, a: a, c: c};
11621cb0ef41Sopenharmony_ci  simpleExpression = !f2.a & f2.b == 1234 & f2.c;
11631cb0ef41Sopenharmony_ci  expectedReduction = (Signed(f2) & 0x1fffff) == Convert<int32>(1234 | 1 << 20);
11641cb0ef41Sopenharmony_ci  static_assert(simpleExpression == expectedReduction);
11651cb0ef41Sopenharmony_ci  simpleExpression = !f2.a & !f2.c;
11661cb0ef41Sopenharmony_ci  expectedReduction = (Signed(f2) & 0x180000) == Convert<int32>(0);
11671cb0ef41Sopenharmony_ci  static_assert(simpleExpression == expectedReduction);
11681cb0ef41Sopenharmony_ci}
11691cb0ef41Sopenharmony_ci
11701cb0ef41Sopenharmony_ci@export
11711cb0ef41Sopenharmony_ciclass ExportedSubClass extends ExportedSubClassBase {
11721cb0ef41Sopenharmony_ci  c_field: int32;
11731cb0ef41Sopenharmony_ci  d_field: int32;
11741cb0ef41Sopenharmony_ci  e_field: Smi;
11751cb0ef41Sopenharmony_ci}
11761cb0ef41Sopenharmony_ci
11771cb0ef41Sopenharmony_ci@export
11781cb0ef41Sopenharmony_ciclass ExportedSubClassBase extends HeapObject {
11791cb0ef41Sopenharmony_ci  a: HeapObject;
11801cb0ef41Sopenharmony_ci  b: HeapObject;
11811cb0ef41Sopenharmony_ci}
11821cb0ef41Sopenharmony_ci
11831cb0ef41Sopenharmony_ci@abstract
11841cb0ef41Sopenharmony_ciclass AbstractInternalClass extends HeapObject {
11851cb0ef41Sopenharmony_ci}
11861cb0ef41Sopenharmony_ci
11871cb0ef41Sopenharmony_ciclass AbstractInternalClassSubclass1 extends AbstractInternalClass {}
11881cb0ef41Sopenharmony_ci
11891cb0ef41Sopenharmony_ciclass AbstractInternalClassSubclass2 extends AbstractInternalClass {}
11901cb0ef41Sopenharmony_ci
11911cb0ef41Sopenharmony_ciclass InternalClassWithSmiElements extends FixedArrayBase {
11921cb0ef41Sopenharmony_ci  data: Smi;
11931cb0ef41Sopenharmony_ci  object: Oddball;
11941cb0ef41Sopenharmony_ci  entries[length]: Smi;
11951cb0ef41Sopenharmony_ci}
11961cb0ef41Sopenharmony_ci
11971cb0ef41Sopenharmony_cistruct InternalClassStructElement {
11981cb0ef41Sopenharmony_ci  a: Smi;
11991cb0ef41Sopenharmony_ci  b: Smi;
12001cb0ef41Sopenharmony_ci}
12011cb0ef41Sopenharmony_ci
12021cb0ef41Sopenharmony_ciclass InternalClassWithStructElements extends HeapObject {
12031cb0ef41Sopenharmony_ci  dummy1: int32;
12041cb0ef41Sopenharmony_ci  dummy2: int32;
12051cb0ef41Sopenharmony_ci  const count: Smi;
12061cb0ef41Sopenharmony_ci  data: Smi;
12071cb0ef41Sopenharmony_ci  object: Object;
12081cb0ef41Sopenharmony_ci  entries[count]: Smi;
12091cb0ef41Sopenharmony_ci  more_entries[count]: InternalClassStructElement;
12101cb0ef41Sopenharmony_ci}
12111cb0ef41Sopenharmony_ci
12121cb0ef41Sopenharmony_cistruct SmiGeneratorIterator {
12131cb0ef41Sopenharmony_ci  macro Next(): Smi labels _NoMore {
12141cb0ef41Sopenharmony_ci    return this.value++;
12151cb0ef41Sopenharmony_ci  }
12161cb0ef41Sopenharmony_ci  value: Smi;
12171cb0ef41Sopenharmony_ci}
12181cb0ef41Sopenharmony_ci
12191cb0ef41Sopenharmony_cistruct InternalClassStructElementGeneratorIterator {
12201cb0ef41Sopenharmony_ci  macro Next(): InternalClassStructElement labels _NoMore {
12211cb0ef41Sopenharmony_ci    return InternalClassStructElement{a: this.value++, b: this.value++};
12221cb0ef41Sopenharmony_ci  }
12231cb0ef41Sopenharmony_ci  value: Smi;
12241cb0ef41Sopenharmony_ci}
12251cb0ef41Sopenharmony_ci
12261cb0ef41Sopenharmony_ci@export
12271cb0ef41Sopenharmony_cimacro TestFullyGeneratedClassWithElements(): void {
12281cb0ef41Sopenharmony_ci  // Test creation, initialization and access of a fully generated class with
12291cb0ef41Sopenharmony_ci  // simple (Smi) elements
12301cb0ef41Sopenharmony_ci  const length: Smi = Convert<Smi>(3);
12311cb0ef41Sopenharmony_ci  const object1 = new InternalClassWithSmiElements{
12321cb0ef41Sopenharmony_ci    length,
12331cb0ef41Sopenharmony_ci    data: 0,
12341cb0ef41Sopenharmony_ci    object: Undefined,
12351cb0ef41Sopenharmony_ci    entries: ...SmiGeneratorIterator {
12361cb0ef41Sopenharmony_ci      value: 11
12371cb0ef41Sopenharmony_ci    }
12381cb0ef41Sopenharmony_ci  };
12391cb0ef41Sopenharmony_ci  dcheck(object1.length == 3);
12401cb0ef41Sopenharmony_ci  dcheck(object1.data == 0);
12411cb0ef41Sopenharmony_ci  dcheck(object1.object == Undefined);
12421cb0ef41Sopenharmony_ci  dcheck(object1.entries[0] == 11);
12431cb0ef41Sopenharmony_ci  dcheck(object1.entries[1] == 12);
12441cb0ef41Sopenharmony_ci  dcheck(object1.entries[2] == 13);
12451cb0ef41Sopenharmony_ci
12461cb0ef41Sopenharmony_ci  // Test creation, initialization and access of a fully generated class
12471cb0ef41Sopenharmony_ci  // with elements that are a struct.
12481cb0ef41Sopenharmony_ci  const object2 = new InternalClassWithStructElements{
12491cb0ef41Sopenharmony_ci    dummy1: 44,
12501cb0ef41Sopenharmony_ci    dummy2: 45,
12511cb0ef41Sopenharmony_ci    count: length,
12521cb0ef41Sopenharmony_ci    data: 55,
12531cb0ef41Sopenharmony_ci    object: Undefined,
12541cb0ef41Sopenharmony_ci    entries: ...SmiGeneratorIterator{value: 3},
12551cb0ef41Sopenharmony_ci    more_entries: ...InternalClassStructElementGeneratorIterator {
12561cb0ef41Sopenharmony_ci      value: 1
12571cb0ef41Sopenharmony_ci    }
12581cb0ef41Sopenharmony_ci  };
12591cb0ef41Sopenharmony_ci
12601cb0ef41Sopenharmony_ci  dcheck(object2.dummy1 == 44);
12611cb0ef41Sopenharmony_ci  dcheck(object2.dummy2 == 45);
12621cb0ef41Sopenharmony_ci  dcheck(object2.count == 3);
12631cb0ef41Sopenharmony_ci  dcheck(object2.data == 55);
12641cb0ef41Sopenharmony_ci  dcheck(object2.object == Undefined);
12651cb0ef41Sopenharmony_ci  dcheck(object2.entries[0] == 3);
12661cb0ef41Sopenharmony_ci  dcheck(object2.entries[1] == 4);
12671cb0ef41Sopenharmony_ci  dcheck(object2.entries[2] == 5);
12681cb0ef41Sopenharmony_ci  dcheck(object2.more_entries[0].a == 1);
12691cb0ef41Sopenharmony_ci  dcheck(object2.more_entries[0].b == 2);
12701cb0ef41Sopenharmony_ci  dcheck(object2.more_entries[1].a == 3);
12711cb0ef41Sopenharmony_ci  dcheck(object2.more_entries[1].b == 4);
12721cb0ef41Sopenharmony_ci  dcheck(object2.more_entries[2].a == 5);
12731cb0ef41Sopenharmony_ci  dcheck(object2.more_entries[2].b == 6);
12741cb0ef41Sopenharmony_ci}
12751cb0ef41Sopenharmony_ci
12761cb0ef41Sopenharmony_ci@export
12771cb0ef41Sopenharmony_cimacro TestFullyGeneratedClassFromCpp(): ExportedSubClass {
12781cb0ef41Sopenharmony_ci  return new
12791cb0ef41Sopenharmony_ci  ExportedSubClass{a: Null, b: Null, c_field: 7, d_field: 8, e_field: 9};
12801cb0ef41Sopenharmony_ci}
12811cb0ef41Sopenharmony_ci
12821cb0ef41Sopenharmony_ci@export
12831cb0ef41Sopenharmony_ciclass ExportedSubClass2 extends ExportedSubClassBase {
12841cb0ef41Sopenharmony_ci  x_field: int32;
12851cb0ef41Sopenharmony_ci  y_field: int32;
12861cb0ef41Sopenharmony_ci  z_field: Smi;
12871cb0ef41Sopenharmony_ci}
12881cb0ef41Sopenharmony_ci
12891cb0ef41Sopenharmony_ci@export
12901cb0ef41Sopenharmony_cimacro TestGeneratedCastOperators(implicit context: Context)(): void {
12911cb0ef41Sopenharmony_ci  const a = new
12921cb0ef41Sopenharmony_ci  ExportedSubClass{a: Null, b: Null, c_field: 3, d_field: 4, e_field: 5};
12931cb0ef41Sopenharmony_ci  const b = new ExportedSubClassBase{a: Undefined, b: Null};
12941cb0ef41Sopenharmony_ci  const c = new
12951cb0ef41Sopenharmony_ci  ExportedSubClass2{a: Null, b: Null, x_field: 3, y_field: 4, z_field: 5};
12961cb0ef41Sopenharmony_ci  const aO: Object = a;
12971cb0ef41Sopenharmony_ci  const bO: Object = b;
12981cb0ef41Sopenharmony_ci  const cO: Object = c;
12991cb0ef41Sopenharmony_ci  dcheck(Is<ExportedSubClassBase>(aO));
13001cb0ef41Sopenharmony_ci  dcheck(Is<ExportedSubClass>(aO));
13011cb0ef41Sopenharmony_ci  dcheck(!Is<ExportedSubClass2>(aO));
13021cb0ef41Sopenharmony_ci  dcheck(Is<ExportedSubClassBase>(bO));
13031cb0ef41Sopenharmony_ci  dcheck(!Is<ExportedSubClass>(bO));
13041cb0ef41Sopenharmony_ci  dcheck(Is<ExportedSubClassBase>(cO));
13051cb0ef41Sopenharmony_ci  dcheck(!Is<ExportedSubClass>(cO));
13061cb0ef41Sopenharmony_ci  dcheck(Is<ExportedSubClass2>(cO));
13071cb0ef41Sopenharmony_ci
13081cb0ef41Sopenharmony_ci  const jsf: JSFunction =
13091cb0ef41Sopenharmony_ci      *NativeContextSlot(ContextSlot::REGEXP_FUNCTION_INDEX);
13101cb0ef41Sopenharmony_ci  dcheck(!Is<JSSloppyArgumentsObject>(jsf));
13111cb0ef41Sopenharmony_ci
13121cb0ef41Sopenharmony_ci  const parameterValues = NewFixedArray(0, ConstantIterator(TheHole));
13131cb0ef41Sopenharmony_ci  const elements = NewSloppyArgumentsElements(
13141cb0ef41Sopenharmony_ci      0, context, parameterValues, ConstantIterator(TheHole));
13151cb0ef41Sopenharmony_ci  const fastArgs = arguments::NewJSFastAliasedArgumentsObject(
13161cb0ef41Sopenharmony_ci      elements, Convert<Smi>(0), jsf);
13171cb0ef41Sopenharmony_ci  dcheck(Is<JSArgumentsObject>(fastArgs));
13181cb0ef41Sopenharmony_ci}
13191cb0ef41Sopenharmony_ci
13201cb0ef41Sopenharmony_ciextern runtime InYoungGeneration(implicit context: Context)(HeapObject):
13211cb0ef41Sopenharmony_ci    Boolean;
13221cb0ef41Sopenharmony_ci
13231cb0ef41Sopenharmony_ci@export
13241cb0ef41Sopenharmony_cimacro TestNewPretenured(implicit context: Context)(): void {
13251cb0ef41Sopenharmony_ci  const obj = new (Pretenured) ExportedSubClassBase{a: Undefined, b: Null};
13261cb0ef41Sopenharmony_ci  dcheck(Is<ExportedSubClassBase>(obj));
13271cb0ef41Sopenharmony_ci  dcheck(InYoungGeneration(obj) == False);
13281cb0ef41Sopenharmony_ci}
13291cb0ef41Sopenharmony_ci
13301cb0ef41Sopenharmony_ci@export
13311cb0ef41Sopenharmony_cimacro TestWord8Phi(): void {
13321cb0ef41Sopenharmony_ci  for (let i: intptr = -5; i < 5; ++i) {
13331cb0ef41Sopenharmony_ci    let x: int8;
13341cb0ef41Sopenharmony_ci    if (i == -1) {
13351cb0ef41Sopenharmony_ci      x = -1;
13361cb0ef41Sopenharmony_ci    } else {
13371cb0ef41Sopenharmony_ci      x = Convert<int8>(i);
13381cb0ef41Sopenharmony_ci    }
13391cb0ef41Sopenharmony_ci    check(x == Convert<int8>(i));
13401cb0ef41Sopenharmony_ci  }
13411cb0ef41Sopenharmony_ci}
13421cb0ef41Sopenharmony_ci
13431cb0ef41Sopenharmony_ci@export
13441cb0ef41Sopenharmony_cimacro TestOffHeapSlice(ptr: RawPtr<char8>, length: intptr): void {
13451cb0ef41Sopenharmony_ci  const string = UnsafeCast<SeqOneByteString>(Convert<String>('Hello World!'));
13461cb0ef41Sopenharmony_ci
13471cb0ef41Sopenharmony_ci  check(*torque_internal::unsafe::NewOffHeapReference(ptr) == string.chars[0]);
13481cb0ef41Sopenharmony_ci
13491cb0ef41Sopenharmony_ci  let offHeapSlice = torque_internal::unsafe::NewOffHeapConstSlice(ptr, length);
13501cb0ef41Sopenharmony_ci  let onHeapSlice = &string.chars;
13511cb0ef41Sopenharmony_ci  for (let i: intptr = 0; i < onHeapSlice.length; ++i) {
13521cb0ef41Sopenharmony_ci    check(*onHeapSlice.AtIndex(i) == *offHeapSlice.AtIndex(i));
13531cb0ef41Sopenharmony_ci  }
13541cb0ef41Sopenharmony_ci}
13551cb0ef41Sopenharmony_ci
13561cb0ef41Sopenharmony_cistruct TwoValues {
13571cb0ef41Sopenharmony_ci  a: Smi;
13581cb0ef41Sopenharmony_ci  b: Map;
13591cb0ef41Sopenharmony_ci}
13601cb0ef41Sopenharmony_ci
13611cb0ef41Sopenharmony_cibuiltin ReturnTwoValues(implicit context: Context)(
13621cb0ef41Sopenharmony_ci    value: Smi, obj: HeapObject): TwoValues {
13631cb0ef41Sopenharmony_ci  return TwoValues{a: value + 1, b: obj.map};
13641cb0ef41Sopenharmony_ci}
13651cb0ef41Sopenharmony_ci
13661cb0ef41Sopenharmony_ci@export
13671cb0ef41Sopenharmony_cimacro TestCallMultiReturnBuiltin(implicit context: Context)(): void {
13681cb0ef41Sopenharmony_ci  const result = ReturnTwoValues(444, FromConstexpr<String>('hi'));
13691cb0ef41Sopenharmony_ci  check(result.a == 445);
13701cb0ef41Sopenharmony_ci  check(result.b == FromConstexpr<String>('hi').map);
13711cb0ef41Sopenharmony_ci}
13721cb0ef41Sopenharmony_ci
13731cb0ef41Sopenharmony_ci@export
13741cb0ef41Sopenharmony_cimacro TestRunLazyTwice(lazySmi: Lazy<Smi>): Smi {
13751cb0ef41Sopenharmony_ci  const firstResult = RunLazy(lazySmi);
13761cb0ef41Sopenharmony_ci  const secondResult = RunLazy(lazySmi);
13771cb0ef41Sopenharmony_ci  return firstResult + secondResult;
13781cb0ef41Sopenharmony_ci}
13791cb0ef41Sopenharmony_ci
13801cb0ef41Sopenharmony_cimacro GetLazySmi(): Smi {
13811cb0ef41Sopenharmony_ci  return 3;
13821cb0ef41Sopenharmony_ci}
13831cb0ef41Sopenharmony_ci
13841cb0ef41Sopenharmony_cimacro AddTwoSmiValues(a: Smi, b: Smi): Smi {
13851cb0ef41Sopenharmony_ci  return a + b;
13861cb0ef41Sopenharmony_ci}
13871cb0ef41Sopenharmony_ci
13881cb0ef41Sopenharmony_cimacro AddSmiAndConstexprValues(a: Smi, b: constexpr int31): Smi {
13891cb0ef41Sopenharmony_ci  return a + b;
13901cb0ef41Sopenharmony_ci}
13911cb0ef41Sopenharmony_ci
13921cb0ef41Sopenharmony_ci@export
13931cb0ef41Sopenharmony_cimacro TestCreateLazyNodeFromTorque(): void {
13941cb0ef41Sopenharmony_ci  const lazy = %MakeLazy<Smi>('GetLazySmi');
13951cb0ef41Sopenharmony_ci  const result = TestRunLazyTwice(lazy);
13961cb0ef41Sopenharmony_ci  check(result == 6);
13971cb0ef41Sopenharmony_ci
13981cb0ef41Sopenharmony_ci  // The macro can also be referred to using namespace qualifications.
13991cb0ef41Sopenharmony_ci  const lazy2 = %MakeLazy<Smi>('test::GetLazySmi');
14001cb0ef41Sopenharmony_ci  const result2 = TestRunLazyTwice(lazy2);
14011cb0ef41Sopenharmony_ci  check(result2 == 6);
14021cb0ef41Sopenharmony_ci
14031cb0ef41Sopenharmony_ci  // We can save params to the macro. The most common usage is likely a
14041cb0ef41Sopenharmony_ci  // single-arg macro that just returns the arg, but we can use any number of
14051cb0ef41Sopenharmony_ci  // params.
14061cb0ef41Sopenharmony_ci  const lazy3 = %MakeLazy<Smi>('AddTwoSmiValues', 5, 6);
14071cb0ef41Sopenharmony_ci  const result3 = TestRunLazyTwice(lazy3);
14081cb0ef41Sopenharmony_ci  check(result3 == 22);
14091cb0ef41Sopenharmony_ci
14101cb0ef41Sopenharmony_ci  // It's okay if some of the params are constexpr and some aren't.
14111cb0ef41Sopenharmony_ci  const lazy4 = %MakeLazy<Smi>('AddSmiAndConstexprValues', 7, 8);
14121cb0ef41Sopenharmony_ci  const result4 = TestRunLazyTwice(lazy4);
14131cb0ef41Sopenharmony_ci  check(result4 == 30);
14141cb0ef41Sopenharmony_ci}
14151cb0ef41Sopenharmony_ci}
1416