From c63a8c033420bc3f8c277810ea8cd6ec39150f67 Mon Sep 17 00:00:00 2001 From: Jonne Ransijn Date: Thu, 10 Apr 2025 15:04:56 +0200 Subject: [PATCH] LibJS: Allow `Optional` to be used in constant expressions --- Libraries/LibJS/Runtime/Value.h | 46 ++++++++++++++++----------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/Libraries/LibJS/Runtime/Value.h b/Libraries/LibJS/Runtime/Value.h index 5766b798fc3..687966a9791 100644 --- a/Libraries/LibJS/Runtime/Value.h +++ b/Libraries/LibJS/Runtime/Value.h @@ -154,7 +154,7 @@ public: return !is_nan() && !is_infinity(); } - Value() + constexpr Value() : Value(UNDEFINED_TAG << GC::TAG_SHIFT, (u64)0) { } @@ -428,12 +428,12 @@ private: enum class EmptyTag { Empty }; - Value(EmptyTag) + constexpr Value(EmptyTag) : Value(EMPTY_TAG << GC::TAG_SHIFT, (u64)0) { } - Value(u64 tag, u64 val) + constexpr Value(u64 tag, u64 val) { ASSERT(!(tag & val)); m_value.encoded = tag | val; @@ -467,9 +467,9 @@ private: ThrowCompletionOr to_i32_slow_case(VM&) const; - friend Value js_undefined(); - friend Value js_null(); - friend Value js_special_empty_value(); + friend constexpr Value js_undefined(); + friend constexpr Value js_null(); + friend constexpr Value js_special_empty_value(); friend ThrowCompletionOr greater_than(VM&, Value lhs, Value rhs); friend ThrowCompletionOr greater_than_equals(VM&, Value lhs, Value rhs); friend ThrowCompletionOr less_than(VM&, Value lhs, Value rhs); @@ -478,17 +478,17 @@ private: friend bool same_value_non_number(Value lhs, Value rhs); }; -inline Value js_undefined() +inline constexpr Value js_undefined() { return Value(UNDEFINED_TAG << GC::TAG_SHIFT, (u64)0); } -inline Value js_null() +inline constexpr Value js_null() { return Value(NULL_TAG << GC::TAG_SHIFT, (u64)0); } -inline Value js_special_empty_value() +inline constexpr Value js_special_empty_value() { return Value(Value::EmptyTag::Empty); } @@ -564,38 +564,38 @@ class Optional : public OptionalBase { public: using ValueType = JS::Value; - Optional() = default; + constexpr Optional() = default; template V> - Optional(V) { } + constexpr Optional(V) { } - Optional(Optional const& other) + constexpr Optional(Optional const& other) { if (other.has_value()) m_value = other.m_value; } - Optional(Optional&& other) + constexpr Optional(Optional&& other) : m_value(other.m_value) { } template requires(!IsSame>) - explicit(!IsConvertible) Optional(U&& value) + explicit(!IsConvertible) constexpr Optional(U&& value) requires(!IsSame, Optional> && IsConstructible) : m_value(forward(value)) { } template V> - Optional& operator=(V) + constexpr Optional& operator=(V) { clear(); return *this; } - Optional& operator=(Optional const& other) + constexpr Optional& operator=(Optional const& other) { if (this != &other) { clear(); @@ -604,7 +604,7 @@ public: return *this; } - Optional& operator=(Optional&& other) + constexpr Optional& operator=(Optional&& other) { if (this != &other) { clear(); @@ -613,34 +613,34 @@ public: return *this; } - void clear() + constexpr void clear() { m_value = JS::js_special_empty_value(); } - [[nodiscard]] bool has_value() const + [[nodiscard]] constexpr bool has_value() const { return !m_value.is_special_empty_value(); } - [[nodiscard]] JS::Value& value() & + [[nodiscard]] constexpr JS::Value& value() & { VERIFY(has_value()); return m_value; } - [[nodiscard]] JS::Value const& value() const& + [[nodiscard]] constexpr JS::Value const& value() const& { VERIFY(has_value()); return m_value; } - [[nodiscard]] JS::Value value() && + [[nodiscard]] constexpr JS::Value value() && { return release_value(); } - [[nodiscard]] JS::Value release_value() + [[nodiscard]] constexpr JS::Value release_value() { VERIFY(has_value()); JS::Value released_value = m_value;