diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 2c0f37427c2d..a2c17a076554 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -3690,6 +3690,13 @@ JS_GetFunctionArity(JSFunction* fun) return fun->nargs(); } +JS_PUBLIC_API(bool) +JS_GetFunctionLength(JSContext* cx, HandleFunction fun, uint16_t* length) +{ + assertSameCompartment(cx, fun); + return JSFunction::getLength(cx, fun, length); +} + JS_PUBLIC_API(bool) JS_ObjectIsFunction(JSContext* cx, JSObject* obj) { diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 5133fd13a79b..a30d31c0f9db 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -3137,11 +3137,18 @@ extern JS_PUBLIC_API(JSString*) JS_GetFunctionDisplayId(JSFunction* fun); /* - * Return the arity (length) of fun. + * Return the arity of fun, which includes default parameters and rest + * parameter. This can be used as `nargs` parameter for other functions. */ extern JS_PUBLIC_API(uint16_t) JS_GetFunctionArity(JSFunction* fun); +/* + * Return the length of fun, which is the original value of .length property. + */ +JS_PUBLIC_API(bool) +JS_GetFunctionLength(JSContext* cx, JS::HandleFunction fun, uint16_t* length); + /** * Infallible predicate to test whether obj is a function object (faster than * comparing obj's class name to "Function", but equivalent unless someone has diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp index e08dc9cba267..e0626eff22d7 100644 --- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -536,8 +536,15 @@ JSXrayTraits::resolveOwnProperty(JSContext* cx, HandleObject wrapper, } } else if (key == JSProto_Function) { if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_LENGTH)) { + uint16_t length; + RootedFunction fun(cx, JS_GetObjectFunction(target)); + { + JSAutoRealm ar(cx, target); + if (!JS_GetFunctionLength(cx, fun, &length)) + return false; + } FillPropertyDescriptor(desc, wrapper, JSPROP_PERMANENT | JSPROP_READONLY, - NumberValue(JS_GetFunctionArity(JS_GetObjectFunction(target)))); + NumberValue(length)); return true; } if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_NAME)) {