mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 08:15:31 +00:00
Bug 1288457 - Part 14: Add JSProtoKey for GeneratorFunction. r=mgaudet
Differential Revision: https://phabricator.services.mozilla.com/D42884 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
966f19f7e0
commit
d80c1ed430
@ -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 + 30;
|
||||
JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 28;
|
||||
|
||||
static constexpr uint32_t JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(uint32_t n) {
|
||||
return JSCLASS_IS_GLOBAL |
|
||||
|
@ -118,6 +118,7 @@
|
||||
REAL(SavedFrame, InitViaClassSpec, &js::SavedFrame::class_) \
|
||||
REAL(Promise, InitViaClassSpec, OCLASP(Promise)) \
|
||||
REAL(AsyncFunction, InitAsyncFunction, nullptr) \
|
||||
REAL(GeneratorFunction, InitGeneratorFunction, nullptr) \
|
||||
REAL(ReadableStream, InitViaClassSpec, &js::ReadableStream::class_) \
|
||||
REAL(ReadableStreamDefaultReader, InitViaClassSpec, \
|
||||
&js::ReadableStreamDefaultReader::class_) \
|
||||
|
@ -911,7 +911,8 @@ JS_PUBLIC_API bool JS_ResolveStandardClass(JSContext* cx, HandleObject obj,
|
||||
// If this class is anonymous, then it doesn't exist as a global
|
||||
// property, so we won't resolve anything.
|
||||
JSProtoKey key = stdnm ? stdnm->key : JSProto_Null;
|
||||
if (key != JSProto_Null && key != JSProto_AsyncFunction) {
|
||||
if (key != JSProto_Null && key != JSProto_AsyncFunction &&
|
||||
key != JSProto_GeneratorFunction) {
|
||||
const JSClass* clasp = ProtoKeyToClass(key);
|
||||
if (!clasp || clasp->specShouldDefineConstructor()) {
|
||||
if (!GlobalObject::ensureConstructor(cx, global, key)) {
|
||||
@ -987,8 +988,8 @@ static bool EnumerateStandardClassesInTable(JSContext* cx,
|
||||
continue;
|
||||
}
|
||||
|
||||
// AsyncFunction doesn't yet use ClassSpec.
|
||||
if (key == JSProto_AsyncFunction) {
|
||||
// AsyncFunction and Generator don't yet use ClassSpec.
|
||||
if (key == JSProto_AsyncFunction || key == JSProto_GeneratorFunction) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,6 @@
|
||||
MACRO(futexTimedOut, futexTimedOut, "timed-out") \
|
||||
MACRO(gcCycleNumber, gcCycleNumber, "gcCycleNumber") \
|
||||
MACRO(Generator, Generator, "Generator") \
|
||||
MACRO(GeneratorFunction, GeneratorFunction, "GeneratorFunction") \
|
||||
MACRO(GeneratorNext, GeneratorNext, "GeneratorNext") \
|
||||
MACRO(GeneratorReturn, GeneratorReturn, "GeneratorReturn") \
|
||||
MACRO(GeneratorThrow, GeneratorThrow, "GeneratorThrow") \
|
||||
|
@ -240,44 +240,40 @@ JSObject* js::NewSingletonObjectWithFunctionPrototype(
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool GlobalObject::initGenerators(JSContext* cx, Handle<GlobalObject*> global) {
|
||||
if (global->getReservedSlot(GENERATOR_OBJECT_PROTO).isObject()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
JSObject* js::InitGeneratorFunction(JSContext* cx,
|
||||
Handle<GlobalObject*> global) {
|
||||
RootedObject iteratorProto(
|
||||
cx, GlobalObject::getOrCreateIteratorPrototype(cx, global));
|
||||
if (!iteratorProto) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RootedObject genObjectProto(cx, GlobalObject::createBlankPrototypeInheriting(
|
||||
cx, &PlainObject::class_, iteratorProto));
|
||||
if (!genObjectProto) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
if (!DefinePropertiesAndFunctions(cx, genObjectProto, nullptr,
|
||||
generator_methods) ||
|
||||
!DefineToStringTag(cx, genObjectProto, cx->names().Generator)) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RootedObject genFunctionProto(
|
||||
cx, NewSingletonObjectWithFunctionPrototype(cx, global));
|
||||
if (!genFunctionProto) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
if (!LinkConstructorAndPrototype(cx, genFunctionProto, genObjectProto,
|
||||
JSPROP_READONLY, JSPROP_READONLY) ||
|
||||
!DefineToStringTag(cx, genFunctionProto, cx->names().GeneratorFunction)) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RootedObject proto(
|
||||
cx, GlobalObject::getOrCreateFunctionConstructor(cx, cx->global()));
|
||||
if (!proto) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
HandlePropertyName name = cx->names().GeneratorFunction;
|
||||
RootedObject genFunction(
|
||||
@ -285,19 +281,19 @@ bool GlobalObject::initGenerators(JSContext* cx, Handle<GlobalObject*> global) {
|
||||
nullptr, name, proto, gc::AllocKind::FUNCTION,
|
||||
SingletonObject));
|
||||
if (!genFunction) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
if (!LinkConstructorAndPrototype(cx, genFunction, genFunctionProto,
|
||||
JSPROP_PERMANENT | JSPROP_READONLY,
|
||||
JSPROP_READONLY)) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
global->setReservedSlot(GENERATOR_OBJECT_PROTO, ObjectValue(*genObjectProto));
|
||||
global->setReservedSlot(GENERATOR_FUNCTION, ObjectValue(*genFunction));
|
||||
global->setReservedSlot(GENERATOR_FUNCTION_PROTO,
|
||||
ObjectValue(*genFunctionProto));
|
||||
return true;
|
||||
global->setGeneratorObjectPrototype(genObjectProto);
|
||||
global->setConstructor(JSProto_GeneratorFunction, ObjectValue(*genFunction));
|
||||
global->setPrototype(JSProto_GeneratorFunction,
|
||||
ObjectValue(*genFunctionProto));
|
||||
return genFunction;
|
||||
}
|
||||
|
||||
bool AbstractGeneratorObject::isAfterYield() {
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
namespace js {
|
||||
|
||||
class GlobalObject;
|
||||
|
||||
enum class GeneratorResumeKind { Next, Throw, Return };
|
||||
|
||||
class AbstractGeneratorObject : public NativeObject {
|
||||
@ -223,6 +225,9 @@ AbstractGeneratorObject* GetGeneratorObjectForFrame(JSContext* cx,
|
||||
|
||||
void SetGeneratorClosed(JSContext* cx, AbstractFramePtr frame);
|
||||
|
||||
extern JSObject* InitGeneratorFunction(JSContext* cx,
|
||||
js::Handle<GlobalObject*> global);
|
||||
|
||||
} // namespace js
|
||||
|
||||
template <>
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "vm/AsyncFunction.h"
|
||||
#include "vm/DateObject.h"
|
||||
#include "vm/EnvironmentObject.h"
|
||||
#include "vm/GeneratorObject.h"
|
||||
#include "vm/HelperThreads.h"
|
||||
#include "vm/JSContext.h"
|
||||
#include "vm/PIC.h"
|
||||
@ -401,7 +402,7 @@ 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_AsyncFunction || key == JSProto_GeneratorFunction);
|
||||
|
||||
Rooted<OffThreadPlaceholderObject*> placeholder(cx);
|
||||
placeholder = OffThreadPlaceholderObject::New(cx, prototypeSlot(key));
|
||||
@ -438,9 +439,9 @@ JSObject* GlobalObject::createOffThreadObject(JSContext* cx,
|
||||
// compartment.
|
||||
|
||||
MOZ_ASSERT(global->zone()->createdForHelperThread());
|
||||
MOZ_ASSERT(slot == GENERATOR_FUNCTION_PROTO || slot == ASYNC_GENERATOR ||
|
||||
slot == MODULE_PROTO || slot == IMPORT_ENTRY_PROTO ||
|
||||
slot == EXPORT_ENTRY_PROTO || slot == REQUESTED_MODULE_PROTO);
|
||||
MOZ_ASSERT(slot == ASYNC_GENERATOR || slot == MODULE_PROTO ||
|
||||
slot == IMPORT_ENTRY_PROTO || slot == EXPORT_ENTRY_PROTO ||
|
||||
slot == REQUESTED_MODULE_PROTO);
|
||||
|
||||
auto placeholder = OffThreadPlaceholderObject::New(cx, slot);
|
||||
if (!placeholder) {
|
||||
|
@ -77,8 +77,6 @@ class GlobalObject : public NativeObject {
|
||||
STRING_ITERATOR_PROTO,
|
||||
REGEXP_STRING_ITERATOR_PROTO,
|
||||
GENERATOR_OBJECT_PROTO,
|
||||
GENERATOR_FUNCTION_PROTO,
|
||||
GENERATOR_FUNCTION,
|
||||
ASYNC_ITERATOR_PROTO,
|
||||
ASYNC_FROM_SYNC_ITERATOR_PROTO,
|
||||
ASYNC_GENERATOR,
|
||||
@ -578,21 +576,34 @@ class GlobalObject : public NativeObject {
|
||||
initRegExpStringIteratorProto));
|
||||
}
|
||||
|
||||
void setGeneratorObjectPrototype(JSObject* obj) {
|
||||
setSlot(GENERATOR_OBJECT_PROTO, ObjectValue(*obj));
|
||||
}
|
||||
|
||||
static NativeObject* getOrCreateGeneratorObjectPrototype(
|
||||
JSContext* cx, Handle<GlobalObject*> global) {
|
||||
return MaybeNativeObject(
|
||||
getOrCreateObject(cx, global, GENERATOR_OBJECT_PROTO, initGenerators));
|
||||
if (!ensureConstructor(cx, global, JSProto_GeneratorFunction)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getSlot(GENERATOR_OBJECT_PROTO)
|
||||
.toObject()
|
||||
.as<NativeObject>();
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateGeneratorFunctionPrototype(
|
||||
JSContext* cx, Handle<GlobalObject*> global) {
|
||||
return getOrCreateObject(cx, global, GENERATOR_FUNCTION_PROTO,
|
||||
initGenerators);
|
||||
if (!ensureConstructor(cx, global, JSProto_GeneratorFunction)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_GeneratorFunction).toObject();
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateGeneratorFunction(JSContext* cx,
|
||||
Handle<GlobalObject*> global) {
|
||||
return getOrCreateObject(cx, global, GENERATOR_FUNCTION, initGenerators);
|
||||
if (!ensureConstructor(cx, global, JSProto_GeneratorFunction)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getConstructor(JSProto_GeneratorFunction).toObject();
|
||||
}
|
||||
|
||||
static NativeObject* getOrCreateAsyncFunctionPrototype(
|
||||
@ -778,9 +789,6 @@ class GlobalObject : public NativeObject {
|
||||
static bool initRegExpStringIteratorProto(JSContext* cx,
|
||||
Handle<GlobalObject*> global);
|
||||
|
||||
// Implemented in vm/GeneratorObject.cpp.
|
||||
static bool initGenerators(JSContext* cx, Handle<GlobalObject*> global);
|
||||
|
||||
static bool initAsyncGenerators(JSContext* cx, Handle<GlobalObject*> global);
|
||||
|
||||
// Implemented in builtin/MapObject.cpp.
|
||||
|
@ -842,7 +842,7 @@ static bool EnsureParserCreatedClasses(JSContext* cx, ParseTaskKind kind) {
|
||||
return false; // needed by regular expression literals
|
||||
}
|
||||
|
||||
if (!GlobalObject::initGenerators(cx, global)) {
|
||||
if (!EnsureConstructor(cx, global, JSProto_GeneratorFunction)) {
|
||||
return false; // needed by function*() {}
|
||||
}
|
||||
|
||||
|
@ -1961,6 +1961,7 @@ static bool CreateDynamicFunction(JSContext* cx, const CallArgs& args,
|
||||
parameterListEnd)) {
|
||||
return false;
|
||||
}
|
||||
protoKey = JSProto_GeneratorFunction;
|
||||
} else {
|
||||
if (!CompileStandaloneFunction(cx, &fun, options, srcBuf,
|
||||
parameterListEnd)) {
|
||||
|
Loading…
Reference in New Issue
Block a user