LibJS: Remove unused target field from Completion

This shrinks Completion by 16 bytes, which has non-trivial impact
on performance.
This commit is contained in:
Andreas Kling 2024-05-10 09:28:48 +02:00 committed by Alexander Kalenik
parent a77c6e15f4
commit ae11a4de1c
Notes: sideshowbarker 2024-07-16 20:21:48 +09:00
9 changed files with 23 additions and 26 deletions

View File

@ -1819,7 +1819,7 @@ ThrowCompletionOr<void> IteratorClose::execute_impl(Bytecode::Interpreter& inter
auto& iterator = verify_cast<IteratorRecord>(interpreter.get(m_iterator_record).as_object());
// FIXME: Return the value of the resulting completion. (Note that m_completion_value can be empty!)
TRY(iterator_close(vm, iterator, Completion { m_completion_type, m_completion_value, {} }));
TRY(iterator_close(vm, iterator, Completion { m_completion_type, m_completion_value }));
return {};
}
@ -1829,7 +1829,7 @@ ThrowCompletionOr<void> AsyncIteratorClose::execute_impl(Bytecode::Interpreter&
auto& iterator = verify_cast<IteratorRecord>(interpreter.get(m_iterator_record).as_object());
// FIXME: Return the value of the resulting completion. (Note that m_completion_value can be empty!)
TRY(async_iterator_close(vm, iterator, Completion { m_completion_type, m_completion_value, {} }));
TRY(async_iterator_close(vm, iterator, Completion { m_completion_type, m_completion_value }));
return {};
}

View File

@ -403,7 +403,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from_async)
TRY(array->set(vm.names.length, Value(k), Object::ShouldThrowExceptions::Yes));
// b. Return Completion Record { [[Type]]: return, [[Value]]: A, [[Target]]: empty }.
return Completion { Completion::Type::Return, array, {} };
return Completion { Completion::Type::Return, array };
}
// 8. Let nextValue be ? IteratorValue(nextResult).
@ -508,7 +508,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from_async)
TRY(array->set(vm.names.length, Value(length), Object::ShouldThrowExceptions::Yes));
// ix. Return Completion Record { [[Type]]: return, [[Value]]: A, [[Target]]: empty }.
return Completion { Completion::Type::Return, array, {} };
return Completion { Completion::Type::Return, array };
}
};

View File

@ -119,7 +119,7 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncGeneratorPrototype::return_)
auto generator = TRY_OR_REJECT(vm, promise_capability, async_generator_validate(vm, generator_this_value, OptionalNone {}));
// 5. Let completion be Completion Record { [[Type]]: return, [[Value]]: value, [[Target]]: empty }.
auto completion = Completion(Completion::Type::Return, vm.argument(0), {});
auto completion = Completion(Completion::Type::Return, vm.argument(0));
// 6. Perform AsyncGeneratorEnqueue(generator, completion, promiseCapability).
generator->async_generator_enqueue(completion, promise_capability);

View File

@ -144,7 +144,7 @@ Completion throw_completion(Value value)
log_exception(value);
// 1. Return Completion Record { [[Type]]: throw, [[Value]]: value, [[Target]]: empty }.
return { Completion::Type::Throw, value, {} };
return { Completion::Type::Throw, value };
}
}

View File

@ -63,10 +63,9 @@ public:
Throw,
};
ALWAYS_INLINE Completion(Type type, Optional<Value> value, Optional<DeprecatedFlyString> target)
ALWAYS_INLINE Completion(Type type, Optional<Value> value)
: m_type(type)
, m_value(move(value))
, m_target(move(target))
{
VERIFY(type != Type::Empty);
if (m_value.has_value())
@ -78,12 +77,12 @@ public:
// 5.2.3.1 Implicit Completion Values, https://tc39.es/ecma262/#sec-implicit-completion-values
// Not `explicit` on purpose.
ALWAYS_INLINE Completion(Value value)
: Completion(Type::Normal, value, {})
: Completion(Type::Normal, value)
{
}
ALWAYS_INLINE Completion(Optional<Value> value)
: Completion(Type::Normal, move(value), {})
: Completion(Type::Normal, move(value))
{
}
@ -104,8 +103,6 @@ public:
}
[[nodiscard]] Optional<Value>& value() { return m_value; }
[[nodiscard]] Optional<Value> const& value() const { return m_value; }
[[nodiscard]] Optional<DeprecatedFlyString>& target() { return m_target; }
[[nodiscard]] Optional<DeprecatedFlyString> const& target() const { return m_target; }
// "abrupt completion refers to any completion with a [[Type]] value other than normal"
[[nodiscard]] bool is_abrupt() const { return m_type != Type::Normal; }
@ -117,7 +114,7 @@ public:
{
VERIFY(is_error());
VERIFY(m_value.has_value());
return { m_type, release_value(), move(m_target) };
return { m_type, release_value() };
}
// 6.2.3.4 UpdateEmpty ( completionRecord, value ), https://tc39.es/ecma262/#sec-updateempty
@ -132,7 +129,7 @@ public:
return *this;
// 3. Return Completion Record { [[Type]]: completionRecord.[[Type]], [[Value]]: value, [[Target]]: completionRecord.[[Target]] }.
return { m_type, move(value), m_target };
return { m_type, move(value) };
}
private:
@ -150,9 +147,9 @@ private:
return m_type == Type::Empty;
}
Type m_type { Type::Normal }; // [[Type]]
Optional<Value> m_value; // [[Value]]
Optional<DeprecatedFlyString> m_target; // [[Target]]
Type m_type { Type::Normal }; // [[Type]]
Optional<Value> m_value; // [[Value]]
// NOTE: We don't need the [[Target]] slot since control flow is handled in bytecode.
};
}
@ -354,7 +351,7 @@ ThrowCompletionOr<Value> await(VM&, Value);
inline Completion normal_completion(Optional<Value> value)
{
// 1. Return Completion Record { [[Type]]: normal, [[Value]]: value, [[Target]]: empty }.
return { Completion::Type::Normal, move(value), {} };
return { Completion::Type::Normal, move(value) };
}
// 6.2.4.2 ThrowCompletion ( value ), https://tc39.es/ecma262/#sec-throwcompletion

