Bug 916949 - Change __noSuchMethod__ so that it only gets invoked on undefined bindings. r=jorendorff
authorKannan Vijayan <kvijayan@mozilla.com>
Mon, 21 Oct 2013 17:59:11 -0400
changeset 166383 ad6254a681f1a662a709ac377246db96a5e9de87
parent 166382 5ee5595998460658ca101492eef576e3ca6eedb2
child 166384 b299be671230fba31eda317ff2c5e7c6c8d712c1
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs916949
milestone27.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 916949 - Change __noSuchMethod__ so that it only gets invoked on undefined bindings. r=jorendorff
js/src/jit/BaselineIC.cpp
js/src/jit/IonCaches.cpp
js/src/tests/js1_5/extensions/regress-564577.js
js/src/vm/Interpreter-inl.h
js/src/vm/Interpreter.cpp
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -6010,17 +6010,17 @@ DoGetPropFallback(JSContext *cx, Baselin
     if (!obj)
         return false;
 
     if (!JSObject::getGeneric(cx, obj, obj, id, res))
         return false;
 
 #if JS_HAS_NO_SUCH_METHOD
     // Handle objects with __noSuchMethod__.
-    if (op == JSOP_CALLPROP && JS_UNLIKELY(res.isPrimitive()) && val.isObject()) {
+    if (op == JSOP_CALLPROP && JS_UNLIKELY(res.isUndefined()) && val.isObject()) {
         if (!OnUnknownMethod(cx, obj, IdToValue(id), res))
             return false;
     }
 #endif
 
     types::TypeScript::Monitor(cx, script, pc, res);
 
     // Add a type monitor stub for the resulting value.
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -1776,17 +1776,17 @@ GetPropertyIC::update(JSContext *cx, siz
         jsbytecode *pc;
         cache.getScriptedLocation(&script, &pc);
 
         // If the cache is idempotent, the property exists so we don't have to
         // call __noSuchMethod__.
 
 #if JS_HAS_NO_SUCH_METHOD
         // Handle objects with __noSuchMethod__.
-        if (JSOp(*pc) == JSOP_CALLPROP && JS_UNLIKELY(vp.isPrimitive())) {
+        if (JSOp(*pc) == JSOP_CALLPROP && JS_UNLIKELY(vp.isUndefined())) {
             if (!OnUnknownMethod(cx, obj, IdToValue(id), vp))
                 return false;
         }
 #endif
 
         // Monitor changes to cache entry.
         types::TypeScript::Monitor(cx, script, pc, vp);
     }
--- a/js/src/tests/js1_5/extensions/regress-564577.js
+++ b/js/src/tests/js1_5/extensions/regress-564577.js
@@ -38,28 +38,40 @@ function test()
   };
 
   status = summary + ' ' + inSection(1) + ' ';
   actual = o.aaa();
   expect = 'aaa() undefined';
   reportCompare(expect, actual, status);
 
   status = summary + ' ' + inSection(2) + ' ';
-  actual = o.bbb();
-  expect = 'bbb() null';
+  try {
+    actual = o.bbb();
+  } catch(e) {
+    actual = e + '';
+  }
+  expect = 'TypeError: o.bbb is not a function';
   reportCompare(expect, actual, status);
 
   status = summary + ' ' + inSection(3) + ' ';
-  actual = o.ccc();
-  expect = 'ccc() 77';
+  try {
+    actual = o.ccc();
+  } catch(e) {
+    actual = e + '';
+  }
+  expect = 'TypeError: o.ccc is not a function';
   reportCompare(expect, actual, status);
 
   status = summary + ' ' + inSection(4) + ' ';
-  actual = o.ddd();
-  expect = 'ddd() foo';
+  try {
+    actual = o.ddd();
+  } catch(e) {
+    actual = e + '';
+  }
+  expect = 'TypeError: o.ddd is not a function';
   reportCompare(expect, actual, status);
 
   status = summary + ' ' + inSection(5) + ' ';
   try {
     actual = o.eee();
   } catch(e) {
     actual = e + '';
   }
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -386,17 +386,17 @@ GetObjectElementOperation(JSContext *cx,
             if (!JSObject::getProperty(cx, obj, obj, name->asPropertyName(), res))
                 return false;
         }
 
         objArg = obj;
     } while (0);
 
 #if JS_HAS_NO_SUCH_METHOD
-    if (op == JSOP_CALLELEM && JS_UNLIKELY(res.isPrimitive()) && wasObject) {
+    if (op == JSOP_CALLELEM && JS_UNLIKELY(res.isUndefined()) && wasObject) {
         RootedObject obj(cx, objArg);
         if (!OnUnknownMethod(cx, obj, rref, res))
             return false;
     }
 #endif
 
     assertSameCompartmentDebugOnly(cx, res);
     return true;
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -261,17 +261,17 @@ GetPropertyOperation(JSContext *cx, Stac
 
     bool wasObject = lval.isObject();
 
     if (!JSObject::getGeneric(cx, obj, obj, id, vp))
         return false;
 
 #if JS_HAS_NO_SUCH_METHOD
     if (op == JSOP_CALLPROP &&
-        JS_UNLIKELY(vp.isPrimitive()) &&
+        JS_UNLIKELY(vp.isUndefined()) &&
         wasObject)
     {
         if (!OnUnknownMethod(cx, obj, IdToValue(id), vp))
             return false;
     }
 #endif
 
     return true;
@@ -3448,17 +3448,17 @@ js::GetProperty(JSContext *cx, HandleVal
 
 bool
 js::CallProperty(JSContext *cx, HandleValue v, HandlePropertyName name, MutableHandleValue vp)
 {
     if (!GetProperty(cx, v, name, vp))
         return false;
 
 #if JS_HAS_NO_SUCH_METHOD
-    if (JS_UNLIKELY(vp.isPrimitive()) && v.isObject())
+    if (JS_UNLIKELY(vp.isUndefined()) && v.isObject())
     {
         RootedObject obj(cx, &v.toObject());
         if (!OnUnknownMethod(cx, obj, StringValue(name), vp))
             return false;
     }
 #endif
 
     return true;