mirror of
https://github.com/RGBCube/serenity
synced 2025-07-23 20:17:42 +00:00
LibJS: Convert GeneratorObject to ThrowCompletionOr
This commit is contained in:
parent
11a90700df
commit
91881be4b0
4 changed files with 16 additions and 25 deletions
|
@ -688,7 +688,7 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
|
||||||
if (m_kind != FunctionKind::Generator)
|
if (m_kind != FunctionKind::Generator)
|
||||||
return { Completion::Type::Return, result.value_or(js_undefined()), {} };
|
return { Completion::Type::Return, result.value_or(js_undefined()), {} };
|
||||||
|
|
||||||
return normal_completion(GeneratorObject::create(global_object(), result, this, vm.running_execution_context().lexical_environment, bytecode_interpreter->snapshot_frame()));
|
return normal_completion(TRY(GeneratorObject::create(global_object(), result, this, vm.running_execution_context().lexical_environment, bytecode_interpreter->snapshot_frame())));
|
||||||
} else {
|
} else {
|
||||||
if (m_kind != FunctionKind::Regular)
|
if (m_kind != FunctionKind::Regular)
|
||||||
return vm.throw_completion<InternalError>(global_object(), ErrorType::NotImplemented, "Non regular function execution in AST interpreter");
|
return vm.throw_completion<InternalError>(global_object(), ErrorType::NotImplemented, "Non regular function execution in AST interpreter");
|
||||||
|
|
|
@ -13,11 +13,11 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
GeneratorObject* GeneratorObject::create(GlobalObject& global_object, Value initial_value, ECMAScriptFunctionObject* generating_function, Environment* generating_scope, Bytecode::RegisterWindow frame)
|
ThrowCompletionOr<GeneratorObject*> GeneratorObject::create(GlobalObject& global_object, Value initial_value, ECMAScriptFunctionObject* generating_function, Environment* generating_scope, Bytecode::RegisterWindow frame)
|
||||||
{
|
{
|
||||||
// This is "g1.prototype" in figure-2 (https://tc39.es/ecma262/img/figure-2.png)
|
// This is "g1.prototype" in figure-2 (https://tc39.es/ecma262/img/figure-2.png)
|
||||||
auto generating_function_prototype = TRY_OR_DISCARD(generating_function->get(global_object.vm().names.prototype));
|
auto generating_function_prototype = TRY(generating_function->get(global_object.vm().names.prototype));
|
||||||
auto* generating_function_prototype_object = TRY_OR_DISCARD(generating_function_prototype.to_object(global_object));
|
auto* generating_function_prototype_object = TRY(generating_function_prototype.to_object(global_object));
|
||||||
auto object = global_object.heap().allocate<GeneratorObject>(global_object, global_object, *generating_function_prototype_object);
|
auto object = global_object.heap().allocate<GeneratorObject>(global_object, global_object, *generating_function_prototype_object);
|
||||||
object->m_generating_function = generating_function;
|
object->m_generating_function = generating_function;
|
||||||
object->m_environment = generating_scope;
|
object->m_environment = generating_scope;
|
||||||
|
@ -47,29 +47,26 @@ void GeneratorObject::visit_edges(Cell::Visitor& visitor)
|
||||||
visitor.visit(m_previous_value);
|
visitor.visit(m_previous_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value GeneratorObject::next_impl(VM& vm, GlobalObject& global_object, Optional<Value> value_to_throw)
|
ThrowCompletionOr<Value> GeneratorObject::next_impl(VM& vm, GlobalObject& global_object, Optional<Value> value_to_throw)
|
||||||
{
|
{
|
||||||
auto bytecode_interpreter = Bytecode::Interpreter::current();
|
auto bytecode_interpreter = Bytecode::Interpreter::current();
|
||||||
VERIFY(bytecode_interpreter);
|
VERIFY(bytecode_interpreter);
|
||||||
|
|
||||||
auto generated_value = [](Value value) -> Value {
|
auto generated_value = [](Value value) -> ThrowCompletionOr<Value> {
|
||||||
if (value.is_object())
|
if (value.is_object())
|
||||||
return TRY_OR_DISCARD(value.as_object().get("result"));
|
return TRY(value.as_object().get("result"));
|
||||||
return value.is_empty() ? js_undefined() : value;
|
return value.is_empty() ? js_undefined() : value;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto generated_continuation = [&](Value value) -> Bytecode::BasicBlock const* {
|
auto generated_continuation = [&](Value value) -> ThrowCompletionOr<Bytecode::BasicBlock const*> {
|
||||||
if (value.is_object()) {
|
if (value.is_object()) {
|
||||||
auto number_value = TRY_OR_DISCARD(value.as_object().get("continuation"));
|
auto number_value = TRY(value.as_object().get("continuation"));
|
||||||
return reinterpret_cast<Bytecode::BasicBlock const*>(static_cast<u64>(TRY_OR_DISCARD(number_value.to_double(global_object))));
|
return reinterpret_cast<Bytecode::BasicBlock const*>(static_cast<u64>(TRY(number_value.to_double(global_object))));
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
Value previous_generated_value { generated_value(m_previous_value) };
|
auto previous_generated_value = TRY(generated_value(m_previous_value));
|
||||||
|
|
||||||
if (vm.exception())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
auto result = Object::create(global_object, global_object.object_prototype());
|
auto result = Object::create(global_object, global_object.object_prototype());
|
||||||
result->define_direct_property("value", previous_generated_value, JS::default_attributes);
|
result->define_direct_property("value", previous_generated_value, JS::default_attributes);
|
||||||
|
@ -80,9 +77,7 @@ Value GeneratorObject::next_impl(VM& vm, GlobalObject& global_object, Optional<V
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract the continuation
|
// Extract the continuation
|
||||||
auto next_block = generated_continuation(m_previous_value);
|
auto next_block = TRY(generated_continuation(m_previous_value));
|
||||||
if (vm.exception())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
if (!next_block) {
|
if (!next_block) {
|
||||||
// The generator has terminated, now we can simply return done=true.
|
// The generator has terminated, now we can simply return done=true.
|
||||||
|
@ -112,14 +107,11 @@ Value GeneratorObject::next_impl(VM& vm, GlobalObject& global_object, Optional<V
|
||||||
|
|
||||||
bytecode_interpreter->leave_frame();
|
bytecode_interpreter->leave_frame();
|
||||||
|
|
||||||
m_done = generated_continuation(m_previous_value) == nullptr;
|
m_done = TRY(generated_continuation(m_previous_value)) == nullptr;
|
||||||
|
|
||||||
result->define_direct_property("value", generated_value(m_previous_value), JS::default_attributes);
|
result->define_direct_property("value", TRY(generated_value(m_previous_value)), JS::default_attributes);
|
||||||
result->define_direct_property("done", Value(m_done), JS::default_attributes);
|
result->define_direct_property("done", Value(m_done), JS::default_attributes);
|
||||||
|
|
||||||
if (vm.exception())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,13 @@ class GeneratorObject final : public Object {
|
||||||
JS_OBJECT(GeneratorObject, Object);
|
JS_OBJECT(GeneratorObject, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static GeneratorObject* create(GlobalObject&, Value, ECMAScriptFunctionObject*, Environment*, Bytecode::RegisterWindow);
|
static ThrowCompletionOr<GeneratorObject*> create(GlobalObject&, Value, ECMAScriptFunctionObject*, Environment*, Bytecode::RegisterWindow);
|
||||||
GeneratorObject(GlobalObject&, Object& prototype);
|
GeneratorObject(GlobalObject&, Object& prototype);
|
||||||
virtual void initialize(GlobalObject&) override;
|
virtual void initialize(GlobalObject&) override;
|
||||||
virtual ~GeneratorObject() override;
|
virtual ~GeneratorObject() override;
|
||||||
void visit_edges(Cell::Visitor&) override;
|
void visit_edges(Cell::Visitor&) override;
|
||||||
|
|
||||||
Value next_impl(VM&, GlobalObject&, Optional<Value> value_to_throw);
|
ThrowCompletionOr<Value> next_impl(VM&, GlobalObject&, Optional<Value> value_to_throw);
|
||||||
void set_done() { m_done = true; }
|
void set_done() { m_done = true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <LibJS/Bytecode/Interpreter.h>
|
|
||||||
#include <LibJS/Runtime/GeneratorObjectPrototype.h>
|
#include <LibJS/Runtime/GeneratorObjectPrototype.h>
|
||||||
#include <LibJS/Runtime/GlobalObject.h>
|
#include <LibJS/Runtime/GlobalObject.h>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue