Bug 1320408 - Part 1: Change JSFunction::getLength and JSFunction::getUnresolvedLength to static method. r=jandem
authorTooru Fujisawa <arai_a@mac.com>
Mon, 28 Nov 2016 12:29:16 +0900
changeset 324416 20c75f210e9a2abb0d6a932adb69b88a27579846
parent 324415 dad211727cb3a1f110fe977d8f0b35f6416aea68
child 324417 6b4e659892cee5ac0d89931f79bdf367807bf3c2
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersjandem
bugs1320408
milestone53.0a1
Bug 1320408 - Part 1: Change JSFunction::getLength and JSFunction::getUnresolvedLength to static method. r=jandem
js/src/jsfun.cpp
js/src/jsfun.h
js/src/vm/AsyncFunction.cpp
js/src/vm/SelfHosting.cpp
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -492,17 +492,17 @@ fun_resolve(JSContext* cx, HandleObject 
         //     assertEq(f.length, 0);  // gets Function.prototype.length!
         //     assertEq(f.name, "");  // gets Function.prototype.name!
         // We use the RESOLVED_LENGTH and RESOLVED_NAME flags as a hack to prevent this
         // bug.
         if (isLength) {
             if (fun->hasResolvedLength())
                 return true;
 
-            if (!fun->getUnresolvedLength(cx, &v))
+            if (!JSFunction::getUnresolvedLength(cx, fun, &v))
                 return false;
         } else {
             if (fun->hasResolvedName())
                 return true;
 
             // Don't define an own .name property for unnamed functions.
             JSAtom* name = fun->getUnresolvedName(cx);
             if (name == nullptr)
@@ -1264,45 +1264,44 @@ JSFunction::isDerivedClassConstructor()
         }
     } else {
         derived = nonLazyScript()->isDerivedClassConstructor();
     }
     MOZ_ASSERT_IF(derived, isClassConstructor());
     return derived;
 }
 
-bool
-JSFunction::getLength(JSContext* cx, uint16_t* length)
+/* static */ bool
+JSFunction::getLength(JSContext* cx, HandleFunction fun, uint16_t* length)
 {
-    JS::RootedFunction self(cx, this);
-    MOZ_ASSERT(!self->isBoundFunction());
-    if (self->isInterpretedLazy() && !self->getOrCreateScript(cx))
+    MOZ_ASSERT(!fun->isBoundFunction());
+    if (fun->isInterpretedLazy() && !fun->getOrCreateScript(cx))
         return false;
 
-    *length = self->hasScript() ? self->nonLazyScript()->funLength()
-                                : (self->nargs() - self->hasRest());
+    *length = fun->hasScript() ? fun->nonLazyScript()->funLength()
+                               : (fun->nargs() - fun->hasRest());
     return true;
 }
 
