LibJS: Make Completion.[[Value]] non-optional

Instead, just use js_undefined() whenever the [[Value]] field is unused.
This avoids a whole bunch of presence checks.
This commit is contained in:
Andreas Kling 2025-04-04 18:11:45 +02:00 committed by Andreas Kling
commit de424d6879
Notes: github-actions[bot] 2025-04-05 09:21:48 +00:00
65 changed files with 225 additions and 250 deletions

View file

@ -38,9 +38,8 @@ namespace JS {
if (_temporary_result.is_error()) { \
auto _completion = _temporary_result.release_error(); \
\
VERIFY(_completion.value().has_value()); \
VERIFY(_completion.value()->is_object()); \
VERIFY(::AK::is<JS::InternalError>(_completion.value()->as_object())); \
VERIFY(_completion.value().is_object()); \
VERIFY(::AK::is<JS::InternalError>(_completion.value().as_object())); \
\
return _completion; \
} \
@ -61,13 +60,12 @@ public:
Throw,
};
ALWAYS_INLINE Completion(Type type, Optional<Value> value)
ALWAYS_INLINE Completion(Type type, Value value)
: m_type(type)
, m_value(move(value))
, m_value(value)
{
VERIFY(type != Type::Empty);
if (m_value.has_value())
VERIFY(!m_value->is_empty());
VERIFY(!value.is_empty());
}
Completion(ThrowCompletionOr<Value> const&);
@ -79,11 +77,6 @@ public:
{
}
ALWAYS_INLINE Completion(Optional<Value> value)
: Completion(Type::Normal, move(value))
{
}
ALWAYS_INLINE Completion()
: Completion(js_undefined())
{
@ -99,19 +92,18 @@ public:
VERIFY(m_type != Type::Empty);
return m_type;
}
[[nodiscard]] Optional<Value>& value() { return m_value; }
[[nodiscard]] Optional<Value> const& value() const { return m_value; }
[[nodiscard]] Value& value() { return m_value; }
[[nodiscard]] Value const& value() const { return m_value; }
// "abrupt completion refers to any completion with a [[Type]] value other than normal"
[[nodiscard]] bool is_abrupt() const { return m_type != Type::Normal; }
// These are for compatibility with the TRY() macro in AK.
[[nodiscard]] bool is_error() const { return m_type == Type::Throw; }
[[nodiscard]] Optional<Value> release_value() { return move(m_value); }
[[nodiscard]] Value release_value() { return m_value; }
Completion release_error()
{
VERIFY(is_error());
VERIFY(m_value.has_value());
return { m_type, release_value() };
}
@ -131,7 +123,7 @@ private:
}
Type m_type { Type::Normal }; // [[Type]]
Optional<Value> m_value; // [[Value]]
Value m_value; // [[Value]]
// NOTE: We don't need the [[Target]] slot since control flow is handled in bytecode.
};
@ -244,7 +236,7 @@ public:
// Not `explicit` on purpose so that `return vm.throw_completion<Error>(...);` is possible.
ALWAYS_INLINE ThrowCompletionOr(Completion throw_completion)
: m_value_or_error(ErrorValue { throw_completion.release_error().value().value() })
: m_value_or_error(ErrorValue { throw_completion.release_error().value() })
{
}
@ -314,7 +306,7 @@ public:
ThrowCompletionOr<Value> await(VM&, Value);
// 6.2.4.1 NormalCompletion ( value ), https://tc39.es/ecma262/#sec-normalcompletion
inline Completion normal_completion(Optional<Value> value)
inline Completion normal_completion(Value value)
{
// 1. Return Completion Record { [[Type]]: normal, [[Value]]: value, [[Target]]: empty }.
return { Completion::Type::Normal, move(value) };