mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1029933 - Introduce the concept of "dependent" standard classes and handle them in the ClassSpec infrastructure. r=Waldo
This commit is contained in:
parent
16f12b1347
commit
8095d9d618
@ -609,6 +609,23 @@ GetObjectJSClass(JSObject *obj)
|
||||
return js::Jsvalify(GetObjectClass(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(const Class *)
|
||||
ProtoKeyToClass(JSProtoKey key);
|
||||
|
||||
// Returns true if the standard class identified by |key| inherits from
|
||||
// another standard class with the same js::Class. This basically means
|
||||
// that the various properties described by our js::Class are intended
|
||||
// to live higher up on the proto chain.
|
||||
//
|
||||
// In practice, this only returns true for Error subtypes.
|
||||
inline bool
|
||||
StandardClassIsDependent(JSProtoKey key)
|
||||
{
|
||||
JSProtoKey keyFromClass = JSCLASS_CACHED_PROTO_KEY(ProtoKeyToClass(key));
|
||||
MOZ_ASSERT(keyFromClass);
|
||||
return key != keyFromClass;
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsInnerObject(JSObject *obj) {
|
||||
return !!GetObjectClass(obj)->ext.outerObject;
|
||||
|
@ -1249,9 +1249,6 @@ GetBuiltinConstructor(ExclusiveContext *cx, JSProtoKey key, MutableHandleObject
|
||||
bool
|
||||
GetBuiltinPrototype(ExclusiveContext *cx, JSProtoKey key, MutableHandleObject objp);
|
||||
|
||||
const Class *
|
||||
ProtoKeyToClass(JSProtoKey key);
|
||||
|
||||
JSObject *
|
||||
GetBuiltinPrototypePure(GlobalObject *global, JSProtoKey protoKey);
|
||||
|
||||
|
@ -63,7 +63,7 @@ static const ProtoTableEntry protoTable[JSProto_LIMIT] = {
|
||||
#undef INIT_FUNC
|
||||
};
|
||||
|
||||
const js::Class *
|
||||
JS_FRIEND_API(const js::Class *)
|
||||
js::ProtoKeyToClass(JSProtoKey key)
|
||||
{
|
||||
MOZ_ASSERT(key < JSProto_LIMIT);
|
||||
@ -166,18 +166,21 @@ GlobalObject::resolveConstructor(JSContext *cx, Handle<GlobalObject*> global, JS
|
||||
global->setConstructor(key, ObjectValue(*ctor));
|
||||
global->setConstructorPropertySlot(key, ObjectValue(*ctor));
|
||||
|
||||
// Define any specified functions and properties.
|
||||
if (const JSFunctionSpec *funs = clasp->spec.prototypeFunctions) {
|
||||
if (!JS_DefineFunctions(cx, proto, funs))
|
||||
return false;
|
||||
}
|
||||
if (const JSPropertySpec *props = clasp->spec.prototypeProperties) {
|
||||
if (!JS_DefineProperties(cx, proto, props))
|
||||
return false;
|
||||
}
|
||||
if (const JSFunctionSpec *funs = clasp->spec.constructorFunctions) {
|
||||
if (!JS_DefineFunctions(cx, ctor, funs))
|
||||
return false;
|
||||
// Define any specified functions and properties, unless we're a dependent
|
||||
// standard class (in which case they live on the prototype).
|
||||
if (!StandardClassIsDependent(key)) {
|
||||
if (const JSFunctionSpec *funs = clasp->spec.prototypeFunctions) {
|
||||
if (!JS_DefineFunctions(cx, proto, funs))
|
||||
return false;
|
||||
}
|
||||
if (const JSPropertySpec *props = clasp->spec.prototypeProperties) {
|
||||
if (!JS_DefineProperties(cx, proto, props))
|
||||
return false;
|
||||
}
|
||||
if (const JSFunctionSpec *funs = clasp->spec.constructorFunctions) {
|
||||
if (!JS_DefineFunctions(cx, ctor, funs))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If the prototype exists, link it with the constructor.
|
||||
|
@ -616,9 +616,8 @@ JSXrayTraits::resolveOwnProperty(JSContext *cx, const Wrapper &jsWrapper,
|
||||
|
||||
// Grab the JSClass. We require all Xrayable classes to have a ClassSpec.
|
||||
const js::Class *clasp = js::GetObjectClass(target);
|
||||
JSProtoKey protoKey = JSCLASS_CACHED_PROTO_KEY(clasp);
|
||||
MOZ_ASSERT(protoKey == getProtoKey(holder));
|
||||
MOZ_ASSERT(clasp->spec.defined());
|
||||
JSProtoKey protoKey = getProtoKey(holder);
|
||||
|
||||
// Handle the 'constructor' property.
|
||||
if (id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_CONSTRUCTOR)) {
|
||||
@ -638,6 +637,11 @@ JSXrayTraits::resolveOwnProperty(JSContext *cx, const Wrapper &jsWrapper,
|
||||
return true;
|
||||
}
|
||||
|
||||
// Bail out for dependent classes, since all the rest of the properties we'll
|
||||
// resolve here will live on the parent prototype.
|
||||
if (js::StandardClassIsDependent(protoKey))
|
||||
return true;
|
||||
|
||||
// Compute the property name we're looking for. We'll handle indexed
|
||||
// properties when we start supporting arrays.
|
||||
if (!JSID_IS_STRING(id))
|
||||
@ -867,8 +871,17 @@ JSXrayTraits::enumerateNames(JSContext *cx, HandleObject wrapper, unsigned flags
|
||||
|
||||
// Grab the JSClass. We require all Xrayable classes to have a ClassSpec.
|
||||
const js::Class *clasp = js::GetObjectClass(target);
|
||||
MOZ_ASSERT(JSCLASS_CACHED_PROTO_KEY(clasp) == getProtoKey(holder));
|
||||
MOZ_ASSERT(clasp->spec.defined());
|
||||
JSProtoKey protoKey = getProtoKey(holder);
|
||||
|
||||
// Add the 'constructor' property.
|
||||
if (!props.append(GetRTIdByIndex(cx, XPCJSRuntime::IDX_CONSTRUCTOR)))
|
||||
return false;
|
||||
|
||||
// Bail out for dependent classes, since all the rest of the properties we'll
|
||||
// resolve here will live on the parent prototype.
|
||||
if (js::StandardClassIsDependent(protoKey))
|
||||
return true;
|
||||
|
||||
// Intern all the strings, and pass theme to the caller.
|
||||
for (const JSFunctionSpec *fs = clasp->spec.prototypeFunctions; fs && fs->name; ++fs) {
|
||||
@ -893,8 +906,7 @@ JSXrayTraits::enumerateNames(JSContext *cx, HandleObject wrapper, unsigned flags
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add the 'constructor' property.
|
||||
return props.append(GetRTIdByIndex(cx, XPCJSRuntime::IDX_CONSTRUCTOR));
|
||||
return true;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
|
Loading…
Reference in New Issue
Block a user