Serenity Operating System
at master 115 lines 4.3 kB view raw
1/* 2 * Copyright (c) 2022, David Tuin <davidot@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibJS/Runtime/Value.h> 8#include <LibTest/TestCase.h> 9 10using namespace JS; 11 12template<typename Type> 13static void test_nullptr_input() 14{ 15 Type* ptr = nullptr; 16 JS::Value val { ptr }; 17 EXPECT(val.is_null()); 18 EXPECT(!val.is_object()); 19 EXPECT(!val.is_string()); 20 EXPECT(!val.is_bigint()); 21 EXPECT(!val.is_symbol()); 22 EXPECT(!val.is_accessor()); 23 EXPECT(!val.is_cell()); 24 EXPECT(!val.is_number()); 25 EXPECT(!val.is_undefined()); 26} 27 28#define TEST_NULLPTR_INPUT(type) \ 29 TEST_CASE(value_nullptr_input_##type) \ 30 { \ 31 test_nullptr_input<type>(); \ 32 } 33 34TEST_NULLPTR_INPUT(Object); 35TEST_NULLPTR_INPUT(PrimitiveString); 36TEST_NULLPTR_INPUT(Symbol); 37TEST_NULLPTR_INPUT(BigInt); 38TEST_NULLPTR_INPUT(Accessor); 39 40#undef TEST_NULLPTR_INPUT 41 42TEST_CASE(valid_pointer_in_gives_same_pointer_out) 43{ 44 if (sizeof(void*) < sizeof(double)) 45 return; 46 47#define EXPECT_POINTER_TO_SURVIVE(input) \ 48 { \ 49 JS::Value value(reinterpret_cast<Object*>(static_cast<u64>(input))); \ 50 EXPECT(value.is_object()); \ 51 EXPECT(!value.is_null()); \ 52 auto extracted_pointer = JS::Value::extract_pointer_bits(value.encoded()); \ 53 EXPECT_EQ(static_cast<u64>(input), extracted_pointer); \ 54 } 55 56 EXPECT_POINTER_TO_SURVIVE(0x1); 57 EXPECT_POINTER_TO_SURVIVE(0x10); 58 EXPECT_POINTER_TO_SURVIVE(0x100); 59 EXPECT_POINTER_TO_SURVIVE(0x00007fffffffffff); 60 EXPECT_POINTER_TO_SURVIVE(0x0000700000000000); 61 EXPECT_POINTER_TO_SURVIVE(0x0000100000000000); 62 63#if ARCH(X86_64) 64 // On x86-64, the top 16 bits of pointers are equal to bit 47. 65 EXPECT_POINTER_TO_SURVIVE(0xffff800000000000); 66 EXPECT_POINTER_TO_SURVIVE(0xffff800000000001); 67 EXPECT_POINTER_TO_SURVIVE(0xffff800000000010); 68#elif ARCH(AARCH64) 69 // ... but they should contain zeroes on AArch64. 70 EXPECT_POINTER_TO_SURVIVE(0x0000800000000000); 71 EXPECT_POINTER_TO_SURVIVE(0x0000800000000001); 72 EXPECT_POINTER_TO_SURVIVE(0x0000800000000010); 73#endif 74 75#undef EXPECT_POINTER_TO_SURVIVE 76} 77 78TEST_CASE(non_canon_nans) 79{ 80#define EXPECT_TO_BE_NAN(input) \ 81 { \ 82 Value val { bit_cast<double>(input) }; \ 83 EXPECT(val.is_nan()); \ 84 EXPECT(val.is_number()); \ 85 EXPECT(!val.is_integral_number()); \ 86 EXPECT(!val.is_finite_number()); \ 87 EXPECT(!val.is_infinity()); \ 88 EXPECT(!val.is_empty()); \ 89 EXPECT(!val.is_nullish()); \ 90 } 91 92 EXPECT_TO_BE_NAN(CANON_NAN_BITS | 0x1); 93 EXPECT_TO_BE_NAN(CANON_NAN_BITS | 0x10); 94 EXPECT_TO_BE_NAN(CANON_NAN_BITS | (NULL_TAG << TAG_SHIFT)); 95 EXPECT_TO_BE_NAN(CANON_NAN_BITS | (UNDEFINED_TAG << TAG_SHIFT)); 96 EXPECT_TO_BE_NAN(CANON_NAN_BITS | (INT32_TAG << TAG_SHIFT) | 0x88); 97 EXPECT_TO_BE_NAN(CANON_NAN_BITS | (OBJECT_TAG << TAG_SHIFT)); 98 EXPECT_TO_BE_NAN(CANON_NAN_BITS | (OBJECT_TAG << TAG_SHIFT) | 0x1230); 99 EXPECT_TO_BE_NAN(CANON_NAN_BITS | (STRING_TAG << TAG_SHIFT)); 100 EXPECT_TO_BE_NAN(CANON_NAN_BITS | (STRING_TAG << TAG_SHIFT) | 0x1230); 101 102 u64 sign_bit = 1ULL << 63; 103 104 EXPECT_TO_BE_NAN(CANON_NAN_BITS | sign_bit | 0x1); 105 EXPECT_TO_BE_NAN(CANON_NAN_BITS | sign_bit | 0x10); 106 EXPECT_TO_BE_NAN(CANON_NAN_BITS | sign_bit | (NULL_TAG << TAG_SHIFT)); 107 EXPECT_TO_BE_NAN(CANON_NAN_BITS | sign_bit | (UNDEFINED_TAG << TAG_SHIFT)); 108 EXPECT_TO_BE_NAN(CANON_NAN_BITS | sign_bit | (INT32_TAG << TAG_SHIFT) | 0x88); 109 EXPECT_TO_BE_NAN(CANON_NAN_BITS | sign_bit | (OBJECT_TAG << TAG_SHIFT)); 110 EXPECT_TO_BE_NAN(CANON_NAN_BITS | sign_bit | (OBJECT_TAG << TAG_SHIFT) | 0x1230); 111 EXPECT_TO_BE_NAN(CANON_NAN_BITS | sign_bit | (STRING_TAG << TAG_SHIFT)); 112 EXPECT_TO_BE_NAN(CANON_NAN_BITS | sign_bit | (STRING_TAG << TAG_SHIFT) | 0x1230); 113 114#undef EXPECT_TO_BE_NAN 115}