mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-23 09:22:30 +00:00
LibJS: Make async functions & generators faster with helper types
Instead of returning internal generator results as ordinary JS::Objects with properties, we now use GeneratorResult and CompletionCell which both inherit from Cell directly and allow efficient access to state. 1.59x speedup on JetStream3/lazy-collections.js :^)
This commit is contained in:
parent
1022566bff
commit
a0bb31f7a0
Notes:
github-actions[bot]
2025-04-01 00:31:35 +00:00
Author: https://github.com/awesomekling
Commit: a0bb31f7a0
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4161
12 changed files with 259 additions and 93 deletions
|
@ -7,8 +7,10 @@
|
|||
#include <AK/TemporaryChange.h>
|
||||
#include <LibJS/Bytecode/Generator.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
#include <LibJS/Runtime/CompletionCell.h>
|
||||
#include <LibJS/Runtime/GeneratorObject.h>
|
||||
#include <LibJS/Runtime/GeneratorPrototype.h>
|
||||
#include <LibJS/Runtime/GeneratorResult.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/Iterator.h>
|
||||
|
||||
|
@ -82,15 +84,15 @@ ThrowCompletionOr<Value> GeneratorObject::execute(VM& vm, Completion const& comp
|
|||
|
||||
VERIFY(completion.value().has_value());
|
||||
|
||||
auto generated_value = [&vm](Value value) -> Value {
|
||||
if (value.is_object())
|
||||
return value.as_object().get_without_side_effects(vm.names.result);
|
||||
auto generated_value = [](Value value) -> Value {
|
||||
if (value.is_cell())
|
||||
return static_cast<GeneratorResult const&>(value.as_cell()).result();
|
||||
return value.is_empty() ? js_undefined() : value;
|
||||
};
|
||||
|
||||
auto generated_continuation = [&](Value value) -> Optional<size_t> {
|
||||
if (value.is_object()) {
|
||||
auto number_value = value.as_object().get_without_side_effects(vm.names.continuation);
|
||||
if (value.is_cell()) {
|
||||
auto number_value = static_cast<GeneratorResult const&>(value.as_cell()).continuation();
|
||||
if (number_value.is_null())
|
||||
return {};
|
||||
return static_cast<u64>(number_value.as_double());
|
||||
|
@ -98,10 +100,7 @@ ThrowCompletionOr<Value> GeneratorObject::execute(VM& vm, Completion const& comp
|
|||
return {};
|
||||
};
|
||||
|
||||
auto& realm = *vm.current_realm();
|
||||
auto completion_object = Object::create(realm, nullptr);
|
||||
completion_object->define_direct_property(vm.names.type, Value(to_underlying(completion.type())), default_attributes);
|
||||
completion_object->define_direct_property(vm.names.value, completion.value().value(), default_attributes);
|
||||
auto compleion_cell = heap().allocate<CompletionCell>(completion);
|
||||
|
||||
auto& bytecode_interpreter = vm.bytecode_interpreter();
|
||||
|
||||
|
@ -110,7 +109,7 @@ ThrowCompletionOr<Value> GeneratorObject::execute(VM& vm, Completion const& comp
|
|||
// We should never enter `execute` again after the generator is complete.
|
||||
VERIFY(next_block.has_value());
|
||||
|
||||
auto next_result = bytecode_interpreter.run_executable(*m_generating_function->bytecode_executable(), next_block, completion_object);
|
||||
auto next_result = bytecode_interpreter.run_executable(*m_generating_function->bytecode_executable(), next_block, compleion_cell);
|
||||
|
||||
vm.pop_execution_context();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue