Bug 580544 - Don't bother trying to use the global object as a constructor. r=jorendorff
authorBlake Kaplan <mrbkap@gmail.com>
Wed, 21 Jul 2010 16:56:57 -0700
changeset 50471 cf9fc9bb9c3ef823cd09addad8e2c3f9262fef2d
parent 50470 233ad8dd6f484bc329ae8fdce293b336284fbf1e
child 50472 4d411039d112b2e05736fccc6dca3a8ac698aace
push idunknown
push userunknown
push dateunknown
reviewersjorendorff
bugs580544
milestone2.0b4pre
Bug 580544 - Don't bother trying to use the global object as a constructor. r=jorendorff
js/src/jsinterp.cpp
js/src/tests/ecma_3/Regress/jstests.list
js/src/tests/ecma_3/Regress/regress-580544.js
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1133,43 +1133,40 @@ InstanceOfSlow(JSContext *cx, JSObject *
 }
 
 JS_REQUIRES_STACK bool
 InvokeConstructor(JSContext *cx, const CallArgs &argsRef)
 {
     JS_ASSERT(!js_FunctionClass.construct);
     CallArgs args = argsRef;
 
-    if (args.callee().isPrimitive()) {
+    JSObject *obj2;
+    if (args.callee().isPrimitive() || !(obj2 = &args.callee().toObject())->getParent()) {
         /* Use js_ValueToFunction to report an error. */
         JS_ALWAYS_TRUE(!js_ValueToFunction(cx, &args.callee(), JSV2F_CONSTRUCT));
         return false;
     }
 
-    JSObject *obj2 = &args.callee().toObject();
-
     Value protov;
     if (!obj2->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom), &protov))
         return false;
 
     JSObject *proto = protov.isObjectOrNull() ? protov.toObjectOrNull() : NULL;
     JSObject *parent = obj2->getParent();
     Class *clasp = &js_ObjectClass;
 
     if (obj2->getClass() == &js_FunctionClass) {
         JSFunction *f = GET_FUNCTION_PRIVATE(cx, obj2);
         if (!f->isInterpreted() && f->u.n.clasp)
             clasp = f->u.n.clasp;
     }
 
     JSObject* obj = NewObject<WithProto::Class>(cx, clasp, proto, parent);
-    if (!obj) {
+    if (!obj)
         return JS_FALSE;
-    }
-
 
     /* Now we have an object with a constructor method; call it. */
     args.thisv().setObject(*obj);
     if (!Invoke(cx, args, JSINVOKE_CONSTRUCT))
         return JS_FALSE;
 
     /* Check the return value and if it's primitive, force it to be obj. */
     if (args.rval().isPrimitive()) {
--- a/js/src/tests/ecma_3/Regress/jstests.list
+++ b/js/src/tests/ecma_3/Regress/jstests.list
@@ -1,7 +1,8 @@
 url-prefix ../../jsreftest.html?test=ecma_3/Regress/
 script regress-385393-04.js
 script regress-419152.js
 script regress-420087.js
 script regress-420610.js
 script regress-441477-01.js
 script regress-469937.js
+script regress-580544.js
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_3/Regress/regress-580544.js
@@ -0,0 +1,30 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+var gTestfile = 'regress-580544.js';
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 580544;
+var summary = 'Do not assert: new (this.prototype = this)';
+var actual = 'No Crash';
+var expect = 'No Crash';
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+function test()
+{
+  enterFunc ('test');
+  printBugNumber(BUGNUMBER);
+  printStatus (summary);
+
+  try {
+    new (this.prototype = this);
+  } catch (e) {
+  }
+
+  reportCompare(expect, actual, summary);
+
+  exitFunc ('test');
+}