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:
André Bargull 2019-10-16 12:35:08 +00:00
parent 966f19f7e0
commit d80c1ed430
10 changed files with 51 additions and 39 deletions

View File

@ -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 |

View File

@ -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_) \

View File

@ -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;
}

View File

@ -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") \

View File

@ -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() {

View File

@ -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 <>

View File

@ -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) {

View File

@ -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.

View File

@ -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*() {}
}

View File

@ -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)) {