Bug 976148 - Support the .name and .length properties of Function instances. r=gabor
authorBobby Holley <bobbyholley@gmail.com>
Thu, 19 Jun 2014 09:57:06 -0700
changeset 189578 206d7f502e142587002b10f96f49e76f0cacf594
parent 189577 a471415834ae635da94c5e8a2344bf31c44118ed
child 189579 871d570bc7c9194bef14848cd84dbd7323043402
push id45099
push userbobbyholley@gmail.com
push dateThu, 19 Jun 2014 16:57:19 +0000
treeherdermozilla-inbound@871d570bc7c9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgabor
bugs976148
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 976148 - Support the .name and .length properties of Function instances. r=gabor
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/wrappers/XrayWrapper.cpp
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -75,18 +75,20 @@ const char* const XPCJSRuntime::mStrings
     "Function",             // IDX_FUNCTION
     "prototype",            // IDX_PROTOTYPE
     "createInstance",       // IDX_CREATE_INSTANCE
     "item",                 // IDX_ITEM
     "__proto__",            // IDX_PROTO
     "__iterator__",         // IDX_ITERATOR
     "__exposedProps__",     // IDX_EXPOSEDPROPS
     "eval",                 // IDX_EVAL
-    "controllers",           // IDX_CONTROLLERS
+    "controllers",          // IDX_CONTROLLERS
     "realFrameElement",     // IDX_REALFRAMEELEMENT
+    "length",               // IDX_LENGTH
+    "name",                 // IDX_NAME
 };
 
 /***************************************************************************/
 
 static mozilla::Atomic<bool> sDiscardSystemSource(false);
 
 bool
 xpc::ShouldDiscardSystemSource() { return sDiscardSystemSource; }
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -475,16 +475,18 @@ public:
         IDX_CREATE_INSTANCE         ,
         IDX_ITEM                    ,
         IDX_PROTO                   ,
         IDX_ITERATOR                ,
         IDX_EXPOSEDPROPS            ,
         IDX_EVAL                    ,
         IDX_CONTROLLERS             ,
         IDX_REALFRAMEELEMENT        ,
+        IDX_LENGTH                  ,
+        IDX_NAME                    ,
         IDX_TOTAL_COUNT // just a count of the above
     };
 
     JS::HandleId GetStringID(unsigned index) const
     {
         MOZ_ASSERT(index < IDX_TOTAL_COUNT, "index out of range");
         // fromMarkedLocation() is safe because the string is interned.
         return JS::HandleId::fromMarkedLocation(&mStrIDs[index]);
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -568,18 +568,25 @@ JSXrayTraits::resolveOwnProperty(JSConte
         } else if (IsTypedArrayKey(key)) {
             if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {
                 JS_ReportError(cx, "Accessing TypedArray data over Xrays is slow, and forbidden "
                                    "in order to encourage performant code. To copy TypedArrays "
                                    "across origin boundaries, consider using Components.utils.cloneInto().");
                 return false;
             }
         } else if (key == JSProto_Function) {
-            // Handle the 'prototype' property to make xrayedGlobal.StandardClass.prototype work.
-            if (id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_PROTOTYPE)) {
+            if (id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_LENGTH)) {
+                FillPropertyDescriptor(desc, wrapper, JSPROP_PERMANENT | JSPROP_READONLY,
+                                       NumberValue(JS_GetFunctionArity(JS_GetObjectFunction(target))));
+                return true;
+            } else if (id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_NAME)) {
+                FillPropertyDescriptor(desc, wrapper, JSPROP_PERMANENT | JSPROP_READONLY,
+                                       StringValue(JS_GetFunctionId(JS_GetObjectFunction(target))));
+            } else if (id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_PROTOTYPE)) {
+                // Handle the 'prototype' property to make xrayedGlobal.StandardClass.prototype work.
                 JSProtoKey standardConstructor = constructorFor(holder);
                 if (standardConstructor != JSProto_Null) {
                     RootedObject standardProto(cx);
                     {
                         JSAutoCompartment ac(cx, target);
                         if (!JS_GetClassPrototype(cx, standardConstructor, &standardProto))
                             return false;
                         MOZ_ASSERT(standardProto);
@@ -840,16 +847,20 @@ JSXrayTraits::enumerateNames(JSContext *
             uint32_t length = JS_GetTypedArrayLength(target);
             // TypedArrays enumerate every indexed property in range, but
             // |length| is a getter that lives on the proto, like it should be.
             if (!props.reserve(length))
                 return false;
             for (int32_t i = 0; i <= int32_t(length - 1); ++i)
                 props.infallibleAppend(INT_TO_JSID(i));
         } else if (key == JSProto_Function) {
+            if (!props.append(GetRTIdByIndex(cx, XPCJSRuntime::IDX_LENGTH)))
+                return false;
+            if (!props.append(GetRTIdByIndex(cx, XPCJSRuntime::IDX_NAME)))
+                return false;
             // Handle the .prototype property on standard constructors.
             if (constructorFor(holder) != JSProto_Null) {
                 if (!props.append(GetRTIdByIndex(cx, XPCJSRuntime::IDX_PROTOTYPE)))
                     return false;
             }
         }
 
         // The rest of this function applies only to prototypes.