summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibJS/Heap/Heap.cpp2
-rw-r--r--Userland/Libraries/LibJS/Runtime/Value.h28
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);