Bug 1214048 - Improve callee-not-a-function error for spread calls. (r=jorendorff)
authorShu-yu Guo <shu@rfrn.org>
Mon, 26 Oct 2015 14:13:25 -0700
changeset 304801 a944e7136866c0a95a0ef18918d04840c4905bf5
parent 304800 f066d7c6b5566699ae3624b59b20ab51d9eda71e
child 304802 a6f01cc9c740cc536a8d4e73565e1ee0db55427b
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs1214048
milestone44.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 1214048 - Improve callee-not-a-function error for spread calls. (r=jorendorff)
js/src/vm/Interpreter.cpp
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -4515,16 +4515,41 @@ js::SpreadCallOperation(JSContext* cx, H
 
     if (length > ARGS_LENGTH_MAX) {
         JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
                              constructing ? JSMSG_TOO_MANY_CON_SPREADARGS
                                           : JSMSG_TOO_MANY_FUN_SPREADARGS);
         return false;
     }
 
+    // Do our own checks for the callee being a function, as Invoke uses the
+    // expression decompiler to decompile the callee stack operand based on
+    // the number of arguments. Spread operations have the callee at sp - 3
+    // when not constructing, and sp - 4 when constructing.
+    if (callee.isPrimitive()) {
+        return ReportIsNotFunction(cx, callee, 2 + constructing,
+                                   constructing ? CONSTRUCT : NO_CONSTRUCT);
+    }
+
+    const Class* clasp = callee.toObject().getClass();
+    if (MOZ_UNLIKELY(clasp != &JSFunction::class_)) {
+#if JS_HAS_NO_SUCH_METHOD
+        if (MOZ_UNLIKELY(clasp != &js_NoSuchMethodClass)) {
+#endif
+
+            if (!callee.toObject().callHook()) {
+                return ReportIsNotFunction(cx, callee, 2 + constructing,
+                                           constructing ? CONSTRUCT : NO_CONSTRUCT);
+            }
+
+#if JS_HAS_NO_SUCH_METHOD
+        }
+#endif
+    }
+
 #ifdef DEBUG
     // The object must be an array with dense elements and no holes. Baseline's
     // optimized spread call stubs rely on this.
     MOZ_ASSERT(aobj->getDenseInitializedLength() == length);
     MOZ_ASSERT(!aobj->isIndexed());
     for (uint32_t i = 0; i < length; i++)
         MOZ_ASSERT(!aobj->getDenseElement(i).isMagic());
 #endif