View File

@ -1247,7 +1247,7 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
if (declaration_result.is_throw_completion()) {
auto promise_capability = MUST(new_promise_capability(vm, realm.intrinsics().promise_constructor()));
MUST(call(vm, *promise_capability->reject(), js_undefined(), *declaration_result.throw_completion().value()));
return Completion { Completion::Type::Return, promise_capability->promise(), {} };
return Completion { Completion::Type::Return, promise_capability->promise() };
}
}
@ -1261,11 +1261,11 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
// NOTE: Running the bytecode should eventually return a completion.
// Until it does, we assume "return" and include the undefined fallback from the call site.
if (m_kind == FunctionKind::Normal)
return { Completion::Type::Return, result.value_or(js_undefined()), {} };
return { Completion::Type::Return, result.value_or(js_undefined()) };
if (m_kind == FunctionKind::AsyncGenerator) {
auto async_generator_object = TRY(AsyncGenerator::create(realm, result, this, vm.running_execution_context().copy()));
return { Completion::Type::Return, async_generator_object, {} };
return { Completion::Type::Return, async_generator_object };
}
auto generator_object = TRY(GeneratorObject::create(realm, result, this, vm.running_execution_context().copy()));
@ -1273,10 +1273,10 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
// NOTE: Async functions are entirely transformed to generator functions, and wrapped in a custom driver that returns a promise
// See AwaitExpression::generate_bytecode() for the transformation.
if (m_kind == FunctionKind::Async)
return { Completion::Type::Return, AsyncFunctionDriverWrapper::create(realm, generator_object), {} };
return { Completion::Type::Return, AsyncFunctionDriverWrapper::create(realm, generator_object) };
VERIFY(m_kind == FunctionKind::Generator);
return { Completion::Type::Return, generator_object, {} };
return { Completion::Type::Return, generator_object };
}
void ECMAScriptFunctionObject::set_name(DeprecatedFlyString const& name)

View File

@ -44,7 +44,7 @@ JS_DEFINE_NATIVE_FUNCTION(GeneratorPrototype::return_)
auto generator_object = TRY(typed_this_object(vm));
// 2. Let C be Completion Record { [[Type]]: return, [[Value]]: value, [[Target]]: empty }.
auto completion = Completion(Completion::Type::Return, vm.argument(0), {});
auto completion = Completion(Completion::Type::Return, vm.argument(0));
// 3. Return ? GeneratorResumeAbrupt(g, C, empty).
return generator_object->resume_abrupt(vm, completion, {});

View File

@ -62,7 +62,7 @@ JS_DEFINE_NATIVE_FUNCTION(IteratorHelperPrototype::return_)
}
// 5. Let C be Completion { [[Type]]: return, [[Value]]: undefined, [[Target]]: empty }.
Completion completion { Completion::Type::Return, js_undefined(), {} };
Completion completion { Completion::Type::Return, js_undefined() };
// 6. Return ? GeneratorResumeAbrupt(O, C, "Iterator Helper").
return TRY(iterator->resume_abrupt(vm, move(completion), "Iterator Helper"sv));

View File

@ -91,7 +91,7 @@ JS::Completion ClassicScript::run(RethrowErrors rethrow_errors, JS::GCPtr<JS::En
// 5. If script's error to rethrow is not null, then set evaluationStatus to Completion { [[Type]]: throw, [[Value]]: script's error to rethrow, [[Target]]: empty }.
if (!error_to_rethrow().is_null()) {
evaluation_status = JS::Completion { JS::Completion::Type::Throw, error_to_rethrow(), {} };
evaluation_status = JS::Completion { JS::Completion::Type::Throw, error_to_rethrow() };
} else {
auto timer = Core::ElapsedTimer::start_new();