mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 962449 - Remove init functions from JSStdName, and pipe everything through ensureConstructor. r=luke
This commit is contained in:
parent
a59f4aa124
commit
0e18a87edd
123
js/src/jsapi.cpp
123
js/src/jsapi.cpp
@ -1142,25 +1142,21 @@ JS_InitStandardClasses(JSContext *cx, HandleObject obj)
|
||||
#define EAGER_ATOM(name) NAME_OFFSET(name)
|
||||
#define EAGER_CLASS_ATOM(name) NAME_OFFSET(name)
|
||||
|
||||
static JSObject *
|
||||
DummyInit(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
MOZ_ASSUME_UNREACHABLE();
|
||||
return nullptr;
|
||||
}
|
||||
static js::Class DummyClass;
|
||||
static js::Class SentinelClass;
|
||||
|
||||
typedef struct JSStdName {
|
||||
ClassInitializerOp init;
|
||||
size_t atomOffset; /* offset of atom pointer in JSAtomState */
|
||||
const Class *clasp;
|
||||
bool isDummy() const { return init == DummyInit; };
|
||||
bool isDummy() const { return clasp == &DummyClass; };
|
||||
bool isSentinel() const { return clasp == &SentinelClass; };
|
||||
} JSStdName;
|
||||
|
||||
static const JSStdName*
|
||||
LookupStdName(JSRuntime *rt, HandleString name, const JSStdName *table)
|
||||
{
|
||||
MOZ_ASSERT(name->isAtom());
|
||||
for (unsigned i = 0; table[i].init; i++) {
|
||||
for (unsigned i = 0; !table[i].isSentinel(); i++) {
|
||||
if (table[i].isDummy())
|
||||
continue;
|
||||
JSAtom *atom = AtomStateOffsetToName(rt->atomState, table[i].atomOffset);
|
||||
@ -1177,11 +1173,11 @@ LookupStdName(JSRuntime *rt, HandleString name, const JSStdName *table)
|
||||
* JSProtoKey does not correspond to a class with a meaningful constructor, we
|
||||
* insert a null entry into the table.
|
||||
*/
|
||||
#define STD_NAME_ENTRY(name, code, init, clasp) { init, EAGER_CLASS_ATOM(name), clasp },
|
||||
#define STD_DUMMY_ENTRY(name, code, init, dummy) { DummyInit, 0, nullptr },
|
||||
#define STD_NAME_ENTRY(name, code, init, clasp) { EAGER_CLASS_ATOM(name), clasp },
|
||||
#define STD_DUMMY_ENTRY(name, code, init, dummy) { 0, &DummyClass },
|
||||
static const JSStdName standard_class_names[] = {
|
||||
JS_FOR_PROTOTYPES(STD_NAME_ENTRY, STD_DUMMY_ENTRY)
|
||||
{ nullptr, 0, nullptr }
|
||||
{ 0, &SentinelClass }
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1189,58 +1185,58 @@ static const JSStdName standard_class_names[] = {
|
||||
* corresponding standard class that sets them up.
|
||||
*/
|
||||
static const JSStdName builtin_property_names[] = {
|
||||
{js_InitObjectClass, EAGER_ATOM(eval), &JSObject::class_},
|
||||
{ EAGER_ATOM(eval), &JSObject::class_ },
|
||||
|
||||
/* Global properties and functions defined by the Number class. */
|
||||
{js_InitNumberClass, EAGER_ATOM(NaN), OCLASP(Number)},
|
||||
{js_InitNumberClass, EAGER_ATOM(Infinity), OCLASP(Number)},
|
||||
{js_InitNumberClass, EAGER_ATOM(isNaN), OCLASP(Number)},
|
||||
{js_InitNumberClass, EAGER_ATOM(isFinite), OCLASP(Number)},
|
||||
{js_InitNumberClass, EAGER_ATOM(parseFloat), OCLASP(Number)},
|
||||
{js_InitNumberClass, EAGER_ATOM(parseInt), OCLASP(Number)},
|
||||
{ EAGER_ATOM(NaN), OCLASP(Number) },
|
||||
{ EAGER_ATOM(Infinity), OCLASP(Number) },
|
||||
{ EAGER_ATOM(isNaN), OCLASP(Number) },
|
||||
{ EAGER_ATOM(isFinite), OCLASP(Number) },
|
||||
{ EAGER_ATOM(parseFloat), OCLASP(Number) },
|
||||
{ EAGER_ATOM(parseInt), OCLASP(Number) },
|
||||
|
||||
/* String global functions. */
|
||||
{js_InitStringClass, EAGER_ATOM(escape), OCLASP(String)},
|
||||
{js_InitStringClass, EAGER_ATOM(unescape), OCLASP(String)},
|
||||
{js_InitStringClass, EAGER_ATOM(decodeURI), OCLASP(String)},
|
||||
{js_InitStringClass, EAGER_ATOM(encodeURI), OCLASP(String)},
|
||||
{js_InitStringClass, EAGER_ATOM(decodeURIComponent), OCLASP(String)},
|
||||
{js_InitStringClass, EAGER_ATOM(encodeURIComponent), OCLASP(String)},
|
||||
{ EAGER_ATOM(escape), OCLASP(String) },
|
||||
{ EAGER_ATOM(unescape), OCLASP(String) },
|
||||
{ EAGER_ATOM(decodeURI), OCLASP(String) },
|
||||
{ EAGER_ATOM(encodeURI), OCLASP(String) },
|
||||
{ EAGER_ATOM(decodeURIComponent), OCLASP(String) },
|
||||
{ EAGER_ATOM(encodeURIComponent), OCLASP(String) },
|
||||
#if JS_HAS_UNEVAL
|
||||
{js_InitStringClass, EAGER_ATOM(uneval), OCLASP(String)},
|
||||
{ EAGER_ATOM(uneval), OCLASP(String) },
|
||||
#endif
|
||||
#ifdef ENABLE_BINARYDATA
|
||||
{js_InitSIMDClass, EAGER_ATOM(SIMD), OCLASP(SIMD)},
|
||||
{js_InitTypedObjectModuleObject, EAGER_ATOM(TypedObject), OCLASP(TypedObjectModule)},
|
||||
{ EAGER_ATOM(SIMD), OCLASP(SIMD) },
|
||||
{ EAGER_ATOM(TypedObject), OCLASP(TypedObjectModule) },
|
||||
#endif
|
||||
|
||||
{nullptr, 0, nullptr}
|
||||
{ 0, &SentinelClass }
|
||||
};
|
||||
|
||||
static const JSStdName object_prototype_names[] = {
|
||||
/* Object.prototype properties (global delegates to Object.prototype). */
|
||||
{js_InitObjectClass, EAGER_ATOM(proto), &JSObject::class_},
|
||||
{ EAGER_ATOM(proto), &JSObject::class_ },
|
||||
#if JS_HAS_TOSOURCE
|
||||
{js_InitObjectClass, EAGER_ATOM(toSource), &JSObject::class_},
|
||||
{ EAGER_ATOM(toSource), &JSObject::class_ },
|
||||
#endif
|
||||
{js_InitObjectClass, EAGER_ATOM(toString), &JSObject::class_},
|
||||
{js_InitObjectClass, EAGER_ATOM(toLocaleString), &JSObject::class_},
|
||||
{js_InitObjectClass, EAGER_ATOM(valueOf), &JSObject::class_},
|
||||
{ EAGER_ATOM(toString), &JSObject::class_ },
|
||||
{ EAGER_ATOM(toLocaleString), &JSObject::class_ },
|
||||
{ EAGER_ATOM(valueOf), &JSObject::class_ },
|
||||
#if JS_HAS_OBJ_WATCHPOINT
|
||||
{js_InitObjectClass, EAGER_ATOM(watch), &JSObject::class_},
|
||||
{js_InitObjectClass, EAGER_ATOM(unwatch), &JSObject::class_},
|
||||
{ EAGER_ATOM(watch), &JSObject::class_ },
|
||||
{ EAGER_ATOM(unwatch), &JSObject::class_ },
|
||||
#endif
|
||||
{js_InitObjectClass, EAGER_ATOM(hasOwnProperty), &JSObject::class_},
|
||||
{js_InitObjectClass, EAGER_ATOM(isPrototypeOf), &JSObject::class_},
|
||||
{js_InitObjectClass, EAGER_ATOM(propertyIsEnumerable), &JSObject::class_},
|
||||
{ EAGER_ATOM(hasOwnProperty), &JSObject::class_ },
|
||||
{ EAGER_ATOM(isPrototypeOf), &JSObject::class_ },
|
||||
{ EAGER_ATOM(propertyIsEnumerable), &JSObject::class_ },
|
||||
#if JS_OLD_GETTER_SETTER_METHODS
|
||||
{js_InitObjectClass, EAGER_ATOM(defineGetter), &JSObject::class_},
|
||||
{js_InitObjectClass, EAGER_ATOM(defineSetter), &JSObject::class_},
|
||||
{js_InitObjectClass, EAGER_ATOM(lookupGetter), &JSObject::class_},
|
||||
{js_InitObjectClass, EAGER_ATOM(lookupSetter), &JSObject::class_},
|
||||
{ EAGER_ATOM(defineGetter), &JSObject::class_ },
|
||||
{ EAGER_ATOM(defineSetter), &JSObject::class_ },
|
||||
{ EAGER_ATOM(lookupGetter), &JSObject::class_ },
|
||||
{ EAGER_ATOM(lookupSetter), &JSObject::class_ },
|
||||
#endif
|
||||
|
||||
{nullptr, 0, nullptr}
|
||||
{ 0, &SentinelClass }
|
||||
};
|
||||
|
||||
#undef CLASP
|
||||
@ -1306,11 +1302,9 @@ JS_ResolveStandardClass(JSContext *cx, HandleObject obj, HandleId id, bool *reso
|
||||
if (stdnm->clasp->flags & JSCLASS_IS_ANONYMOUS)
|
||||
return true;
|
||||
|
||||
if (obj->as<GlobalObject>().isStandardClassResolved(stdnm->clasp))
|
||||
return true;
|
||||
|
||||
if (!stdnm->init(cx, obj))
|
||||
if (!obj->as<GlobalObject>().ensureConstructor(cx, JSCLASS_CACHED_PROTO_KEY(stdnm->clasp)))
|
||||
return false;
|
||||
|
||||
*resolved = true;
|
||||
}
|
||||
return true;
|
||||
@ -1323,37 +1317,8 @@ JS_EnumerateStandardClasses(JSContext *cx, HandleObject obj)
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj);
|
||||
MOZ_ASSERT(obj->is<GlobalObject>());
|
||||
|
||||
/*
|
||||
* Check whether we need to bind 'undefined' and define it if so.
|
||||
* Since ES5 15.1.1.3 undefined can't be deleted.
|
||||
*/
|
||||
HandlePropertyName undefinedName = cx->names().undefined;
|
||||
RootedValue undefinedValue(cx, UndefinedValue());
|
||||
if (!obj->nativeContains(cx, undefinedName) &&
|
||||
!JSObject::defineProperty(cx, obj, undefinedName, undefinedValue,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JSPROP_PERMANENT | JSPROP_READONLY)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize any classes that have not been initialized yet. Note that
|
||||
* resolving everything in standard_class_names has the effect of resolving
|
||||
* everything in builtin_property_names, so we don't need to iterate over
|
||||
* that separately. Moreover, we'll resolve the Object constructor as well,
|
||||
* so we can also skip object_prototype_names.
|
||||
*/
|
||||
for (unsigned i = 0; standard_class_names[i].init; i++) {
|
||||
const JSStdName &stdnm = standard_class_names[i];
|
||||
// Watch out for dummy entries.
|
||||
if (!stdnm.isDummy() && !obj->as<GlobalObject>().isStandardClassResolved(stdnm.clasp)) {
|
||||
if (!stdnm.init(cx, obj))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
|
||||
return GlobalObject::initStandardClasses(cx, global);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
|
Loading…
Reference in New Issue
Block a user