Bug 621376 - new Function.prototype on trace should not define Function.prototype.prototype. r=brendan
authorJeff Walden <jwalden@mit.edu>
Mon, 27 Dec 2010 16:24:27 -0600
changeset 59967 6b68235ee417b4e078e691ad6bac1909dca9e5bd
parent 59966 25908114259b1688488f495f0f135cd5c2ef4906
child 59968 0d9a5752b1cf36be73c2bc2cab784fbdcb04eb20
push id17820
push usercleary@mozilla.com
push dateTue, 04 Jan 2011 21:40:57 +0000
treeherdermozilla-central@969691cfe40e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbrendan
bugs621376
milestone2.0b9pre
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 621376 - new Function.prototype on trace should not define Function.prototype.prototype. r=brendan
js/src/jit-test/tests/basic/new-Function-prototype.js
js/src/jit-test/tests/basic/new-bound-function.js
js/src/jsobj.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/new-Function-prototype.js
@@ -0,0 +1,22 @@
+var funProto = Function.prototype;
+assertEq(Object.getOwnPropertyDescriptor(funProto, "prototype"), undefined);
+
+assertEq(parseInt.prototype, undefined);
+
+var oldObj;
+for (var i = 0, sz = RUNLOOP; i < sz; oldObj = obj, i++)
+{
+  var obj = new funProto;
+  assertEq(obj === oldObj, false);
+  assertEq(Object.prototype.toString.call(obj), "[object Object]");
+  assertEq(Object.getOwnPropertyDescriptor(funProto, "prototype"), undefined);
+  assertEq(Object.getOwnPropertyDescriptor(parseInt, "prototype"), undefined);
+  assertEq(parseInt.prototype, undefined);
+}
+
+checkStats({
+  recorderStarted: 1,
+  recorderAborted: 0,
+  traceTriggered: 1,
+  traceCompleted: 1,
+});
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/new-bound-function.js
@@ -0,0 +1,26 @@
+var funProto = Function.prototype;
+assertEq(Object.getOwnPropertyDescriptor(funProto, "prototype"), undefined);
+
+function Point(x, y) { this.x = x; this.y = y; }
+
+var YAxisPoint = Point.bind(null, 0);
+
+assertEq(YAxisPoint.prototype, undefined);
+
+var oldPoint;
+for (var i = 0, sz = RUNLOOP; i < sz; oldPoint = point, i++)
+{
+  var point = new YAxisPoint(5);
+  assertEq(point === oldPoint, false);
+  assertEq(point.x, 0);
+  assertEq(point.y, 5);
+  assertEq(Object.getOwnPropertyDescriptor(funProto, "prototype"), undefined);
+  assertEq(Object.getOwnPropertyDescriptor(YAxisPoint, "prototype"), undefined);
+}
+
+checkStats({
+  recorderStarted: 1,
+  recorderAborted: 1,
+  traceTriggered: 0,
+  traceCompleted: 0,
+});
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -2945,18 +2945,21 @@ js_CreateThisFromTrace(JSContext *cx, Cl
         if (pval.isMagic(JS_GENERIC_MAGIC)) {
             /*
              * No ctor.prototype was set, so we inline-expand and optimize
              * fun_resolve's prototype creation code.
              */
             proto = NewNativeClassInstance(cx, clasp, proto, parent);
             if (!proto)
                 return NULL;
-            if (!js_SetClassPrototype(cx, ctor, proto, JSPROP_ENUMERATE | JSPROP_PERMANENT))
-                return NULL;
+            JSFunction *fun = ctor->getFunctionPrivate();
+            if (!fun->isNative() && !fun->isFunctionPrototype()) {
+                if (!js_SetClassPrototype(cx, ctor, proto, JSPROP_ENUMERATE | JSPROP_PERMANENT))
+                    return NULL;
+            }
         } else {
             /*
              * A primitive value in .prototype means to use Object.prototype
              * for proto. See ES5 13.2.2 step 7.
              */
         }
     }