mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 08:15:31 +00:00
Bug 1288457 - Part 15: Add JSProtoKey for AsyncGeneratorFunction. r=mgaudet
Differential Revision: https://phabricator.services.mozilla.com/D42885 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
d80c1ed430
commit
7a5b5e0a24
@ -746,7 +746,7 @@ static const uint32_t JSCLASS_FOREGROUND_FINALIZE =
|
||||
// application.
|
||||
static const uint32_t JSCLASS_GLOBAL_APPLICATION_SLOTS = 5;
|
||||
static const uint32_t JSCLASS_GLOBAL_SLOT_COUNT =
|
||||
JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 28;
|
||||
JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 26;
|
||||
|
||||
static constexpr uint32_t JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(uint32_t n) {
|
||||
return JSCLASS_IS_GLOBAL |
|
||||
|
@ -119,6 +119,7 @@
|
||||
REAL(Promise, InitViaClassSpec, OCLASP(Promise)) \
|
||||
REAL(AsyncFunction, InitAsyncFunction, nullptr) \
|
||||
REAL(GeneratorFunction, InitGeneratorFunction, nullptr) \
|
||||
REAL(AsyncGeneratorFunction, InitAsyncGeneratorFunction, nullptr) \
|
||||
REAL(ReadableStream, InitViaClassSpec, &js::ReadableStream::class_) \
|
||||
REAL(ReadableStreamDefaultReader, InitViaClassSpec, \
|
||||
&js::ReadableStreamDefaultReader::class_) \
|
||||
|
@ -912,7 +912,8 @@ JS_PUBLIC_API bool JS_ResolveStandardClass(JSContext* cx, HandleObject obj,
|
||||
// property, so we won't resolve anything.
|
||||
JSProtoKey key = stdnm ? stdnm->key : JSProto_Null;
|
||||
if (key != JSProto_Null && key != JSProto_AsyncFunction &&
|
||||
key != JSProto_GeneratorFunction) {
|
||||
key != JSProto_GeneratorFunction &&
|
||||
key != JSProto_AsyncGeneratorFunction) {
|
||||
const JSClass* clasp = ProtoKeyToClass(key);
|
||||
if (!clasp || clasp->specShouldDefineConstructor()) {
|
||||
if (!GlobalObject::ensureConstructor(cx, global, key)) {
|
||||
@ -988,8 +989,9 @@ static bool EnumerateStandardClassesInTable(JSContext* cx,
|
||||
continue;
|
||||
}
|
||||
|
||||
// AsyncFunction and Generator don't yet use ClassSpec.
|
||||
if (key == JSProto_AsyncFunction || key == JSProto_GeneratorFunction) {
|
||||
// Async(Function|Generator) and Generator don't yet use ClassSpec.
|
||||
if (key == JSProto_AsyncFunction || key == JSProto_GeneratorFunction ||
|
||||
key == JSProto_AsyncGeneratorFunction) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -406,21 +406,17 @@ static const JSFunctionSpec async_generator_methods[] = {
|
||||
JS_FN("throw", AsyncGeneratorThrow, 1, 0),
|
||||
JS_FN("return", AsyncGeneratorReturn, 1, 0), JS_FS_END};
|
||||
|
||||
/* static */ MOZ_MUST_USE bool GlobalObject::initAsyncGenerators(
|
||||
JSContext* cx, Handle<GlobalObject*> global) {
|
||||
if (global->getReservedSlot(ASYNC_ITERATOR_PROTO).isObject()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
JSObject* js::InitAsyncGeneratorFunction(JSContext* cx,
|
||||
Handle<GlobalObject*> global) {
|
||||
// 25.1.3 The %AsyncIteratorPrototype% Object
|
||||
RootedObject asyncIterProto(
|
||||
cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
|
||||
if (!asyncIterProto) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
if (!DefinePropertiesAndFunctions(cx, asyncIterProto, nullptr,
|
||||
async_iterator_proto_methods)) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 25.1.4.2 The %AsyncFromSyncIteratorPrototype% Object
|
||||
@ -428,44 +424,44 @@ static const JSFunctionSpec async_generator_methods[] = {
|
||||
cx, GlobalObject::createBlankPrototypeInheriting(cx, &PlainObject::class_,
|
||||
asyncIterProto));
|
||||
if (!asyncFromSyncIterProto) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
if (!DefinePropertiesAndFunctions(cx, asyncFromSyncIterProto, nullptr,
|
||||
async_from_sync_iter_methods) ||
|
||||
!DefineToStringTag(cx, asyncFromSyncIterProto,
|
||||
cx->names().AsyncFromSyncIterator)) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 25.5 AsyncGenerator Objects
|
||||
RootedObject asyncGenProto(cx, GlobalObject::createBlankPrototypeInheriting(
|
||||
cx, &PlainObject::class_, asyncIterProto));
|
||||
if (!asyncGenProto) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
if (!DefinePropertiesAndFunctions(cx, asyncGenProto, nullptr,
|
||||
async_generator_methods) ||
|
||||
!DefineToStringTag(cx, asyncGenProto, cx->names().AsyncGenerator)) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 25.3.3 Properties of the AsyncGeneratorFunction Prototype Object
|
||||
RootedObject asyncGenerator(
|
||||
cx, NewSingletonObjectWithFunctionPrototype(cx, global));
|
||||
if (!asyncGenerator) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
if (!LinkConstructorAndPrototype(cx, asyncGenerator, asyncGenProto,
|
||||
JSPROP_READONLY, JSPROP_READONLY) ||
|
||||
!DefineToStringTag(cx, asyncGenerator,
|
||||
cx->names().AsyncGeneratorFunction)) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RootedObject proto(
|
||||
cx, GlobalObject::getOrCreateFunctionConstructor(cx, cx->global()));
|
||||
if (!proto) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
HandlePropertyName name = cx->names().AsyncGeneratorFunction;
|
||||
|
||||
@ -475,20 +471,21 @@ static const JSFunctionSpec async_generator_methods[] = {
|
||||
FunctionFlags::NATIVE_CTOR, nullptr, name, proto,
|
||||
gc::AllocKind::FUNCTION, SingletonObject));
|
||||
if (!asyncGenFunction) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
if (!LinkConstructorAndPrototype(cx, asyncGenFunction, asyncGenerator,
|
||||
JSPROP_PERMANENT | JSPROP_READONLY,
|
||||
JSPROP_READONLY)) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
global->setReservedSlot(ASYNC_ITERATOR_PROTO, ObjectValue(*asyncIterProto));
|
||||
global->setReservedSlot(ASYNC_FROM_SYNC_ITERATOR_PROTO,
|
||||
ObjectValue(*asyncFromSyncIterProto));
|
||||
global->setReservedSlot(ASYNC_GENERATOR, ObjectValue(*asyncGenerator));
|
||||
global->setReservedSlot(ASYNC_GENERATOR_FUNCTION,
|
||||
ObjectValue(*asyncGenFunction));
|
||||
global->setReservedSlot(ASYNC_GENERATOR_PROTO, ObjectValue(*asyncGenProto));
|
||||
return true;
|
||||
global->setAsyncIteratorPrototype(asyncIterProto);
|
||||
global->setAsyncFromSyncIteratorPrototype(asyncFromSyncIterProto);
|
||||
global->setAsyncGeneratorPrototype(asyncGenProto);
|
||||
|
||||
global->setConstructor(JSProto_AsyncGeneratorFunction,
|
||||
ObjectValue(*asyncGenFunction));
|
||||
global->setPrototype(JSProto_AsyncGeneratorFunction,
|
||||
ObjectValue(*asyncGenerator));
|
||||
return asyncGenFunction;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
namespace js {
|
||||
|
||||
class AsyncGeneratorObject;
|
||||
class GlobalObject;
|
||||
|
||||
// Resume the async generator when the `await` operand fulfills to `value`.
|
||||
MOZ_MUST_USE bool AsyncGeneratorAwaitedFulfilled(
|
||||
@ -294,6 +295,9 @@ MOZ_MUST_USE bool AsyncGeneratorResume(
|
||||
JSContext* cx, Handle<AsyncGeneratorObject*> asyncGenObj,
|
||||
CompletionKind completionKind, HandleValue argument);
|
||||
|
||||
extern JSObject* InitAsyncGeneratorFunction(JSContext* cx,
|
||||
js::Handle<GlobalObject*> global);
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif /* vm_AsyncIteration_h */
|
||||
|
@ -36,8 +36,6 @@
|
||||
MACRO(AsyncFunctionNext, AsyncFunctionNext, "AsyncFunctionNext") \
|
||||
MACRO(AsyncFunctionThrow, AsyncFunctionThrow, "AsyncFunctionThrow") \
|
||||
MACRO(AsyncGenerator, AsyncGenerator, "AsyncGenerator") \
|
||||
MACRO(AsyncGeneratorFunction, AsyncGeneratorFunction, \
|
||||
"AsyncGeneratorFunction") \
|
||||
MACRO(AsyncGeneratorNext, AsyncGeneratorNext, "AsyncGeneratorNext") \
|
||||
MACRO(AsyncGeneratorReturn, AsyncGeneratorReturn, "AsyncGeneratorReturn") \
|
||||
MACRO(AsyncGeneratorThrow, AsyncGeneratorThrow, "AsyncGeneratorThrow") \
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "gc/FreeOp.h"
|
||||
#include "js/ProtoKey.h"
|
||||
#include "vm/AsyncFunction.h"
|
||||
#include "vm/AsyncIteration.h"
|
||||
#include "vm/DateObject.h"
|
||||
#include "vm/EnvironmentObject.h"
|
||||
#include "vm/GeneratorObject.h"
|
||||
@ -402,7 +403,8 @@ bool GlobalObject::resolveOffThreadConstructor(JSContext* cx,
|
||||
MOZ_ASSERT(global->zone()->createdForHelperThread());
|
||||
MOZ_ASSERT(key == JSProto_Object || key == JSProto_Function ||
|
||||
key == JSProto_Array || key == JSProto_RegExp ||
|
||||
key == JSProto_AsyncFunction || key == JSProto_GeneratorFunction);
|
||||
key == JSProto_AsyncFunction || key == JSProto_GeneratorFunction ||
|
||||
key == JSProto_AsyncGeneratorFunction);
|
||||
|
||||
Rooted<OffThreadPlaceholderObject*> placeholder(cx);
|
||||
placeholder = OffThreadPlaceholderObject::New(cx, prototypeSlot(key));
|
||||
@ -439,9 +441,8 @@ JSObject* GlobalObject::createOffThreadObject(JSContext* cx,
|
||||
// compartment.
|
||||
|
||||
MOZ_ASSERT(global->zone()->createdForHelperThread());
|
||||
MOZ_ASSERT(slot == ASYNC_GENERATOR || slot == MODULE_PROTO ||
|
||||
slot == IMPORT_ENTRY_PROTO || slot == EXPORT_ENTRY_PROTO ||
|
||||
slot == REQUESTED_MODULE_PROTO);
|
||||
MOZ_ASSERT(slot == MODULE_PROTO || slot == IMPORT_ENTRY_PROTO ||
|
||||
slot == EXPORT_ENTRY_PROTO || slot == REQUESTED_MODULE_PROTO);
|
||||
|
||||
auto placeholder = OffThreadPlaceholderObject::New(cx, slot);
|
||||
if (!placeholder) {
|
||||
|
@ -79,8 +79,6 @@ class GlobalObject : public NativeObject {
|
||||
GENERATOR_OBJECT_PROTO,
|
||||
ASYNC_ITERATOR_PROTO,
|
||||
ASYNC_FROM_SYNC_ITERATOR_PROTO,
|
||||
ASYNC_GENERATOR,
|
||||
ASYNC_GENERATOR_FUNCTION,
|
||||
ASYNC_GENERATOR_PROTO,
|
||||
MAP_ITERATOR_PROTO,
|
||||
SET_ITERATOR_PROTO,
|
||||
@ -624,34 +622,66 @@ class GlobalObject : public NativeObject {
|
||||
return &global->getConstructor(JSProto_AsyncFunction).toObject();
|
||||
}
|
||||
|
||||
void setAsyncIteratorPrototype(JSObject* obj) {
|
||||
MOZ_ASSERT(getReservedSlot(ASYNC_ITERATOR_PROTO).isUndefined());
|
||||
MOZ_ASSERT(obj != nullptr);
|
||||
setSlot(ASYNC_ITERATOR_PROTO, ObjectValue(*obj));
|
||||
}
|
||||
|
||||
void setAsyncFromSyncIteratorPrototype(JSObject* obj) {
|
||||
MOZ_ASSERT(getReservedSlot(ASYNC_FROM_SYNC_ITERATOR_PROTO).isUndefined());
|
||||
MOZ_ASSERT(obj != nullptr);
|
||||
setSlot(ASYNC_FROM_SYNC_ITERATOR_PROTO, ObjectValue(*obj));
|
||||
}
|
||||
|
||||
static NativeObject* getOrCreateAsyncIteratorPrototype(
|
||||
JSContext* cx, Handle<GlobalObject*> global) {
|
||||
return MaybeNativeObject(getOrCreateObject(cx, global, ASYNC_ITERATOR_PROTO,
|
||||
initAsyncGenerators));
|
||||
if (!ensureConstructor(cx, global, JSProto_AsyncGeneratorFunction)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getSlot(ASYNC_ITERATOR_PROTO).toObject().as<NativeObject>();
|
||||
}
|
||||
|
||||
static NativeObject* getOrCreateAsyncFromSyncIteratorPrototype(
|
||||
JSContext* cx, Handle<GlobalObject*> global) {
|
||||
return MaybeNativeObject(getOrCreateObject(
|
||||
cx, global, ASYNC_FROM_SYNC_ITERATOR_PROTO, initAsyncGenerators));
|
||||
if (!ensureConstructor(cx, global, JSProto_AsyncGeneratorFunction)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getSlot(ASYNC_FROM_SYNC_ITERATOR_PROTO)
|
||||
.toObject()
|
||||
.as<NativeObject>();
|
||||
}
|
||||
|
||||
static NativeObject* getOrCreateAsyncGenerator(JSContext* cx,
|
||||
Handle<GlobalObject*> global) {
|
||||
return MaybeNativeObject(
|
||||
getOrCreateObject(cx, global, ASYNC_GENERATOR, initAsyncGenerators));
|
||||
if (!ensureConstructor(cx, global, JSProto_AsyncGeneratorFunction)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_AsyncGeneratorFunction)
|
||||
.toObject()
|
||||
.as<NativeObject>();
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateAsyncGeneratorFunction(
|
||||
JSContext* cx, Handle<GlobalObject*> global) {
|
||||
return getOrCreateObject(cx, global, ASYNC_GENERATOR_FUNCTION,
|
||||
initAsyncGenerators);
|
||||
if (!ensureConstructor(cx, global, JSProto_AsyncGeneratorFunction)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getConstructor(JSProto_AsyncGeneratorFunction).toObject();
|
||||
}
|
||||
|
||||
void setAsyncGeneratorPrototype(JSObject* obj) {
|
||||
setSlot(ASYNC_GENERATOR_PROTO, ObjectValue(*obj));
|
||||
}
|
||||
|
||||
static NativeObject* getOrCreateAsyncGeneratorPrototype(
|
||||
JSContext* cx, Handle<GlobalObject*> global) {
|
||||
return MaybeNativeObject(getOrCreateObject(
|
||||
cx, global, ASYNC_GENERATOR_PROTO, initAsyncGenerators));
|
||||
if (!ensureConstructor(cx, global, JSProto_AsyncGeneratorFunction)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getSlot(ASYNC_GENERATOR_PROTO)
|
||||
.toObject()
|
||||
.as<NativeObject>();
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateMapIteratorPrototype(
|
||||
@ -789,8 +819,6 @@ class GlobalObject : public NativeObject {
|
||||
static bool initRegExpStringIteratorProto(JSContext* cx,
|
||||
Handle<GlobalObject*> global);
|
||||
|
||||
static bool initAsyncGenerators(JSContext* cx, Handle<GlobalObject*> global);
|
||||
|
||||
// Implemented in builtin/MapObject.cpp.
|
||||
static bool initMapIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
|
||||
static bool initSetIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
|
||||
|
@ -850,7 +850,7 @@ static bool EnsureParserCreatedClasses(JSContext* cx, ParseTaskKind kind) {
|
||||
return false; // needed by async function() {}
|
||||
}
|
||||
|
||||
if (!GlobalObject::initAsyncGenerators(cx, global)) {
|
||||
if (!EnsureConstructor(cx, global, JSProto_AsyncGeneratorFunction)) {
|
||||
return false; // needed by async function*() {}
|
||||
}
|
||||
|
||||
|
@ -1941,13 +1941,14 @@ static bool CreateDynamicFunction(JSContext* cx, const CallArgs& args,
|
||||
return false;
|
||||
}
|
||||
|
||||
JSProtoKey protoKey = JSProto_Null;
|
||||
JSProtoKey protoKey;
|
||||
if (isAsync) {
|
||||
if (isGenerator) {
|
||||
if (!CompileStandaloneAsyncGenerator(cx, &fun, options, srcBuf,
|
||||
parameterListEnd)) {
|
||||
return false;
|
||||
}
|
||||
protoKey = JSProto_AsyncGeneratorFunction;
|
||||
} else {
|
||||
if (!CompileStandaloneAsyncFunction(cx, &fun, options, srcBuf,
|
||||
parameterListEnd)) {
|
||||
|
Loading…
Reference in New Issue
Block a user