1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 05:37:43 +00:00

LibJS: Add the remaining generator objects

- %GeneratorFunction%
- %GeneratorFunction.prototype%
- %GeneratorFunction.prototype.prototype%
- %Generator%.prototype
This commit is contained in:
Matthew Olsson 2021-06-15 00:04:08 -07:00 committed by Linus Groh
parent b205c9814a
commit 22b17219ff
14 changed files with 302 additions and 67 deletions

View file

@ -8,13 +8,19 @@
#include <LibJS/Bytecode/Generator.h>
#include <LibJS/Bytecode/Interpreter.h>
#include <LibJS/Runtime/GeneratorObject.h>
#include <LibJS/Runtime/GeneratorObjectPrototype.h>
#include <LibJS/Runtime/GlobalObject.h>
namespace JS {
GeneratorObject* GeneratorObject::create(GlobalObject& global_object, Value initial_value, ScriptFunction* generating_function, ScopeObject* generating_scope, Bytecode::RegisterWindow frame)
{
auto object = global_object.heap().allocate<GeneratorObject>(global_object, global_object);
// This is "g1.prototype" in figure-2 (https://tc39.es/ecma262/img/figure-2.png)
auto generating_function_proto_property = generating_function->get(global_object.vm().names.prototype).to_object(global_object);
if (!generating_function_proto_property)
return {};
auto object = global_object.heap().allocate<GeneratorObject>(global_object, global_object, *generating_function_proto_property);
object->m_generating_function = generating_function;
object->m_scope = generating_scope;
object->m_frame = move(frame);
@ -22,21 +28,13 @@ GeneratorObject* GeneratorObject::create(GlobalObject& global_object, Value init
return object;
}
GeneratorObject::GeneratorObject(GlobalObject& global_object)
: Object(*global_object.object_prototype())
GeneratorObject::GeneratorObject(GlobalObject&, Object& prototype)
: Object(prototype)
{
}
void GeneratorObject::initialize(GlobalObject& global_object)
void GeneratorObject::initialize(GlobalObject&)
{
// FIXME: These should be on a separate Generator prototype object!
// https://tc39.es/ecma262/#sec-generator-objects
auto& vm = this->vm();
Object::initialize(global_object);
define_native_function(vm.names.next, next);
define_native_function(vm.names.return_, return_);
define_native_function(vm.names.throw_, throw_);
}
GeneratorObject::~GeneratorObject()
@ -52,18 +50,6 @@ void GeneratorObject::visit_edges(Cell::Visitor& visitor)
visitor.visit(&m_previous_value.as_object());
}
GeneratorObject* GeneratorObject::typed_this(VM& vm, GlobalObject& global_object)
{
auto* this_object = vm.this_value(global_object).to_object(global_object);
if (!this_object)
return {};
if (!is<GeneratorObject>(this_object)) {
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "Generator");
return nullptr;
}
return static_cast<GeneratorObject*>(this_object);
}
Value GeneratorObject::next_impl(VM& vm, GlobalObject& global_object, Optional<Value> value_to_throw)
{
auto bytecode_interpreter = Bytecode::Interpreter::current();
@ -138,29 +124,4 @@ Value GeneratorObject::next_impl(VM& vm, GlobalObject& global_object, Optional<V
return result;
}
JS_DEFINE_NATIVE_FUNCTION(GeneratorObject::next)
{
auto object = typed_this(vm, global_object);
if (!object)
return {};
return object->next_impl(vm, global_object, {});
}
JS_DEFINE_NATIVE_FUNCTION(GeneratorObject::return_)
{
auto object = typed_this(vm, global_object);
if (!object)
return {};
object->m_done = true;
return object->next_impl(vm, global_object, {});
}
JS_DEFINE_NATIVE_FUNCTION(GeneratorObject::throw_)
{
auto object = typed_this(vm, global_object);
if (!object)
return {};
return object->next_impl(vm, global_object, vm.argument(0));
}
}