[INFER] Don't try to infer 'new' objects for non-compileAndGo scripts, bug 641231.
authorBrian Hackett <bhackett1024@gmail.com>
Sun, 13 Mar 2011 22:35:51 -0700
changeset 74769 1ce8efbb75cc6122286f9d4e33aba3592fb6a5fb
parent 74768 f70363576e62beffec41a3296f305e970717c441
child 74770 e1a60884a125591363d32a4cc80fb78fdae45033
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
bugs641231
milestone2.0b13pre
[INFER] Don't try to infer 'new' objects for non-compileAndGo scripts, bug 641231.
js/src/jit-test/tests/basic/bug641231.js
js/src/jsfun.cpp
js/src/jsinfer.cpp
js/src/methodjit/InvokeHelpers.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug641231.js
@@ -0,0 +1,1 @@
+try { Function("function a(){this(*)}new a")() } catch (e) {}
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -2853,19 +2853,18 @@ JSObject * JS_FASTCALL
 js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent,
                        JSObject *proto)
 {
     JS_ASSERT(parent);
     JS_ASSERT(proto);
 
     /*
      * In COMPILE_N_GO code the existing prototype will be correct, so we can
-     * reuse the type. In non-COMPILE_N_GO code the proto is NULL, but since
-     * we don't run type inference on such code we can use the default new
-     * Function type.
+     * reuse the type. In non-COMPILE_N_GO code the existing prototype is NULL;
+     * Just use the default 'new' object for Function.prototype.
      */
     TypeObject *type = (fun->getProto() == proto) ? fun->getType() : proto->getNewType(cx);
     if (!type)
         return NULL;
 
     JSObject *clone;
     if (cx->compartment == fun->compartment()) {
         /*
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -3644,17 +3644,19 @@ AnalyzeScriptNew(JSContext *cx, JSScript
 {
     JS_ASSERT(script->calledWithNew && script->fun);
 
     /*
      * Compute the 'this' type when called with 'new'. We do not distinguish regular
      * from 'new' calls to the function.
      */
 
-    if (script->fun->getType()->unknownProperties || script->fun->isFunctionPrototype()) {
+    if (script->fun->getType()->unknownProperties ||
+        script->fun->isFunctionPrototype() ||
+        !script->compileAndGo) {
         script->thisTypes()->addType(cx, TYPE_UNKNOWN);
         return;
     }
 
     TypeFunction *funType = script->fun->getType()->asFunction();
     TypeSet *prototypeTypes = funType->getProperty(cx, id_prototype(cx), false);
     if (!prototypeTypes)
         return;
--- a/js/src/methodjit/InvokeHelpers.cpp
+++ b/js/src/methodjit/InvokeHelpers.cpp
@@ -353,18 +353,23 @@ UncachedInlineCall(VMFrame &f, uint32 fl
 
     if (argTypes && argc == newfun->nargs) {
         /*
          * Use the space of all possible types being passed at this callsite if there
          * is a match between argc and nargs, so that the fastEntry can be subsequently
          * used without further type checking. If there is an argument count mismatch,
          * the callee's args will end up getting marked as unknown.
          */
-        if (!(flags & JSFRAME_CONSTRUCTING) && !newscript->typeSetThis(cx, argTypes[0]))
-            return false;
+        if (flags & JSFRAME_CONSTRUCTING) {
+            if (!newscript->typeSetNewCalled(cx))
+                return false;
+        } else {
+            if (!newscript->typeSetThis(cx, argTypes[0]))
+                return false;
+        }
         for (unsigned i = 0; i < argc; i++) {
             if (!newscript->typeSetArgument(cx, i, argTypes[1 + i]))
                 return false;
         }
     } else {
         CallArgs args(vp + 2, argc);
         if (!cx->typeMonitorCall(args, flags & JSFRAME_CONSTRUCTING))
             return false;