mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 975042 - Implement resolveOwnProperty and enumerateNames trap. r=peterv
This commit is contained in:
parent
b65a5d12b4
commit
ce9c4ef5c4
@ -295,10 +295,7 @@ public:
|
||||
|
||||
virtual bool resolveOwnProperty(JSContext *cx, Wrapper &jsWrapper, HandleObject wrapper,
|
||||
HandleObject holder, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc, unsigned flags)
|
||||
{
|
||||
MOZ_ASSUME_UNREACHABLE("Not yet implemented");
|
||||
}
|
||||
MutableHandle<JSPropertyDescriptor> desc, unsigned flags);
|
||||
|
||||
static bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
@ -310,10 +307,7 @@ public:
|
||||
}
|
||||
|
||||
virtual bool enumerateNames(JSContext *cx, HandleObject wrapper, unsigned flags,
|
||||
AutoIdVector &props)
|
||||
{
|
||||
MOZ_ASSUME_UNREACHABLE("Not yet implemented");
|
||||
}
|
||||
AutoIdVector &props);
|
||||
|
||||
static bool call(JSContext *cx, HandleObject wrapper,
|
||||
const JS::CallArgs &args, js::Wrapper& baseInstance)
|
||||
@ -389,6 +383,137 @@ const JSClass JSXrayTraits::HolderClass = {
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
|
||||
};
|
||||
|
||||
bool
|
||||
JSXrayTraits::resolveOwnProperty(JSContext *cx, Wrapper &jsWrapper,
|
||||
HandleObject wrapper, HandleObject holder,
|
||||
HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
unsigned flags)
|
||||
{
|
||||
// Call the common code.
|
||||
bool ok = XrayTraits::resolveOwnProperty(cx, jsWrapper, wrapper, holder,
|
||||
id, desc, flags);
|
||||
if (!ok || desc.object())
|
||||
return ok;
|
||||
|
||||
// Non-prototypes don't have anything on them yet.
|
||||
if (!isPrototype(holder))
|
||||
return true;
|
||||
|
||||
// The non-HasPrototypes semantics implemented by traditional Xrays are kind
|
||||
// of broken with respect to |own|-ness and the holder. The common code
|
||||
// muddles through by only checking the holder for non-|own| lookups, but
|
||||
// that doesn't work for us. So we do an explicit holder check here, and hope
|
||||
// that this mess gets fixed up soon.
|
||||
if (!JS_GetPropertyDescriptorById(cx, holder, id, 0, desc))
|
||||
return false;
|
||||
if (desc.object()) {
|
||||
desc.object().set(wrapper);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Grab the JSClass. We require all Xrayable classes to have a ClassSpec.
|
||||
RootedObject target(cx, getTargetObject(wrapper));
|
||||
const js::Class *clasp = js::GetObjectClass(target);
|
||||
JSProtoKey protoKey = JSCLASS_CACHED_PROTO_KEY(clasp);
|
||||
MOZ_ASSERT(protoKey == getProtoKey(holder));
|
||||
MOZ_ASSERT(clasp->spec.defined());
|
||||
|
||||
// Handle the 'constructor' property.
|
||||
if (id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_CONSTRUCTOR)) {
|
||||
RootedObject constructor(cx);
|
||||
{
|
||||
JSAutoCompartment ac(cx, target);
|
||||
if (!JS_GetClassObject(cx, protoKey, &constructor))
|
||||
return false;
|
||||
}
|
||||
if (!JS_WrapObject(cx, &constructor))
|
||||
return false;
|
||||
desc.object().set(wrapper);
|
||||
desc.setAttributes(0);
|
||||
desc.setGetter(nullptr);
|
||||
desc.setSetter(nullptr);
|
||||
desc.value().setObject(*constructor);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Find the properties available, if any.
|
||||
const JSFunctionSpec *fs = clasp->spec.prototypeFunctions;
|
||||
if (!fs)
|
||||
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))
|
||||
return true;
|
||||
Rooted<JSFlatString*> str(cx, JSID_TO_FLAT_STRING(id));
|
||||
|
||||
// Scan through the properties. If we don't find anything, we're done.
|
||||
for (; fs->name; ++fs) {
|
||||
// We don't support self-hosted functions yet. See bug 972987.
|
||||
if (fs->selfHostedName)
|
||||
continue;
|
||||
if (JS_FlatStringEqualsAscii(str, fs->name))
|
||||
break;
|
||||
}
|
||||
if (!fs->name)
|
||||
return true;
|
||||
|
||||
// Generate an Xrayed version of the method.
|
||||
Rooted<JSFunction*> fun(cx, JS_NewFunctionById(cx, fs->call.op, fs->nargs,
|
||||
0, wrapper, id));
|
||||
if (!fun)
|
||||
return false;
|
||||
|
||||
// The generic Xray machinery only defines non-own properties on the holder.
|
||||
// This is broken, and will be fixed at some point, but for now we need to
|
||||
// cache the value explicitly. See the corresponding call to
|
||||
// JS_GetPropertyById at the top of this function.
|
||||
return JS_DefinePropertyById(cx, holder, id,
|
||||
ObjectValue(*JS_GetFunctionObject(fun)),
|
||||
nullptr, nullptr, 0) &&
|
||||
JS_GetPropertyDescriptorById(cx, holder, id, 0, desc);
|
||||
}
|
||||
|
||||
bool
|
||||
JSXrayTraits::enumerateNames(JSContext *cx, HandleObject wrapper, unsigned flags,
|
||||
AutoIdVector &props)
|
||||
{
|
||||
RootedObject holder(cx, ensureHolder(cx, wrapper));
|
||||
if (!holder)
|
||||
return false;
|
||||
|
||||
// Non-prototypes don't have anything on them yet.
|
||||
if (!isPrototype(holder))
|
||||
return true;
|
||||
|
||||
// Grab the JSClass. We require all Xrayable classes to have a ClassSpec.
|
||||
RootedObject target(cx, getTargetObject(wrapper));
|
||||
const js::Class *clasp = js::GetObjectClass(target);
|
||||
MOZ_ASSERT(JSCLASS_CACHED_PROTO_KEY(clasp) == getProtoKey(holder));
|
||||
MOZ_ASSERT(clasp->spec.defined());
|
||||
|
||||
// Find the properties available, if any.
|
||||
const JSFunctionSpec *fs = clasp->spec.prototypeFunctions;
|
||||
if (!fs)
|
||||
return true;
|
||||
|
||||
// Intern all the strings, and pass theme to the caller.
|
||||
for (; fs->name; ++fs) {
|
||||
// We don't support self-hosted functions yet. See bug 972987.
|
||||
if (fs->selfHostedName)
|
||||
continue;
|
||||
RootedString str(cx, JS_InternString(cx, fs->name));
|
||||
if (!str)
|
||||
return false;
|
||||
if (!props.append(INTERNED_STRING_TO_JSID(cx, str)))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add the 'constructor' property.
|
||||
return props.append(GetRTIdByIndex(cx, XPCJSRuntime::IDX_CONSTRUCTOR));
|
||||
}
|
||||
|
||||
JSObject*
|
||||
JSXrayTraits::createHolder(JSContext *cx, JSObject *wrapper)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user