mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 11:18:11 +00:00
LibJS: Add AsyncGenerator / AsyncGeneratorPrototype
Not implementing any prototype functions yet, but stubbing out async generator infrastructure will allow us to make some progress in that direction.
This commit is contained in:
parent
2c68ec9097
commit
0c65624a32
10 changed files with 162 additions and 9 deletions
|
@ -49,8 +49,10 @@ set(SOURCES
|
||||||
Runtime/AsyncFunctionConstructor.cpp
|
Runtime/AsyncFunctionConstructor.cpp
|
||||||
Runtime/AsyncFunctionDriverWrapper.cpp
|
Runtime/AsyncFunctionDriverWrapper.cpp
|
||||||
Runtime/AsyncFunctionPrototype.cpp
|
Runtime/AsyncFunctionPrototype.cpp
|
||||||
|
Runtime/AsyncGenerator.cpp
|
||||||
Runtime/AsyncGeneratorFunctionConstructor.cpp
|
Runtime/AsyncGeneratorFunctionConstructor.cpp
|
||||||
Runtime/AsyncGeneratorFunctionPrototype.cpp
|
Runtime/AsyncGeneratorFunctionPrototype.cpp
|
||||||
|
Runtime/AsyncGeneratorPrototype.cpp
|
||||||
Runtime/AsyncIteratorPrototype.cpp
|
Runtime/AsyncIteratorPrototype.cpp
|
||||||
Runtime/AtomicsObject.cpp
|
Runtime/AtomicsObject.cpp
|
||||||
Runtime/BigInt.cpp
|
Runtime/BigInt.cpp
|
||||||
|
|
|
@ -196,8 +196,10 @@ class ProxyObject;
|
||||||
class ProxyConstructor;
|
class ProxyConstructor;
|
||||||
|
|
||||||
// Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct constructor
|
// Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct constructor
|
||||||
class GeneratorPrototype;
|
|
||||||
class AsyncFromSyncIteratorPrototype;
|
class AsyncFromSyncIteratorPrototype;
|
||||||
|
class AsyncGenerator;
|
||||||
|
class AsyncGeneratorPrototype;
|
||||||
|
class GeneratorPrototype;
|
||||||
|
|
||||||
class TypedArrayConstructor;
|
class TypedArrayConstructor;
|
||||||
class TypedArrayPrototype;
|
class TypedArrayPrototype;
|
||||||
|
|
30
Userland/Libraries/LibJS/Runtime/AsyncGenerator.cpp
Normal file
30
Userland/Libraries/LibJS/Runtime/AsyncGenerator.cpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibJS/Runtime/AsyncGenerator.h>
|
||||||
|
#include <LibJS/Runtime/AsyncGeneratorPrototype.h>
|
||||||
|
#include <LibJS/Runtime/GlobalObject.h>
|
||||||
|
|
||||||
|
namespace JS {
|
||||||
|
|
||||||
|
AsyncGenerator::AsyncGenerator(Object& prototype)
|
||||||
|
: Object(prototype)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsyncGenerator::visit_edges(Cell::Visitor& visitor)
|
||||||
|
{
|
||||||
|
Base::visit_edges(visitor);
|
||||||
|
for (auto const& request : m_async_generator_queue) {
|
||||||
|
if (request.completion.value().has_value())
|
||||||
|
visitor.visit(*request.completion.value());
|
||||||
|
visitor.visit(request.capability.promise);
|
||||||
|
visitor.visit(request.capability.reject);
|
||||||
|
visitor.visit(request.capability.resolve);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
45
Userland/Libraries/LibJS/Runtime/AsyncGenerator.h
Normal file
45
Userland/Libraries/LibJS/Runtime/AsyncGenerator.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Variant.h>
|
||||||
|
#include <LibJS/Runtime/AsyncGeneratorRequest.h>
|
||||||
|
#include <LibJS/Runtime/ExecutionContext.h>
|
||||||
|
#include <LibJS/Runtime/Object.h>
|
||||||
|
|
||||||
|
namespace JS {
|
||||||
|
|
||||||
|
// 27.6.2 Properties of AsyncGenerator Instances, https://tc39.es/ecma262/#sec-properties-of-asyncgenerator-intances
|
||||||
|
class AsyncGenerator final : public Object {
|
||||||
|
JS_OBJECT(AsyncGenerator, Object);
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum class State {
|
||||||
|
SuspendedStart,
|
||||||
|
SuspendedYield,
|
||||||
|
Executing,
|
||||||
|
AwaitingReturn,
|
||||||
|
Completed,
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit AsyncGenerator(Object& prototype);
|
||||||
|
virtual ~AsyncGenerator() override = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void visit_edges(Cell::Visitor&) override;
|
||||||
|
|
||||||
|
// At the time of constructing an AsyncGenerator, we still need to point to an
|
||||||
|
// execution context on the stack, but later need to 'adopt' it.
|
||||||
|
using ExecutionContextVariant = Variant<ExecutionContext, ExecutionContext*, Empty>;
|
||||||
|
|
||||||
|
Optional<State> m_async_generator_state; // [[AsyncGeneratorState]]
|
||||||
|
ExecutionContextVariant m_async_generator_context; // [[AsyncGeneratorContext]]
|
||||||
|
Vector<AsyncGeneratorRequest> m_async_generator_queue; // [[AsyncGeneratorQueue]]
|
||||||
|
Optional<String> m_generator_brand; // [[GeneratorBrand]]
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <LibJS/Runtime/AsyncGeneratorFunctionConstructor.h>
|
#include <LibJS/Runtime/AsyncGeneratorFunctionConstructor.h>
|
||||||
#include <LibJS/Runtime/AsyncGeneratorFunctionPrototype.h>
|
#include <LibJS/Runtime/AsyncGeneratorFunctionPrototype.h>
|
||||||
|
#include <LibJS/Runtime/AsyncGeneratorPrototype.h>
|
||||||
#include <LibJS/Runtime/GlobalObject.h>
|
#include <LibJS/Runtime/GlobalObject.h>
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
@ -23,8 +24,7 @@ void AsyncGeneratorFunctionPrototype::initialize(GlobalObject& global_object)
|
||||||
// The constructor cannot be set at this point since it has not been initialized.
|
// The constructor cannot be set at this point since it has not been initialized.
|
||||||
|
|
||||||
// 27.4.3.2 AsyncGeneratorFunction.prototype.prototype, https://tc39.es/ecma262/#sec-asyncgeneratorfunction-prototype-prototype
|
// 27.4.3.2 AsyncGeneratorFunction.prototype.prototype, https://tc39.es/ecma262/#sec-asyncgeneratorfunction-prototype-prototype
|
||||||
// FIXME: AsyncGenerator does not exist yet.
|
define_direct_property(vm.names.prototype, global_object.async_generator_prototype(), Attribute::Configurable);
|
||||||
// define_direct_property(vm.names.prototype, global_object.async_generator_prototype(), Attribute::Configurable);
|
|
||||||
|
|
||||||
// 27.4.3.3 AsyncGeneratorFunction.prototype [ @@toStringTag ], https://tc39.es/ecma262/#sec-asyncgeneratorfunction-prototype-tostringtag
|
// 27.4.3.3 AsyncGeneratorFunction.prototype [ @@toStringTag ], https://tc39.es/ecma262/#sec-asyncgeneratorfunction-prototype-tostringtag
|
||||||
define_direct_property(*vm.well_known_symbol_to_string_tag(), js_string(vm, vm.names.AsyncGeneratorFunction.as_string()), Attribute::Configurable);
|
define_direct_property(*vm.well_known_symbol_to_string_tag(), js_string(vm, vm.names.AsyncGeneratorFunction.as_string()), Attribute::Configurable);
|
||||||
|
|
26
Userland/Libraries/LibJS/Runtime/AsyncGeneratorPrototype.cpp
Normal file
26
Userland/Libraries/LibJS/Runtime/AsyncGeneratorPrototype.cpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibJS/Runtime/AsyncGeneratorPrototype.h>
|
||||||
|
|
||||||
|
namespace JS {
|
||||||
|
|
||||||
|
// 27.6.1 Properties of the AsyncGenerator Prototype Object, https://tc39.es/ecma262/#sec-properties-of-asyncgenerator-prototype
|
||||||
|
AsyncGeneratorPrototype::AsyncGeneratorPrototype(GlobalObject& global_object)
|
||||||
|
: PrototypeObject(*global_object.async_iterator_prototype())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsyncGeneratorPrototype::initialize(GlobalObject& global_object)
|
||||||
|
{
|
||||||
|
auto& vm = this->vm();
|
||||||
|
Object::initialize(global_object);
|
||||||
|
|
||||||
|
// 27.6.1.5 AsyncGenerator.prototype [ @@toStringTag ], https://tc39.es/ecma262/#sec-asyncgenerator-prototype-tostringtag
|
||||||
|
define_direct_property(*vm.well_known_symbol_to_string_tag(), js_string(vm, "AsyncGenerator"), Attribute::Configurable);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
23
Userland/Libraries/LibJS/Runtime/AsyncGeneratorPrototype.h
Normal file
23
Userland/Libraries/LibJS/Runtime/AsyncGeneratorPrototype.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibJS/Runtime/AsyncGenerator.h>
|
||||||
|
#include <LibJS/Runtime/PrototypeObject.h>
|
||||||
|
|
||||||
|
namespace JS {
|
||||||
|
|
||||||
|
class AsyncGeneratorPrototype final : public PrototypeObject<AsyncGeneratorPrototype, AsyncGenerator> {
|
||||||
|
JS_PROTOTYPE_OBJECT(AsyncGeneratorPrototype, AsyncGenerator, AsyncGenerator)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AsyncGeneratorPrototype(GlobalObject&);
|
||||||
|
virtual void initialize(GlobalObject&) override;
|
||||||
|
virtual ~AsyncGeneratorPrototype() override = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
20
Userland/Libraries/LibJS/Runtime/AsyncGeneratorRequest.h
Normal file
20
Userland/Libraries/LibJS/Runtime/AsyncGeneratorRequest.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibJS/Runtime/Completion.h>
|
||||||
|
#include <LibJS/Runtime/PromiseReaction.h>
|
||||||
|
|
||||||
|
namespace JS {
|
||||||
|
|
||||||
|
// 27.6.3.1 AsyncGeneratorRequest Records, https://tc39.es/ecma262/#sec-asyncgeneratorrequest-records
|
||||||
|
struct AsyncGeneratorRequest {
|
||||||
|
Completion completion; // [[Completion]]
|
||||||
|
PromiseCapability capability; // [[Capability]]
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -28,6 +28,7 @@
|
||||||
#include <LibJS/Runtime/AsyncFunctionPrototype.h>
|
#include <LibJS/Runtime/AsyncFunctionPrototype.h>
|
||||||
#include <LibJS/Runtime/AsyncGeneratorFunctionConstructor.h>
|
#include <LibJS/Runtime/AsyncGeneratorFunctionConstructor.h>
|
||||||
#include <LibJS/Runtime/AsyncGeneratorFunctionPrototype.h>
|
#include <LibJS/Runtime/AsyncGeneratorFunctionPrototype.h>
|
||||||
|
#include <LibJS/Runtime/AsyncGeneratorPrototype.h>
|
||||||
#include <LibJS/Runtime/AsyncIteratorPrototype.h>
|
#include <LibJS/Runtime/AsyncIteratorPrototype.h>
|
||||||
#include <LibJS/Runtime/AtomicsObject.h>
|
#include <LibJS/Runtime/AtomicsObject.h>
|
||||||
#include <LibJS/Runtime/BigIntConstructor.h>
|
#include <LibJS/Runtime/BigIntConstructor.h>
|
||||||
|
@ -177,12 +178,10 @@ void GlobalObject::initialize_global_object()
|
||||||
JS_ENUMERATE_ITERATOR_PROTOTYPES
|
JS_ENUMERATE_ITERATOR_PROTOTYPES
|
||||||
#undef __JS_ENUMERATE
|
#undef __JS_ENUMERATE
|
||||||
|
|
||||||
// %GeneratorFunction.prototype.prototype% must be initialized separately as it has no
|
// These must be initialized separately as they have no companion constructor
|
||||||
// companion constructor
|
|
||||||
m_generator_prototype = heap().allocate<GeneratorPrototype>(*this, *this);
|
|
||||||
|
|
||||||
m_async_from_sync_iterator_prototype = heap().allocate<AsyncFromSyncIteratorPrototype>(*this, *this);
|
m_async_from_sync_iterator_prototype = heap().allocate<AsyncFromSyncIteratorPrototype>(*this, *this);
|
||||||
|
m_async_generator_prototype = heap().allocate<AsyncGeneratorPrototype>(*this, *this);
|
||||||
|
m_generator_prototype = heap().allocate<GeneratorPrototype>(*this, *this);
|
||||||
m_intl_segments_prototype = heap().allocate<Intl::SegmentsPrototype>(*this, *this);
|
m_intl_segments_prototype = heap().allocate<Intl::SegmentsPrototype>(*this, *this);
|
||||||
|
|
||||||
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \
|
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \
|
||||||
|
@ -298,6 +297,9 @@ void GlobalObject::initialize_global_object()
|
||||||
// 27.5.1.1 Generator.prototype.constructor, https://tc39.es/ecma262/#sec-generator.prototype.constructor
|
// 27.5.1.1 Generator.prototype.constructor, https://tc39.es/ecma262/#sec-generator.prototype.constructor
|
||||||
m_generator_prototype->define_direct_property(vm.names.constructor, m_generator_function_prototype, Attribute::Configurable);
|
m_generator_prototype->define_direct_property(vm.names.constructor, m_generator_function_prototype, Attribute::Configurable);
|
||||||
|
|
||||||
|
// 27.6.1.1 AsyncGenerator.prototype.constructor, https://tc39.es/ecma262/#sec-asyncgenerator-prototype-constructor
|
||||||
|
m_async_generator_prototype->define_direct_property(vm.names.constructor, m_async_generator_function_prototype, Attribute::Configurable);
|
||||||
|
|
||||||
m_array_prototype_values_function = &m_array_prototype->get_without_side_effects(vm.names.values).as_function();
|
m_array_prototype_values_function = &m_array_prototype->get_without_side_effects(vm.names.values).as_function();
|
||||||
m_date_constructor_now_function = &m_date_constructor->get_without_side_effects(vm.names.now).as_function();
|
m_date_constructor_now_function = &m_date_constructor->get_without_side_effects(vm.names.now).as_function();
|
||||||
m_eval_function = &get_without_side_effects(vm.names.eval).as_function();
|
m_eval_function = &get_without_side_effects(vm.names.eval).as_function();
|
||||||
|
@ -315,8 +317,9 @@ void GlobalObject::visit_edges(Visitor& visitor)
|
||||||
visitor.visit(m_new_object_shape);
|
visitor.visit(m_new_object_shape);
|
||||||
visitor.visit(m_new_ordinary_function_prototype_object_shape);
|
visitor.visit(m_new_ordinary_function_prototype_object_shape);
|
||||||
visitor.visit(m_proxy_constructor);
|
visitor.visit(m_proxy_constructor);
|
||||||
visitor.visit(m_generator_prototype);
|
|
||||||
visitor.visit(m_async_from_sync_iterator_prototype);
|
visitor.visit(m_async_from_sync_iterator_prototype);
|
||||||
|
visitor.visit(m_async_generator_prototype);
|
||||||
|
visitor.visit(m_generator_prototype);
|
||||||
visitor.visit(m_intl_segments_prototype);
|
visitor.visit(m_intl_segments_prototype);
|
||||||
visitor.visit(m_array_prototype_values_function);
|
visitor.visit(m_array_prototype_values_function);
|
||||||
visitor.visit(m_date_constructor_now_function);
|
visitor.visit(m_date_constructor_now_function);
|
||||||
|
|
|
@ -37,6 +37,7 @@ public:
|
||||||
|
|
||||||
// Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct constructor
|
// Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct constructor
|
||||||
Object* async_from_sync_iterator_prototype() { return m_async_from_sync_iterator_prototype; }
|
Object* async_from_sync_iterator_prototype() { return m_async_from_sync_iterator_prototype; }
|
||||||
|
Object* async_generator_prototype() { return m_async_generator_prototype; }
|
||||||
Object* generator_prototype() { return m_generator_prototype; }
|
Object* generator_prototype() { return m_generator_prototype; }
|
||||||
|
|
||||||
// Not included in JS_ENUMERATE_INTL_OBJECTS due to missing distinct constructor
|
// Not included in JS_ENUMERATE_INTL_OBJECTS due to missing distinct constructor
|
||||||
|
@ -109,6 +110,7 @@ private:
|
||||||
|
|
||||||
// Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct constructor
|
// Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct constructor
|
||||||
Object* m_async_from_sync_iterator_prototype { nullptr };
|
Object* m_async_from_sync_iterator_prototype { nullptr };
|
||||||
|
Object* m_async_generator_prototype { nullptr };
|
||||||
Object* m_generator_prototype { nullptr };
|
Object* m_generator_prototype { nullptr };
|
||||||
|
|
||||||
// Not included in JS_ENUMERATE_INTL_OBJECTS due to missing distinct constructor
|
// Not included in JS_ENUMERATE_INTL_OBJECTS due to missing distinct constructor
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue