2018-05-13 10:10:44 +00:00
|
|
|
// 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.
|
|
|
|
|
2018-11-13 13:00:34 +00:00
|
|
|
namespace test {
|
2018-05-16 09:45:07 +00:00
|
|
|
macro ElementsKindTestHelper1(kind: constexpr ElementsKind): bool {
|
2018-09-24 09:28:48 +00:00
|
|
|
if constexpr ((kind == UINT8_ELEMENTS) || (kind == UINT16_ELEMENTS)) {
|
|
|
|
return true;
|
|
|
|
} else {
|
2018-05-16 09:45:07 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2018-05-13 10:10:44 +00:00
|
|
|
|
2018-05-16 09:45:07 +00:00
|
|
|
macro ElementsKindTestHelper2(kind: constexpr ElementsKind): bool {
|
|
|
|
return ((kind == UINT8_ELEMENTS) || (kind == UINT16_ELEMENTS));
|
2018-05-13 10:10:44 +00:00
|
|
|
}
|
|
|
|
|
2018-05-16 09:45:07 +00:00
|
|
|
macro ElementsKindTestHelper3(kind: constexpr ElementsKind): constexpr bool {
|
|
|
|
return ((kind == UINT8_ELEMENTS) || (kind == UINT16_ELEMENTS));
|
|
|
|
}
|
2018-05-13 10:10:44 +00:00
|
|
|
|
2018-05-16 09:45:07 +00:00
|
|
|
macro LabelTestHelper1(): never
|
2018-09-24 09:28:48 +00:00
|
|
|
labels Label1 {
|
2018-05-16 09:45:07 +00:00
|
|
|
goto Label1;
|
|
|
|
}
|
2018-05-13 10:10:44 +00:00
|
|
|
|
2018-05-16 09:45:07 +00:00
|
|
|
macro LabelTestHelper2(): never
|
2018-09-24 09:28:48 +00:00
|
|
|
labels Label2(Smi) {
|
2018-05-16 09:45:07 +00:00
|
|
|
goto Label2(42);
|
|
|
|
}
|
2018-05-13 14:24:08 +00:00
|
|
|
|
2018-05-16 09:45:07 +00:00
|
|
|
macro LabelTestHelper3(): never
|
2018-09-24 09:28:48 +00:00
|
|
|
labels Label3(String, Smi) {
|
2018-05-16 09:45:07 +00:00
|
|
|
goto Label3('foo', 7);
|
|
|
|
}
|
2018-05-13 14:24:08 +00:00
|
|
|
|
2018-05-16 09:45:07 +00:00
|
|
|
macro TestConstexpr1() {
|
2018-09-11 13:15:02 +00:00
|
|
|
check(FromConstexpr<bool>(IsFastElementsKind(PACKED_SMI_ELEMENTS)));
|
2018-05-16 09:45:07 +00:00
|
|
|
}
|
2018-05-13 14:24:08 +00:00
|
|
|
|
2018-05-16 09:45:07 +00:00
|
|
|
macro TestConstexprIf() {
|
2018-05-24 14:09:12 +00:00
|
|
|
check(ElementsKindTestHelper1(UINT8_ELEMENTS));
|
|
|
|
check(ElementsKindTestHelper1(UINT16_ELEMENTS));
|
|
|
|
check(!ElementsKindTestHelper1(UINT32_ELEMENTS));
|
2018-05-16 09:45:07 +00:00
|
|
|
}
|
2018-05-13 10:10:44 +00:00
|
|
|
|
2018-05-16 09:45:07 +00:00
|
|
|
macro TestConstexprReturn() {
|
2018-09-11 13:15:02 +00:00
|
|
|
check(FromConstexpr<bool>(ElementsKindTestHelper3(UINT8_ELEMENTS)));
|
|
|
|
check(FromConstexpr<bool>(ElementsKindTestHelper3(UINT16_ELEMENTS)));
|
|
|
|
check(!FromConstexpr<bool>(ElementsKindTestHelper3(UINT32_ELEMENTS)));
|
|
|
|
check(FromConstexpr<bool>(!ElementsKindTestHelper3(UINT32_ELEMENTS)));
|
2018-05-16 09:45:07 +00:00
|
|
|
}
|
2018-05-13 10:10:44 +00:00
|
|
|
|
2018-05-16 09:45:07 +00:00
|
|
|
macro TestGotoLabel(): Boolean {
|
|
|
|
try {
|
|
|
|
LabelTestHelper1() otherwise Label1;
|
|
|
|
}
|
|
|
|
label Label1 {
|
|
|
|
return True;
|
|
|
|
}
|
|
|
|
}
|
2018-05-13 10:10:44 +00:00
|
|
|
|
2018-05-16 09:45:07 +00:00
|
|
|
macro TestGotoLabelWithOneParameter(): Boolean {
|
|
|
|
try {
|
|
|
|
LabelTestHelper2() otherwise Label2;
|
|
|
|
}
|
|
|
|
label Label2(smi: Smi) {
|
2018-05-24 14:09:12 +00:00
|
|
|
check(smi == 42);
|
2018-05-16 09:45:07 +00:00
|
|
|
return True;
|
|
|
|
}
|
2018-05-13 14:24:08 +00:00
|
|
|
}
|
2018-05-16 09:45:07 +00:00
|
|
|
|
|
|
|
macro TestGotoLabelWithTwoParameters(): Boolean {
|
|
|
|
try {
|
|
|
|
LabelTestHelper3() otherwise Label3;
|
|
|
|
}
|
|
|
|
label Label3(str: String, smi: Smi) {
|
2018-05-24 14:09:12 +00:00
|
|
|
check(str == 'foo');
|
|
|
|
check(smi == 7);
|
2018-05-16 09:45:07 +00:00
|
|
|
return True;
|
|
|
|
}
|
2018-05-13 14:24:08 +00:00
|
|
|
}
|
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
builtin GenericBuiltinTest<T: type>(c: Context, param: T): Object {
|
2018-05-16 09:45:07 +00:00
|
|
|
return Null;
|
2018-05-13 14:24:08 +00:00
|
|
|
}
|
2018-05-16 09:45:07 +00:00
|
|
|
|
|
|
|
GenericBuiltinTest<Object>(c: Context, param: Object): Object {
|
|
|
|
return param;
|
2018-05-13 14:24:08 +00:00
|
|
|
}
|
|
|
|
|
2018-05-16 09:45:07 +00:00
|
|
|
macro TestBuiltinSpecialization(c: Context) {
|
2018-05-24 14:09:12 +00:00
|
|
|
check(GenericBuiltinTest<Smi>(c, 0) == Null);
|
|
|
|
check(GenericBuiltinTest<Smi>(c, 1) == Null);
|
|
|
|
check(GenericBuiltinTest<Object>(c, Undefined) == Undefined);
|
|
|
|
check(GenericBuiltinTest<Object>(c, Undefined) == Undefined);
|
2018-05-13 14:24:08 +00:00
|
|
|
}
|
2018-05-16 09:45:07 +00:00
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
macro LabelTestHelper4(flag: constexpr bool): never
|
|
|
|
labels Label4, Label5 {
|
|
|
|
if constexpr (flag) {
|
2018-08-02 15:10:24 +00:00
|
|
|
goto Label4;
|
|
|
|
} else {
|
2018-05-16 09:45:07 +00:00
|
|
|
goto Label5;
|
2018-08-02 15:10:24 +00:00
|
|
|
}
|
2018-05-13 14:24:08 +00:00
|
|
|
}
|
|
|
|
|
2018-05-16 09:45:07 +00:00
|
|
|
macro CallLabelTestHelper4(flag: constexpr bool): bool {
|
|
|
|
try {
|
|
|
|
LabelTestHelper4(flag) otherwise Label4, Label5;
|
|
|
|
}
|
|
|
|
label Label4 {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
label Label5 {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2018-05-14 10:53:04 +00:00
|
|
|
|
2018-05-16 09:45:07 +00:00
|
|
|
macro TestPartiallyUnusedLabel(): Boolean {
|
|
|
|
let r1: bool = CallLabelTestHelper4(true);
|
|
|
|
let r2: bool = CallLabelTestHelper4(false);
|
|
|
|
|
2018-08-02 15:10:24 +00:00
|
|
|
if (r1 && !r2) {
|
2018-05-16 09:45:07 +00:00
|
|
|
return True;
|
2018-08-02 15:10:24 +00:00
|
|
|
} else {
|
2018-05-16 09:45:07 +00:00
|
|
|
return False;
|
2018-08-02 15:10:24 +00:00
|
|
|
}
|
2018-05-14 10:53:04 +00:00
|
|
|
}
|
2018-05-16 09:45:07 +00:00
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
macro GenericMacroTest<T: type>(param: T): Object {
|
2018-05-16 09:45:07 +00:00
|
|
|
return Undefined;
|
2018-05-14 10:53:04 +00:00
|
|
|
}
|
2018-05-16 09:45:07 +00:00
|
|
|
|
|
|
|
GenericMacroTest<Object>(param2: Object): Object {
|
|
|
|
return param2;
|
2018-05-14 10:53:04 +00:00
|
|
|
}
|
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
macro GenericMacroTestWithLabels<T: type>(param: T): Object
|
|
|
|
labels X {
|
2018-05-16 09:45:07 +00:00
|
|
|
return Undefined;
|
|
|
|
}
|
2018-05-14 10:53:04 +00:00
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
GenericMacroTestWithLabels<Object>(param2: Object): Object
|
|
|
|
labels Y {
|
2018-10-04 20:45:31 +00:00
|
|
|
return Cast<Smi>(param2) otherwise Y;
|
2018-05-16 09:45:07 +00:00
|
|
|
}
|
2018-05-14 10:53:04 +00:00
|
|
|
|
2018-05-16 09:45:07 +00:00
|
|
|
macro TestMacroSpecialization() {
|
|
|
|
try {
|
2018-10-04 20:45:31 +00:00
|
|
|
const smi0: Smi = 0;
|
2018-05-24 14:09:12 +00:00
|
|
|
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);
|
2018-10-08 13:50:46 +00:00
|
|
|
check((GenericMacroTestWithLabels<Smi>(0) otherwise Fail) == Undefined);
|
|
|
|
check((GenericMacroTestWithLabels<Smi>(0) otherwise Fail) == Undefined);
|
|
|
|
check((GenericMacroTestWithLabels<Object>(smi0) otherwise Fail) == smi0);
|
2018-10-04 20:45:31 +00:00
|
|
|
try {
|
|
|
|
GenericMacroTestWithLabels<Object>(False) otherwise Expected;
|
|
|
|
}
|
|
|
|
label Expected {}
|
2018-05-16 09:45:07 +00:00
|
|
|
}
|
|
|
|
label Fail {
|
|
|
|
unreachable;
|
|
|
|
}
|
|
|
|
}
|
2018-05-16 14:00:35 +00:00
|
|
|
|
2018-07-17 16:20:53 +00:00
|
|
|
builtin TestHelperPlus1(context: Context, x: Smi): Smi {
|
2018-05-16 14:00:35 +00:00
|
|
|
return x + 1;
|
|
|
|
}
|
2018-07-17 16:20:53 +00:00
|
|
|
builtin TestHelperPlus2(context: Context, x: Smi): Smi {
|
2018-05-16 14:00:35 +00:00
|
|
|
return x + 2;
|
|
|
|
}
|
|
|
|
|
2018-07-17 16:20:53 +00:00
|
|
|
macro TestFunctionPointers(context: Context): Boolean {
|
|
|
|
let fptr: builtin(Context, Smi) => Smi = TestHelperPlus1;
|
2018-05-24 14:09:12 +00:00
|
|
|
check(fptr(context, 42) == 43);
|
2018-05-16 14:00:35 +00:00
|
|
|
fptr = TestHelperPlus2;
|
2018-05-24 14:09:12 +00:00
|
|
|
check(fptr(context, 42) == 44);
|
2018-05-16 14:00:35 +00:00
|
|
|
return True;
|
|
|
|
}
|
2018-05-18 08:33:36 +00:00
|
|
|
|
2018-07-17 16:20:53 +00:00
|
|
|
macro TestVariableRedeclaration(context: Context): Boolean {
|
2018-09-11 13:15:02 +00:00
|
|
|
let var1: int31 = FromConstexpr<bool>(42 == 0) ? 0 : 1;
|
|
|
|
let var2: int31 = FromConstexpr<bool>(42 == 0) ? 1 : 0;
|
2018-05-18 08:33:36 +00:00
|
|
|
return True;
|
|
|
|
}
|
2018-05-22 12:48:29 +00:00
|
|
|
|
2018-07-17 16:20:53 +00:00
|
|
|
macro TestTernaryOperator(x: Smi): Smi {
|
|
|
|
let b: bool = x < 0 ? true : false;
|
2018-07-03 12:02:05 +00:00
|
|
|
return b ? x - 10 : x + 100;
|
|
|
|
}
|
|
|
|
|
2018-05-22 12:48:29 +00:00
|
|
|
macro TestFunctionPointerToGeneric(c: Context) {
|
|
|
|
let fptr1: builtin(Context, Smi) => Object = GenericBuiltinTest<Smi>;
|
|
|
|
let fptr2: builtin(Context, Object) => Object = GenericBuiltinTest<Object>;
|
|
|
|
|
2018-05-24 14:09:12 +00:00
|
|
|
check(fptr1(c, 0) == Null);
|
|
|
|
check(fptr1(c, 1) == Null);
|
|
|
|
check(fptr2(c, Undefined) == Undefined);
|
|
|
|
check(fptr2(c, Undefined) == Undefined);
|
2018-05-22 12:48:29 +00:00
|
|
|
}
|
2018-05-22 21:11:39 +00:00
|
|
|
|
2018-11-05 10:37:49 +00:00
|
|
|
type ObjectToObject = builtin(Context, Object) => Object;
|
|
|
|
macro TestTypeAlias(x: ObjectToObject): Code {
|
2018-05-22 21:11:39 +00:00
|
|
|
return x;
|
|
|
|
}
|
2018-05-29 14:18:39 +00:00
|
|
|
|
|
|
|
macro TestUnsafeCast(c: Context, n: Number): Boolean {
|
|
|
|
if (TaggedIsSmi(n)) {
|
2018-09-11 13:15:02 +00:00
|
|
|
let m: Smi = UnsafeCast<Smi>(n);
|
2018-05-29 14:18:39 +00:00
|
|
|
|
|
|
|
check(TestHelperPlus1(c, m) == 11);
|
|
|
|
return True;
|
|
|
|
}
|
|
|
|
return False;
|
|
|
|
}
|
2018-06-05 08:49:05 +00:00
|
|
|
|
|
|
|
macro TestHexLiteral() {
|
2018-09-11 13:15:02 +00:00
|
|
|
check(Convert<intptr>(0xffff) + 1 == 0x10000);
|
|
|
|
check(Convert<intptr>(-0xffff) == -65535);
|
2018-06-05 08:49:05 +00:00
|
|
|
}
|
2018-06-05 11:54:38 +00:00
|
|
|
|
|
|
|
macro TestLargeIntegerLiterals(c: Context) {
|
|
|
|
let x: int32 = 0x40000000;
|
|
|
|
let y: int32 = 0x7fffffff;
|
|
|
|
}
|
2018-06-13 08:25:17 +00:00
|
|
|
|
|
|
|
macro TestMultilineAssert() {
|
|
|
|
let someVeryLongVariableNameThatWillCauseLineBreaks: Smi = 5;
|
2018-07-17 16:20:53 +00:00
|
|
|
check(
|
|
|
|
someVeryLongVariableNameThatWillCauseLineBreaks > 0 &&
|
|
|
|
someVeryLongVariableNameThatWillCauseLineBreaks < 10);
|
2018-06-13 08:25:17 +00:00
|
|
|
}
|
2018-06-28 12:15:37 +00:00
|
|
|
|
|
|
|
macro TestNewlineInString() {
|
|
|
|
Print('Hello, World!\n');
|
|
|
|
}
|
2018-07-13 08:50:22 +00:00
|
|
|
|
|
|
|
const kConstexprConst: constexpr int31 = 5;
|
|
|
|
const kIntptrConst: intptr = 4;
|
|
|
|
const kSmiConst: Smi = 3;
|
|
|
|
|
|
|
|
macro TestModuleConstBindings() {
|
|
|
|
check(kConstexprConst == Int32Constant(5));
|
|
|
|
check(kIntptrConst == 4);
|
|
|
|
check(kSmiConst == 3);
|
|
|
|
}
|
2018-07-17 06:39:07 +00:00
|
|
|
|
|
|
|
macro TestLocalConstBindings() {
|
2018-09-24 09:28:48 +00:00
|
|
|
const x: constexpr int31 = 3;
|
|
|
|
const xSmi: Smi = x;
|
2018-07-27 13:56:57 +00:00
|
|
|
{
|
2018-09-24 09:28:48 +00:00
|
|
|
const x: Smi = x + FromConstexpr<Smi>(1);
|
2018-09-11 13:15:02 +00:00
|
|
|
check(x == xSmi + 1);
|
2018-09-24 09:28:48 +00:00
|
|
|
const xSmi: Smi = x;
|
2018-09-11 13:15:02 +00:00
|
|
|
check(x == xSmi);
|
2018-07-27 13:56:57 +00:00
|
|
|
check(x == 4);
|
|
|
|
}
|
2018-09-11 13:15:02 +00:00
|
|
|
check(xSmi == 3);
|
|
|
|
check(x == xSmi);
|
2018-07-17 06:39:07 +00:00
|
|
|
}
|
2018-07-17 16:20:53 +00:00
|
|
|
|
|
|
|
struct TestStructA {
|
|
|
|
indexes: FixedArray;
|
|
|
|
i: Smi;
|
|
|
|
k: Number;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct TestStructB {
|
|
|
|
x: TestStructA;
|
|
|
|
y: Smi;
|
|
|
|
}
|
|
|
|
|
|
|
|
macro TestStruct1(i: TestStructA): Smi {
|
|
|
|
return i.i;
|
|
|
|
}
|
|
|
|
|
|
|
|
macro TestStruct2(): TestStructA {
|
2018-09-11 13:15:02 +00:00
|
|
|
return TestStructA{UnsafeCast<FixedArray>(kEmptyFixedArray), 27, 31};
|
2018-07-17 16:20:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
macro TestStruct3(): TestStructA {
|
|
|
|
let a: TestStructA =
|
2018-09-11 13:15:02 +00:00
|
|
|
TestStructA{UnsafeCast<FixedArray>(kEmptyFixedArray), 13, 5};
|
2018-07-17 16:20:53 +00:00
|
|
|
let b: TestStructA = a;
|
|
|
|
let c: TestStructA = TestStruct2();
|
|
|
|
a.i = TestStruct1(c);
|
|
|
|
a.k = a.i;
|
|
|
|
let d: TestStructB;
|
|
|
|
d.x = a;
|
|
|
|
d = TestStructB{a, 7};
|
|
|
|
let e: TestStructA = d.x;
|
2018-09-24 09:28:48 +00:00
|
|
|
let f: Smi =
|
|
|
|
TestStructA{UnsafeCast<FixedArray>(kEmptyFixedArray), 27, 31}.i;
|
2018-07-17 16:20:53 +00:00
|
|
|
f = TestStruct2().i;
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct TestStructC {
|
2018-09-24 09:28:48 +00:00
|
|
|
x: TestStructA;
|
|
|
|
y: TestStructA;
|
2018-07-17 16:20:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
macro TestStruct4(): TestStructC {
|
|
|
|
return TestStructC{TestStruct2(), TestStruct2()};
|
|
|
|
}
|
2018-07-27 10:32:14 +00:00
|
|
|
|
|
|
|
// This macro tests different versions of the for-loop where some parts
|
|
|
|
// are (not) present.
|
|
|
|
macro TestForLoop() {
|
|
|
|
let sum: Smi = 0;
|
2018-07-31 18:24:02 +00:00
|
|
|
for (let i: Smi = 0; i < 5; ++i) sum += i;
|
2018-07-27 10:32:14 +00:00
|
|
|
check(sum == 10);
|
|
|
|
|
|
|
|
sum = 0;
|
|
|
|
let j: Smi = 0;
|
2018-07-31 18:24:02 +00:00
|
|
|
for (; j < 5; ++j) sum += j;
|
2018-07-27 10:32:14 +00:00
|
|
|
check(sum == 10);
|
|
|
|
|
|
|
|
sum = 0;
|
|
|
|
j = 0;
|
2018-07-31 18:24:02 +00:00
|
|
|
for (; j < 5;) sum += j++;
|
2018-07-27 10:32:14 +00:00
|
|
|
check(sum == 10);
|
|
|
|
|
|
|
|
// Check that break works. No test expression.
|
|
|
|
sum = 0;
|
|
|
|
for (let i: Smi = 0;; ++i) {
|
|
|
|
if (i == 5) break;
|
2018-07-31 18:24:02 +00:00
|
|
|
sum += i;
|
2018-07-27 10:32:14 +00:00
|
|
|
}
|
|
|
|
check(sum == 10);
|
|
|
|
|
|
|
|
sum = 0;
|
|
|
|
j = 0;
|
|
|
|
for (;;) {
|
|
|
|
if (j == 5) break;
|
2018-07-31 18:24:02 +00:00
|
|
|
sum += j;
|
2018-07-27 10:32:14 +00:00
|
|
|
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;
|
2018-07-31 18:24:02 +00:00
|
|
|
sum += i;
|
2018-07-27 10:32:14 +00:00
|
|
|
}
|
|
|
|
check(sum == 7);
|
|
|
|
|
|
|
|
sum = 0;
|
|
|
|
j = 0;
|
|
|
|
for (; j < 5; ++j) {
|
|
|
|
if (j == 3) continue;
|
2018-07-31 18:24:02 +00:00
|
|
|
sum += j;
|
2018-07-27 10:32:14 +00:00
|
|
|
}
|
|
|
|
check(sum == 7);
|
|
|
|
|
|
|
|
sum = 0;
|
|
|
|
j = 0;
|
|
|
|
for (; j < 5;) {
|
|
|
|
if (j == 3) {
|
|
|
|
j++;
|
|
|
|
continue;
|
|
|
|
}
|
2018-07-31 18:24:02 +00:00
|
|
|
sum += j;
|
2018-07-27 10:32:14 +00:00
|
|
|
j++;
|
|
|
|
}
|
|
|
|
check(sum == 7);
|
|
|
|
|
|
|
|
sum = 0;
|
|
|
|
for (let i: Smi = 0;; ++i) {
|
|
|
|
if (i == 3) continue;
|
|
|
|
if (i == 5) break;
|
2018-07-31 18:24:02 +00:00
|
|
|
sum += i;
|
2018-07-27 10:32:14 +00:00
|
|
|
}
|
|
|
|
check(sum == 7);
|
|
|
|
|
|
|
|
sum = 0;
|
|
|
|
j = 0;
|
|
|
|
for (;;) {
|
|
|
|
if (j == 3) {
|
|
|
|
j++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (j == 5) break;
|
2018-07-31 18:24:02 +00:00
|
|
|
sum += j;
|
2018-07-27 10:32:14 +00:00
|
|
|
j++;
|
|
|
|
}
|
|
|
|
check(sum == 7);
|
2018-10-24 09:18:30 +00:00
|
|
|
|
|
|
|
j = 0;
|
|
|
|
try {
|
|
|
|
for (;;) {
|
|
|
|
if (++j == 10) goto Exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
label Exit {
|
|
|
|
check(j == 10);
|
|
|
|
}
|
2018-07-27 10:32:14 +00:00
|
|
|
}
|
2018-08-07 14:06:18 +00:00
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
macro TestSubtyping(x: Smi) {
|
|
|
|
const foo: Object = x;
|
2018-08-07 21:57:19 +00:00
|
|
|
}
|
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
macro IncrementIfSmi<A: type>(x: A): A {
|
2018-08-07 21:57:19 +00:00
|
|
|
typeswitch (x) {
|
2018-09-24 09:28:48 +00:00
|
|
|
case (x: Smi): {
|
2018-08-07 21:57:19 +00:00
|
|
|
return x + 1;
|
2018-09-24 09:28:48 +00:00
|
|
|
}
|
|
|
|
case (o: A): {
|
2018-08-07 21:57:19 +00:00
|
|
|
return o;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
macro TypeswitchExample(x: Number | FixedArray): int32 {
|
|
|
|
let result: int32 = 0;
|
2018-11-14 15:38:50 +00:00
|
|
|
typeswitch (IncrementIfSmi(x)) {
|
2018-09-24 09:28:48 +00:00
|
|
|
case (x: FixedArray): {
|
2018-08-07 21:57:19 +00:00
|
|
|
result = result + 1;
|
2018-09-24 09:28:48 +00:00
|
|
|
}
|
|
|
|
case (Number): {
|
2018-08-07 21:57:19 +00:00
|
|
|
result = result + 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result = result * 10;
|
|
|
|
|
2018-11-14 15:38:50 +00:00
|
|
|
typeswitch (IncrementIfSmi(x)) {
|
2018-09-24 09:28:48 +00:00
|
|
|
case (x: Smi): {
|
2018-09-11 13:15:02 +00:00
|
|
|
result = result + Convert<int32>(x);
|
2018-09-24 09:28:48 +00:00
|
|
|
}
|
|
|
|
case (a: FixedArray): {
|
2018-09-11 13:15:02 +00:00
|
|
|
result = result + Convert<int32>(a.length);
|
2018-09-24 09:28:48 +00:00
|
|
|
}
|
|
|
|
case (x: HeapNumber): {
|
2018-08-07 21:57:19 +00:00
|
|
|
result = result + 7;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
macro TestTypeswitch() {
|
2018-09-11 13:15:02 +00:00
|
|
|
check(TypeswitchExample(FromConstexpr<Smi>(5)) == 26);
|
2018-09-24 09:28:48 +00:00
|
|
|
const a: FixedArray = AllocateZeroedFixedArray(3);
|
2018-08-07 21:57:19 +00:00
|
|
|
check(TypeswitchExample(a) == 13);
|
2018-09-11 13:15:02 +00:00
|
|
|
check(TypeswitchExample(FromConstexpr<Number>(0.5)) == 27);
|
2018-08-07 21:57:19 +00:00
|
|
|
}
|
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
macro ExampleGenericOverload<A: type>(o: Object): A {
|
2018-08-07 14:06:18 +00:00
|
|
|
return o;
|
|
|
|
}
|
2018-09-24 09:28:48 +00:00
|
|
|
macro ExampleGenericOverload<A: type>(o: Smi): A {
|
2018-08-07 14:06:18 +00:00
|
|
|
return o + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
macro TestGenericOverload() {
|
2018-09-24 09:28:48 +00:00
|
|
|
const xSmi: Smi = 5;
|
|
|
|
const xObject: Object = xSmi;
|
2018-09-11 13:15:02 +00:00
|
|
|
check(ExampleGenericOverload<Smi>(xSmi) == 6);
|
|
|
|
check(UnsafeCast<Smi>(ExampleGenericOverload<Object>(xObject)) == 5);
|
2018-08-07 14:06:18 +00:00
|
|
|
}
|
[torque] disallow using logical operators in value contexts
This CL makes sure, that logical operators (||, &&) always have return
type never. Together with a check that never is never passed as a
function argument, this prevents faulty evaluation as in !(x || y).
Before, the logical operators had a behavior similar to
(bool labels Taken, NotTaken), with a fast exit if the left-hand side
allowed shor-circuit evaluation, but returning the right-hand side
otherwise. Since we want to allow existing (a || b || c) patterns in
the codebase, this requires weakening the restriction that the left-
and right-hand side need to have the same type. Now the possibilites
are:
bool, never
never, bool
never, never
bool, bool
constexpr bool, constexpr bool
Bug: v8:8137
Change-Id: I9576b337dc4008ac58b4625e77fef4e73bcdd6e3
Reviewed-on: https://chromium-review.googlesource.com/1215162
Reviewed-by: Daniel Clifford <danno@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55750}
2018-09-08 16:16:08 +00:00
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
macro BoolToBranch(x: bool): never
|
|
|
|
labels Taken, NotTaken {
|
[torque] disallow using logical operators in value contexts
This CL makes sure, that logical operators (||, &&) always have return
type never. Together with a check that never is never passed as a
function argument, this prevents faulty evaluation as in !(x || y).
Before, the logical operators had a behavior similar to
(bool labels Taken, NotTaken), with a fast exit if the left-hand side
allowed shor-circuit evaluation, but returning the right-hand side
otherwise. Since we want to allow existing (a || b || c) patterns in
the codebase, this requires weakening the restriction that the left-
and right-hand side need to have the same type. Now the possibilites
are:
bool, never
never, bool
never, never
bool, bool
constexpr bool, constexpr bool
Bug: v8:8137
Change-Id: I9576b337dc4008ac58b4625e77fef4e73bcdd6e3
Reviewed-on: https://chromium-review.googlesource.com/1215162
Reviewed-by: Daniel Clifford <danno@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55750}
2018-09-08 16:16:08 +00:00
|
|
|
if (x) {
|
|
|
|
goto Taken;
|
|
|
|
} else {
|
|
|
|
goto NotTaken;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
macro TestOrAnd1(x: bool, y: bool, z: bool): bool {
|
[torque] disallow using logical operators in value contexts
This CL makes sure, that logical operators (||, &&) always have return
type never. Together with a check that never is never passed as a
function argument, this prevents faulty evaluation as in !(x || y).
Before, the logical operators had a behavior similar to
(bool labels Taken, NotTaken), with a fast exit if the left-hand side
allowed shor-circuit evaluation, but returning the right-hand side
otherwise. Since we want to allow existing (a || b || c) patterns in
the codebase, this requires weakening the restriction that the left-
and right-hand side need to have the same type. Now the possibilites
are:
bool, never
never, bool
never, never
bool, bool
constexpr bool, constexpr bool
Bug: v8:8137
Change-Id: I9576b337dc4008ac58b4625e77fef4e73bcdd6e3
Reviewed-on: https://chromium-review.googlesource.com/1215162
Reviewed-by: Daniel Clifford <danno@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55750}
2018-09-08 16:16:08 +00:00
|
|
|
return BoolToBranch(x) || y && z ? true : false;
|
|
|
|
}
|
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
macro TestOrAnd2(x: bool, y: bool, z: bool): bool {
|
[torque] disallow using logical operators in value contexts
This CL makes sure, that logical operators (||, &&) always have return
type never. Together with a check that never is never passed as a
function argument, this prevents faulty evaluation as in !(x || y).
Before, the logical operators had a behavior similar to
(bool labels Taken, NotTaken), with a fast exit if the left-hand side
allowed shor-circuit evaluation, but returning the right-hand side
otherwise. Since we want to allow existing (a || b || c) patterns in
the codebase, this requires weakening the restriction that the left-
and right-hand side need to have the same type. Now the possibilites
are:
bool, never
never, bool
never, never
bool, bool
constexpr bool, constexpr bool
Bug: v8:8137
Change-Id: I9576b337dc4008ac58b4625e77fef4e73bcdd6e3
Reviewed-on: https://chromium-review.googlesource.com/1215162
Reviewed-by: Daniel Clifford <danno@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55750}
2018-09-08 16:16:08 +00:00
|
|
|
return x || BoolToBranch(y) && z ? true : false;
|
|
|
|
}
|
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
macro TestOrAnd3(x: bool, y: bool, z: bool): bool {
|
[torque] disallow using logical operators in value contexts
This CL makes sure, that logical operators (||, &&) always have return
type never. Together with a check that never is never passed as a
function argument, this prevents faulty evaluation as in !(x || y).
Before, the logical operators had a behavior similar to
(bool labels Taken, NotTaken), with a fast exit if the left-hand side
allowed shor-circuit evaluation, but returning the right-hand side
otherwise. Since we want to allow existing (a || b || c) patterns in
the codebase, this requires weakening the restriction that the left-
and right-hand side need to have the same type. Now the possibilites
are:
bool, never
never, bool
never, never
bool, bool
constexpr bool, constexpr bool
Bug: v8:8137
Change-Id: I9576b337dc4008ac58b4625e77fef4e73bcdd6e3
Reviewed-on: https://chromium-review.googlesource.com/1215162
Reviewed-by: Daniel Clifford <danno@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55750}
2018-09-08 16:16:08 +00:00
|
|
|
return x || y && BoolToBranch(z) ? true : false;
|
|
|
|
}
|
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
macro TestAndOr1(x: bool, y: bool, z: bool): bool {
|
[torque] disallow using logical operators in value contexts
This CL makes sure, that logical operators (||, &&) always have return
type never. Together with a check that never is never passed as a
function argument, this prevents faulty evaluation as in !(x || y).
Before, the logical operators had a behavior similar to
(bool labels Taken, NotTaken), with a fast exit if the left-hand side
allowed shor-circuit evaluation, but returning the right-hand side
otherwise. Since we want to allow existing (a || b || c) patterns in
the codebase, this requires weakening the restriction that the left-
and right-hand side need to have the same type. Now the possibilites
are:
bool, never
never, bool
never, never
bool, bool
constexpr bool, constexpr bool
Bug: v8:8137
Change-Id: I9576b337dc4008ac58b4625e77fef4e73bcdd6e3
Reviewed-on: https://chromium-review.googlesource.com/1215162
Reviewed-by: Daniel Clifford <danno@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55750}
2018-09-08 16:16:08 +00:00
|
|
|
return BoolToBranch(x) && y || z ? true : false;
|
|
|
|
}
|
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
macro TestAndOr2(x: bool, y: bool, z: bool): bool {
|
[torque] disallow using logical operators in value contexts
This CL makes sure, that logical operators (||, &&) always have return
type never. Together with a check that never is never passed as a
function argument, this prevents faulty evaluation as in !(x || y).
Before, the logical operators had a behavior similar to
(bool labels Taken, NotTaken), with a fast exit if the left-hand side
allowed shor-circuit evaluation, but returning the right-hand side
otherwise. Since we want to allow existing (a || b || c) patterns in
the codebase, this requires weakening the restriction that the left-
and right-hand side need to have the same type. Now the possibilites
are:
bool, never
never, bool
never, never
bool, bool
constexpr bool, constexpr bool
Bug: v8:8137
Change-Id: I9576b337dc4008ac58b4625e77fef4e73bcdd6e3
Reviewed-on: https://chromium-review.googlesource.com/1215162
Reviewed-by: Daniel Clifford <danno@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55750}
2018-09-08 16:16:08 +00:00
|
|
|
return x && BoolToBranch(y) || z ? true : false;
|
|
|
|
}
|
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
macro TestAndOr3(x: bool, y: bool, z: bool): bool {
|
[torque] disallow using logical operators in value contexts
This CL makes sure, that logical operators (||, &&) always have return
type never. Together with a check that never is never passed as a
function argument, this prevents faulty evaluation as in !(x || y).
Before, the logical operators had a behavior similar to
(bool labels Taken, NotTaken), with a fast exit if the left-hand side
allowed shor-circuit evaluation, but returning the right-hand side
otherwise. Since we want to allow existing (a || b || c) patterns in
the codebase, this requires weakening the restriction that the left-
and right-hand side need to have the same type. Now the possibilites
are:
bool, never
never, bool
never, never
bool, bool
constexpr bool, constexpr bool
Bug: v8:8137
Change-Id: I9576b337dc4008ac58b4625e77fef4e73bcdd6e3
Reviewed-on: https://chromium-review.googlesource.com/1215162
Reviewed-by: Daniel Clifford <danno@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55750}
2018-09-08 16:16:08 +00:00
|
|
|
return x && y || BoolToBranch(z) ? true : false;
|
|
|
|
}
|
|
|
|
|
|
|
|
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));
|
|
|
|
}
|
2018-10-08 13:50:46 +00:00
|
|
|
|
|
|
|
macro TestCall(i: Smi): Smi
|
|
|
|
labels A {
|
|
|
|
if (i < 5) return i;
|
|
|
|
goto A;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
macro TestOtherwiseWithCode2() {
|
|
|
|
let s: Smi = 0;
|
|
|
|
for (let i: Smi = 0; i < 10; ++i) {
|
|
|
|
TestCall(i) otherwise break;
|
|
|
|
++s;
|
|
|
|
}
|
|
|
|
assert(s == 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
macro TestOtherwiseWithCode3() {
|
|
|
|
let s: Smi = 0;
|
|
|
|
for (let i: Smi = 0; i < 10; ++i) {
|
|
|
|
s += TestCall(i) otherwise break;
|
|
|
|
}
|
|
|
|
assert(s == 10);
|
|
|
|
}
|
|
|
|
|
|
|
|
macro TestForwardLabel() {
|
|
|
|
try {
|
|
|
|
goto A;
|
|
|
|
}
|
|
|
|
label A {
|
|
|
|
goto B(5);
|
|
|
|
}
|
|
|
|
label B(b: Smi) {
|
|
|
|
assert(b == 5);
|
|
|
|
}
|
|
|
|
}
|
2018-10-31 13:00:51 +00:00
|
|
|
|
2018-11-02 12:40:31 +00:00
|
|
|
macro TestQualifiedAccess() {
|
|
|
|
let s: Smi = 0;
|
|
|
|
check(!array::IsJSArray(s));
|
|
|
|
}
|
|
|
|
|
2018-10-31 13:00:51 +00:00
|
|
|
macro TestCatch1(context: Context): Smi {
|
|
|
|
let r: Smi = 0;
|
|
|
|
try {
|
|
|
|
ThrowTypeError(context, kInvalidArrayLength);
|
|
|
|
} catch (e) {
|
|
|
|
r = 1;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
macro TestCatch2Wrapper(context: Context): never {
|
|
|
|
ThrowTypeError(context, kInvalidArrayLength);
|
|
|
|
}
|
|
|
|
|
|
|
|
macro TestCatch2(context: Context): Smi {
|
|
|
|
let r: Smi = 0;
|
|
|
|
try {
|
|
|
|
TestCatch2Wrapper(context);
|
|
|
|
} catch (e) {
|
|
|
|
r = 2;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
macro TestCatch3WrapperWithLabel(context: Context): never
|
|
|
|
labels Abort {
|
|
|
|
ThrowTypeError(context, kInvalidArrayLength);
|
|
|
|
}
|
|
|
|
|
|
|
|
macro TestCatch3(context: Context): Smi {
|
|
|
|
let r: Smi = 0;
|
|
|
|
try {
|
|
|
|
TestCatch3WrapperWithLabel(context) otherwise Abort;
|
|
|
|
}
|
|
|
|
label Abort {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
catch (e) {
|
|
|
|
r = 2;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
}
|
2018-10-31 14:59:13 +00:00
|
|
|
|
|
|
|
// 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.
|
|
|
|
macro TestIterator(implicit context: Context)(o: Object, map: Map) {
|
|
|
|
try {
|
2018-11-02 12:40:31 +00:00
|
|
|
const t1: Object = iterator::GetIteratorMethod(o);
|
2018-11-19 12:45:02 +00:00
|
|
|
const t2: iterator::IteratorRecord = iterator::GetIterator(o);
|
2018-10-31 14:59:13 +00:00
|
|
|
|
2018-11-02 12:40:31 +00:00
|
|
|
const t3: Object = iterator::IteratorStep(t2) otherwise Fail;
|
|
|
|
const t4: Object = iterator::IteratorStep(t2, map) otherwise Fail;
|
2018-10-31 14:59:13 +00:00
|
|
|
|
2018-11-02 12:40:31 +00:00
|
|
|
const t5: Object = iterator::IteratorValue(t4);
|
|
|
|
const t6: Object = iterator::IteratorValue(t4, map);
|
2018-10-31 14:59:13 +00:00
|
|
|
|
2018-11-02 12:40:31 +00:00
|
|
|
const t7: JSArray = iterator::IterableToList(t1, t1);
|
2018-11-09 14:34:54 +00:00
|
|
|
|
|
|
|
iterator::IteratorCloseOnException(t2, t5);
|
2018-10-31 14:59:13 +00:00
|
|
|
}
|
|
|
|
label Fail {}
|
|
|
|
}
|
|
|
|
}
|