mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 07:58:11 +00:00
LibJS: Switch to bytecode interpreter to run generator functions for AST
The bytecode interpreter can execute generator functions while the AST interpreter cannot. This simply makes it create a new bytecode interpreter when one doesn't exist when executing a generator function. Doing so makes it automatically switch to the bytecode interpreter to execute any future code until it exits the generator.
This commit is contained in:
parent
f3763a5275
commit
a1c1ab5f8d
2 changed files with 20 additions and 1 deletions
|
@ -786,11 +786,25 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
auto& realm = *vm.current_realm();
|
auto& realm = *vm.current_realm();
|
||||||
auto* bytecode_interpreter = Bytecode::Interpreter::current();
|
|
||||||
|
|
||||||
if (m_kind == FunctionKind::AsyncGenerator)
|
if (m_kind == FunctionKind::AsyncGenerator)
|
||||||
return vm.throw_completion<InternalError>(ErrorType::NotImplemented, "Async Generator function execution");
|
return vm.throw_completion<InternalError>(ErrorType::NotImplemented, "Async Generator function execution");
|
||||||
|
|
||||||
|
auto* bytecode_interpreter = Bytecode::Interpreter::current();
|
||||||
|
|
||||||
|
// The bytecode interpreter can execute generator functions while the AST interpreter cannot.
|
||||||
|
// This simply makes it create a new bytecode interpreter when one doesn't exist when executing a generator function.
|
||||||
|
// Doing so makes it automatically switch to the bytecode interpreter to execute any future code until it exits the generator. See below.
|
||||||
|
// This allows us to keep all of the existing functionality that works in AST while adding generator support on top of it.
|
||||||
|
// However, this does cause an awkward situation with features not supported in bytecode, where features that work outside of generators with AST
|
||||||
|
// suddenly stop working inside of generators.
|
||||||
|
// This is a stop gap until bytecode mode becomes the default.
|
||||||
|
OwnPtr<Bytecode::Interpreter> temp_bc_interpreter;
|
||||||
|
if (m_kind == FunctionKind::Generator && !bytecode_interpreter) {
|
||||||
|
temp_bc_interpreter = make<Bytecode::Interpreter>(realm);
|
||||||
|
bytecode_interpreter = temp_bc_interpreter.ptr();
|
||||||
|
}
|
||||||
|
|
||||||
if (bytecode_interpreter) {
|
if (bytecode_interpreter) {
|
||||||
if (!m_bytecode_executable) {
|
if (!m_bytecode_executable) {
|
||||||
auto compile = [&](auto& node, auto kind, auto name) -> ThrowCompletionOr<NonnullOwnPtr<Bytecode::Executable>> {
|
auto compile = [&](auto& node, auto kind, auto name) -> ThrowCompletionOr<NonnullOwnPtr<Bytecode::Executable>> {
|
||||||
|
|
|
@ -103,11 +103,16 @@ ThrowCompletionOr<Value> GeneratorObject::execute(VM& vm, Completion const& comp
|
||||||
completion_object->define_direct_property(vm.names.value, completion.value().value(), default_attributes);
|
completion_object->define_direct_property(vm.names.value, completion.value().value(), default_attributes);
|
||||||
|
|
||||||
auto* bytecode_interpreter = Bytecode::Interpreter::current();
|
auto* bytecode_interpreter = Bytecode::Interpreter::current();
|
||||||
|
|
||||||
|
// If we're coming from a context which has no bytecode interpreter, e.g. from AST mode calling Generate.prototype.next,
|
||||||
|
// we need to make one to be able to continue, as generators are only supported in bytecode mode.
|
||||||
|
// See also ECMAScriptFunctionObject::ordinary_call_evaluate_body where this is done as well.
|
||||||
OwnPtr<Bytecode::Interpreter> temp_bc_interpreter;
|
OwnPtr<Bytecode::Interpreter> temp_bc_interpreter;
|
||||||
if (!bytecode_interpreter) {
|
if (!bytecode_interpreter) {
|
||||||
temp_bc_interpreter = make<Bytecode::Interpreter>(realm);
|
temp_bc_interpreter = make<Bytecode::Interpreter>(realm);
|
||||||
bytecode_interpreter = temp_bc_interpreter.ptr();
|
bytecode_interpreter = temp_bc_interpreter.ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
VERIFY(bytecode_interpreter);
|
VERIFY(bytecode_interpreter);
|
||||||
|
|
||||||
auto const* next_block = generated_continuation(m_previous_value);
|
auto const* next_block = generated_continuation(m_previous_value);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue