diff options
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibJS/Heap/Heap.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/Value.h | 28 |
2 files changed, 20 insertions, 10 deletions
diff --git a/Userland/Libraries/LibJS/Heap/Heap.cpp b/Userland/Libraries/LibJS/Heap/Heap.cpp index 1fef87d439..97b416980a 100644 --- a/Userland/Libraries/LibJS/Heap/Heap.cpp +++ b/Userland/Libraries/LibJS/Heap/Heap.cpp @@ -142,7 +142,7 @@ __attribute__((no_sanitize("address"))) void Heap::gather_conservative_roots(Has // match any pointer-backed tag, in that case we have to extract the pointer to its // canonical form and add that as a possible pointer. if ((data & SHIFTED_IS_CELL_PATTERN) == SHIFTED_IS_CELL_PATTERN) - possible_pointers.set((u64)(((i64)data << 16) >> 16)); + possible_pointers.set(Value::extract_pointer_bits(data)); else possible_pointers.set(data); } else { diff --git a/Userland/Libraries/LibJS/Runtime/Value.h b/Userland/Libraries/LibJS/Runtime/Value.h index d53cbf3ecb..aadf403302 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.h +++ b/Userland/Libraries/LibJS/Runtime/Value.h @@ -398,6 +398,24 @@ public: template<typename... Args> [[nodiscard]] ALWAYS_INLINE ThrowCompletionOr<Value> invoke(VM&, PropertyKey const& property_key, Args... args); + static constexpr FlatPtr extract_pointer_bits(u64 encoded) + { +#ifdef AK_ARCH_32_BIT + // For 32-bit system the pointer fully fits so we can just return it directly. + static_assert(sizeof(void*) == sizeof(u32)); + return static_cast<FlatPtr>(encoded & 0xffff'ffff); +#elif ARCH(X86_64) + // For x86_64 the top 16 bits should be sign extending the "real" top bit (47th). + // So first shift the top 16 bits away then using the right shift it sign extends the top 16 bits. + return static_cast<FlatPtr>((static_cast<i64>(encoded << 16)) >> 16); +#elif ARCH(AARCH64) + // For AArch64 the top 16 bits of the pointer should be zero. + return static_cast<FlatPtr>(encoded & 0xffff'ffff'ffffULL); +#else +# error "Unknown architecture. Don't know whether pointers need to be sign-extended." +#endif + } + private: Value(u64 tag, u64 val) { @@ -444,15 +462,7 @@ private: PointerType* extract_pointer() const { VERIFY(is_cell()); - - // For 32-bit system the pointer fully fits so we can just return it directly. - if constexpr (sizeof(PointerType*) < sizeof(u64)) - return reinterpret_cast<PointerType*>(static_cast<u32>(m_value.encoded & 0xffffffff)); - - // For x86_64 the top 16 bits should be sign extending the "real" top bit (47th). - // So first shift the top 16 bits away then using the right shift it sign extends the top 16 bits. - u64 ptr_val = (u64)(((i64)(m_value.encoded << 16)) >> 16); - return reinterpret_cast<PointerType*>(ptr_val); + return reinterpret_cast<PointerType*>(extract_pointer_bits(m_value.encoded)); } [[nodiscard]] ThrowCompletionOr<Value> invoke_internal(VM&, PropertyKey const&, Optional<MarkedVector<Value>> arguments); |