-bool
-JSFunction::getUnresolvedLength(JSContext* cx, MutableHandleValue v)
+/* static */ bool
+JSFunction::getUnresolvedLength(JSContext* cx, HandleFunction fun, MutableHandleValue v)
 {
-    MOZ_ASSERT(!IsInternalFunctionObject(*this));
-    MOZ_ASSERT(!hasResolvedLength());
+    MOZ_ASSERT(!IsInternalFunctionObject(*fun));
+    MOZ_ASSERT(!fun->hasResolvedLength());
 
     // Bound functions' length can have values up to MAX_SAFE_INTEGER, so
     // they're handled differently from other functions.
-    if (isBoundFunction()) {
-        MOZ_ASSERT(getExtendedSlot(BOUND_FUN_LENGTH_SLOT).isNumber());
-        v.set(getExtendedSlot(BOUND_FUN_LENGTH_SLOT));
+    if (fun->isBoundFunction()) {
+        MOZ_ASSERT(fun->getExtendedSlot(BOUND_FUN_LENGTH_SLOT).isNumber());
+        v.set(fun->getExtendedSlot(BOUND_FUN_LENGTH_SLOT));
         return true;
     }
 
     uint16_t length;
-    if (!getLength(cx, &length))
+    if (!JSFunction::getLength(cx, fun, &length))
         return false;
 
     v.setInt32(length);
     return true;
 }
 
 JSAtom*
 JSFunction::getUnresolvedName(JSContext* cx)
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -306,17 +306,18 @@ class JSFunction : public js::NativeObje
 
     void setAsyncKind(js::FunctionAsyncKind asyncKind) {
         if (isInterpretedLazy())
             lazyScript()->setAsyncKind(asyncKind);
         else
             nonLazyScript()->setAsyncKind(asyncKind);
     }
 
-    bool getUnresolvedLength(JSContext* cx, js::MutableHandleValue v);
+    static bool getUnresolvedLength(JSContext* cx, js::HandleFunction fun,
+                                    js::MutableHandleValue v);
 
     JSAtom* getUnresolvedName(JSContext* cx);
 
     JSAtom* name() const { return hasGuessedAtom() ? nullptr : atom_.get(); }
 
     // Because display names (see Debugger.Object.displayName) are already stored
     // on functions and will always contain a valid es6 function name, as described
     // in "ECMA-262 (2016-02-27) 9.2.11 SetFunctionName," we have opted to save
@@ -452,17 +453,17 @@ class JSFunction : public js::NativeObje
         return !u.i.s.script_;
     }
 
     JSScript* nonLazyScript() const {
         MOZ_ASSERT(!hasUncompiledScript());
         return u.i.s.script_;
     }
 
-    bool getLength(JSContext* cx, uint16_t* length);
+    static bool getLength(JSContext* cx, js::HandleFunction fun, uint16_t* length);
 
     js::LazyScript* lazyScript() const {
         MOZ_ASSERT(isInterpretedLazy() && u.i.s.lazy_);
         return u.i.s.lazy_;
     }
 
     js::LazyScript* lazyScriptOrNull() const {
         MOZ_ASSERT(isInterpretedLazy());
--- a/js/src/vm/AsyncFunction.cpp
+++ b/js/src/vm/AsyncFunction.cpp
@@ -116,17 +116,17 @@ js::WrapAsyncFunctionWithProto(JSContext
     MOZ_ASSERT(proto, "We need an explicit prototype to avoid the default"
                       "%FunctionPrototype% fallback in NewFunctionWithProto().");
 
     // Create a new function with AsyncFunctionPrototype, reusing the name and
     // the length of `unwrapped`.
 
     RootedAtom funName(cx, unwrapped->name());
     uint16_t length;
-    if (!unwrapped->getLength(cx, &length))
+    if (!JSFunction::getLength(cx, unwrapped, &length))
         return nullptr;
 
     // Steps 3 (partially).
     RootedFunction wrapped(cx, NewFunctionWithProto(cx, WrappedAsyncFunction, length,
                                                     JSFunction::NATIVE_FUN, nullptr,
                                                     funName, proto,
                                                     AllocKind::FUNCTION_EXTENDED,
                                                     TenuredObject));
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -456,17 +456,17 @@ intrinsic_FinishBoundFunctionInit(JSCont
     }
 
     double argCount = args[2].toNumber();
     double length = 0.0;
 
     // Try to avoid invoking the resolve hook.
     if (targetObj->is<JSFunction>() && !targetObj->as<JSFunction>().hasResolvedLength()) {
         RootedValue targetLength(cx);
-        if (!targetObj->as<JSFunction>().getUnresolvedLength(cx, &targetLength))
+        if (!JSFunction::getUnresolvedLength(cx, targetObj.as<JSFunction>(), &targetLength))
             return false;
 
         length = Max(0.0, targetLength.toNumber() - argCount);
     } else {
         // 19.2.3.2 Function.prototype.bind, step 5.
         bool hasLength;
         RootedId idRoot(cx, NameToId(cx->names().length));
         if (!HasOwnProperty(cx, targetObj, idRoot, &hasLength))