Fix constructors that return objects in catch blocks (bug 604381, r=dmandelin).
authorDavid Anderson <danderson@mozilla.com>
Wed, 01 Dec 2010 17:02:15 -0800
changeset 58700 44573d17ec8c94562087436132ff532b9bc496f9
parent 58699 bdc3aa93dc265b9745b987934593b398a41df881
child 58701 0aad954c48ed8aab15c9e8f996ff3eb55ccdc637
push idunknown
push userunknown
push dateunknown
reviewersdmandelin
bugs604381
milestone2.0b8pre
Fix constructors that return objects in catch blocks (bug 604381, r=dmandelin).
js/src/jit-test/tests/jaeger/bug604381.js
js/src/methodjit/Compiler.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/jaeger/bug604381.js
@@ -0,0 +1,14 @@
+// vim: set ts=4 sw=4 tw=99 et:
+
+function F() {
+    var T = { };
+    try {
+        throw 12;
+    } catch (e) {
+        T.x = 5;
+        return T;
+    }
+}
+
+assertEq((new F()).x, 5);
+
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -2172,27 +2172,31 @@ mjit::Compiler::loadReturnValue(Assemble
 void
 mjit::Compiler::fixPrimitiveReturn(Assembler *masm, FrameEntry *fe)
 {
     JS_ASSERT(isConstructing);
 
     bool ool = (masm != &this->masm);
     Address thisv(JSFrameReg, JSStackFrame::offsetOfThis(fun));
 
-    // Easy cases - no return value, or known primitive, so just return thisv.
-    if (!fe || (fe->isTypeKnown() && fe->getKnownType() != JSVAL_TYPE_OBJECT)) {
+    // We can just load |thisv| if either of the following is true:
+    //  (1) There is no explicit return value, AND fp->rval is not used.
+    //  (2) There is an explicit return value, and it's known to be primitive.
+    if ((!fe && !analysis->usesReturnValue()) ||
+        (fe && fe->isTypeKnown() && fe->getKnownType() != JSVAL_TYPE_OBJECT))
+    {
         if (ool)
             masm->loadValueAsComponents(thisv, JSReturnReg_Type, JSReturnReg_Data);
         else
             frame.loadThisForReturn(JSReturnReg_Type, JSReturnReg_Data, Registers::ReturnReg);
         return;
     }
 
     // If the type is known to be an object, just load the return value as normal.
-    if (fe->isTypeKnown() && fe->getKnownType() == JSVAL_TYPE_OBJECT) {
+    if (fe && fe->isTypeKnown() && fe->getKnownType() == JSVAL_TYPE_OBJECT) {
         loadReturnValue(masm, fe);
         return;
     }
 
     // There's a return value, and its type is unknown. Test the type and load
     // |thisv| if necessary.
     loadReturnValue(masm, fe);
     Jump j = masm->testObject(Assembler::Equal, JSReturnReg_Type);