// 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. module 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): bool { return ((kind == UINT8_ELEMENTS) || (kind == UINT16_ELEMENTS)); } macro ElementsKindTestHelper3(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(String, Smi) { goto Label3('foo', 7); } macro TestConstexpr1() { check(convert(IsFastElementsKind(PACKED_SMI_ELEMENTS))); } macro TestConstexprIf() { check(ElementsKindTestHelper1(UINT8_ELEMENTS)); check(ElementsKindTestHelper1(UINT16_ELEMENTS)); check(!ElementsKindTestHelper1(UINT32_ELEMENTS)); } macro TestConstexprReturn() { check(convert(ElementsKindTestHelper3(UINT8_ELEMENTS))); check(convert(ElementsKindTestHelper3(UINT16_ELEMENTS))); check(!convert(ElementsKindTestHelper3(UINT32_ELEMENTS))); check(convert(!ElementsKindTestHelper3(UINT32_ELEMENTS))); } macro TestGotoLabel(): Boolean { try { LabelTestHelper1() otherwise Label1; } label Label1 { return True; } } macro TestGotoLabelWithOneParameter(): Boolean { try { LabelTestHelper2() otherwise Label2; } label Label2(smi: Smi) { check(smi == 42); return True; } } macro TestGotoLabelWithTwoParameters(): Boolean { try { LabelTestHelper3() otherwise Label3; } label Label3(str: String, smi: Smi) { check(str == 'foo'); check(smi == 7); return True; } } builtin GenericBuiltinTest(c: Context, param: T): Object { return Null; } GenericBuiltinTest(c: Context, param: Object): Object { return param; } macro TestBuiltinSpecialization(c: Context) { check(GenericBuiltinTest(c, 0) == Null); check(GenericBuiltinTest(c, 1) == Null); check(GenericBuiltinTest(c, Undefined) == Undefined); check(GenericBuiltinTest(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; } } macro TestPartiallyUnusedLabel(): Boolean { let r1: bool = CallLabelTestHelper4(true); let r2: bool = CallLabelTestHelper4(false); if (r1 && !r2) return True; else return False; } macro GenericMacroTest(param: T): Object { return Undefined; } GenericMacroTest(param2: Object): Object { return param2; } macro GenericMacroTestWithLabels(param: T): Object labels X { return Undefined; } GenericMacroTestWithLabels(param2: Object): Object labels Y { return param2; } macro TestMacroSpecialization() { try { check(GenericMacroTest(0) == Undefined); check(GenericMacroTest(1) == Undefined); check(GenericMacroTest(Null) == Null); check(GenericMacroTest(False) == False); check(GenericMacroTest(True) == True); check(GenericMacroTestWithLabels(0) otherwise Fail == Undefined); check(GenericMacroTestWithLabels(0) otherwise Fail == Undefined); check(GenericMacroTestWithLabels(Null) otherwise Fail == Null); check(GenericMacroTestWithLabels(False) otherwise Fail == False); } label Fail { unreachable; } } builtin TestHelperPlus1(context : Context, x : Smi) : Smi { return x + 1; } builtin TestHelperPlus2(context : Context, x : Smi) : Smi { return x + 2; } macro TestFunctionPointers(context : Context) : Boolean { let fptr : builtin(Context, Smi) => Smi = TestHelperPlus1; check(fptr(context, 42) == 43); fptr = TestHelperPlus2; check(fptr(context, 42) == 44); return True; } macro TestVariableRedeclaration(context : Context) : Boolean { let var1 : Number = 42 == 0 ? 0 : 1; let var2 : Number = 42 == 0 ? 1 : 0; return True; } macro TestFunctionPointerToGeneric(c: Context) { let fptr1: builtin(Context, Smi) => Object = GenericBuiltinTest; let fptr2: builtin(Context, Object) => Object = GenericBuiltinTest; check(fptr1(c, 0) == Null); check(fptr1(c, 1) == Null); check(fptr2(c, Undefined) == Undefined); check(fptr2(c, Undefined) == Undefined); } type SmiToSmi = builtin(Smi) => Smi; macro TestTypeAlias(x : SmiToSmi) : Code { return x; } macro TestUnsafeCast(c: Context, n: Number): Boolean { if (TaggedIsSmi(n)) { let m: Smi = unsafe_cast(n); check(TestHelperPlus1(c, m) == 11); return True; } return False; } }