test-value-js.cpp 4.2 KB

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