Bug 987669 - Add Xray support for FooError.prototype.name. r=gabor
authorBobby Holley <bobbyholley@gmail.com>
Fri, 11 Jul 2014 09:09:22 -0700
changeset 193613 e171c0317b8279076ce884ec756a204afb774290
parent 193612 4e45b8a55bfbdf96b6ca113efab4bbb926decf8e
child 193614 a2cbaa33712041d83416da86e33618f1a4e80b58
push id27123
push userryanvm@gmail.com
push dateFri, 11 Jul 2014 20:35:05 +0000
treeherdermozilla-central@84bd8d9f4256 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgabor
bugs987669
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 987669 - Add Xray support for FooError.prototype.name. r=gabor
js/xpconnect/wrappers/XrayWrapper.cpp
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -636,18 +636,18 @@ JSXrayTraits::resolveOwnProperty(JSConte
 {
     // Call the common code.
     bool ok = XrayTraits::resolveOwnProperty(cx, jsWrapper, wrapper, holder,
                                              id, desc);
     if (!ok || desc.object())
         return ok;
 
     RootedObject target(cx, getTargetObject(wrapper));
+    JSProtoKey key = getProtoKey(holder);
     if (!isPrototype(holder)) {
-        JSProtoKey key = getProtoKey(holder);
         // For Object and Array instances, we expose some properties from the
         // underlying object, but only after filtering them carefully.
         //
         // Note that, as far as JS observables go, Arrays are just Objects with
         // a different prototype and a magic (own, non-configurable) |.length| that
         // serves as a non-tight upper bound on |own| indexed properties. So while
         // it's tempting to try to impose some sort of structure on what Arrays
         // "should" look like over Xrays, the underlying object is squishy enough
@@ -756,16 +756,24 @@ JSXrayTraits::resolveOwnProperty(JSConte
         desc.object().set(wrapper);
         desc.setAttributes(0);
         desc.setGetter(nullptr);
         desc.setSetter(nullptr);
         desc.value().setObject(*constructor);
         return true;
     }
 
+    // Handle the 'name' property for error prototypes.
+    if (IsErrorObjectKey(key) && id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_NAME)) {
+        RootedId className(cx);
+        ProtoKeyToId(cx, key, &className);
+        FillPropertyDescriptor(desc, wrapper, 0, UndefinedValue());
+        return JS_IdToValue(cx, className, desc.value());
+    }
+
     // 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))
@@ -939,18 +947,18 @@ bool
 JSXrayTraits::enumerateNames(JSContext *cx, HandleObject wrapper, unsigned flags,
                              AutoIdVector &props)
 {
     RootedObject target(cx, getTargetObject(wrapper));
     RootedObject holder(cx, ensureHolder(cx, wrapper));
     if (!holder)
         return false;
 
+    JSProtoKey key = getProtoKey(holder);
     if (!isPrototype(holder)) {
-        JSProtoKey key = getProtoKey(holder);
         // For Object and Array instances, we expose some properties from the underlying
         // object, but only after filtering them carefully.
         if (key == JSProto_Object || key == JSProto_Array) {
             MOZ_ASSERT(props.empty());
             {
                 JSAutoCompartment ac(cx, target);
                 AutoIdVector targetProps(cx);
                 if (!js::GetPropertyNames(cx, target, flags | JSITER_OWNONLY, &targetProps))
@@ -1006,16 +1014,20 @@ JSXrayTraits::enumerateNames(JSContext *
     const js::Class *clasp = js::GetObjectClass(target);
     MOZ_ASSERT(clasp->spec.defined());
     JSProtoKey protoKey = getProtoKey(holder);
 
     // Add the 'constructor' property.
     if (!props.append(GetRTIdByIndex(cx, XPCJSRuntime::IDX_CONSTRUCTOR)))
         return false;
 
+    // For Error protoypes, add the 'name' property.
+    if (IsErrorObjectKey(key) && !props.append(GetRTIdByIndex(cx, XPCJSRuntime::IDX_NAME)))
+        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) {
         RootedString str(cx, JS_InternString(cx, fs->name));