Blob Blame History Raw
#
#  Manual backport of bug 1466000 part 1, needed for following optchain backporting
#

diff -Nrup mozilla-OLD/js/src/frontend/BytecodeEmitter.cpp mozilla/js/src/frontend/BytecodeEmitter.cpp
--- mozilla-OLD/js/src/frontend/BytecodeEmitter.cpp	2022-01-10 07:17:48.764326660 +0300
+++ mozilla/js/src/frontend/BytecodeEmitter.cpp	2022-01-10 07:18:25.683065770 +0300
@@ -9491,20 +9491,21 @@ BytecodeEmitter::isRestParameter(ParseNo
 }
 
 bool
-BytecodeEmitter::emitCallee(ParseNode* callee, ParseNode* call, bool spread, bool* callop)
+BytecodeEmitter::emitCalleeAndThis(ParseNode* callee, ParseNode* call, bool isCall, bool isNew)
 {
+    bool needsThis = !isCall;
     switch (callee->getKind()) {
       case ParseNodeKind::Name:
-        if (!emitGetName(callee, *callop))
+        if (!emitGetName(callee, isCall))
             return false;
         break;
       case ParseNodeKind::Dot:
         MOZ_ASSERT(emitterMode != BytecodeEmitter::SelfHosting);
         if (callee->as<PropertyAccess>().isSuper()) {
-            if (!emitSuperPropOp(callee, JSOP_GETPROP_SUPER, /* isCall = */ *callop))
+            if (!emitSuperPropOp(callee, JSOP_GETPROP_SUPER, isCall))
                 return false;
         } else {
-            if (!emitPropOp(callee, *callop ? JSOP_CALLPROP : JSOP_GETPROP))
+            if (!emitPropOp(callee, isCall ? JSOP_CALLPROP : JSOP_GETPROP))
                 return false;
         }
 
@@ -9512,12 +9513,12 @@ BytecodeEmitter::emitCallee(ParseNode* c
       case ParseNodeKind::Elem:
         MOZ_ASSERT(emitterMode != BytecodeEmitter::SelfHosting);
         if (callee->as<PropertyByValue>().isSuper()) {
-            if (!emitSuperElemOp(callee, JSOP_GETELEM_SUPER, /* isCall = */ *callop))
+            if (!emitSuperElemOp(callee, JSOP_GETELEM_SUPER, isCall))
                 return false;
         } else {
-            if (!emitElemOp(callee, *callop ? JSOP_CALLELEM : JSOP_GETELEM))
+            if (!emitElemOp(callee, isCall ? JSOP_CALLELEM : JSOP_GETELEM))
                 return false;
-            if (*callop) {
+            if (isCall) {
                 if (!emit1(JSOP_SWAP))
                     return false;
             }
@@ -9545,7 +9546,7 @@ BytecodeEmitter::emitCallee(ParseNode* c
             if (!emitTree(callee))
                 return false;
         }
-        *callop = false;
+        needsThis = true;
         break;
       case ParseNodeKind::SuperBase:
         MOZ_ASSERT(call->isKind(ParseNodeKind::SuperCall));
@@ -9556,10 +9557,22 @@ BytecodeEmitter::emitCallee(ParseNode* c
       default:
         if (!emitTree(callee))
             return false;
-        *callop = false;             /* trigger JSOP_UNDEFINED after */
+        needsThis = true;
         break;
     }
 
+    if (needsThis) {
+        if (isNew) {
+            if (!emit1(JSOP_IS_CONSTRUCTING)) {
+                return false;
+            }
+        } else {
+            if (!emit1(JSOP_UNDEFINED)) {
+                return false;
+            }
+        }
+    }
+
     return true;
 }
 
@@ -9575,14 +9588,8 @@ BytecodeEmitter::emitPipeline(ParseNode*
     ParseNode* callee = pn->pn_head->pn_next;
 
     do {
-        bool callop = true;
-        if (!emitCallee(callee, pn, false, &callop))
+        if (!emitCalleeAndThis(callee, pn, true, false)) {
             return false;
-
-        // Emit room for |this|
-        if (!callop) {
-            if (!emit1(JSOP_UNDEFINED))
-                return false;
         }
 
         if (!emit2(JSOP_PICK, 2))
@@ -9707,21 +9714,11 @@ BytecodeEmitter::emitCallOrNew(ParseNode
         // Fall through
     }
 
-    if (!emitCallee(pn_callee, pn, false, &callop))
-        return false;
-
     bool isNewOp = pn->getOp() == JSOP_NEW || pn->getOp() == JSOP_SPREADNEW ||
                    pn->getOp() == JSOP_SUPERCALL || pn->getOp() == JSOP_SPREADSUPERCALL;
 
-    // Emit room for |this|.
-    if (!callop) {
-        if (isNewOp) {
-            if (!emit1(JSOP_IS_CONSTRUCTING))
-                return false;
-        } else {
-            if (!emit1(JSOP_UNDEFINED))
-                return false;
-        }
+    if (!emitCalleeAndThis(pn_callee, pn, callop, isNewOp)) {
+        return false;
     }
 
     if (!emitArguments(pn_args, callop, spread))
diff -Nrup mozilla-OLD/js/src/frontend/BytecodeEmitter.h mozilla/js/src/frontend/BytecodeEmitter.h
--- mozilla-OLD/js/src/frontend/BytecodeEmitter.h	2022-01-10 07:17:48.765326652 +0300
+++ mozilla/js/src/frontend/BytecodeEmitter.h	2022-01-10 07:18:25.684065763 +0300
@@ -868,7 +868,8 @@ struct MOZ_STACK_CLASS BytecodeEmitter
                                             EmitElemOption opts = EmitElemOption::Get);
     MOZ_MUST_USE bool emitSuperElemOp(ParseNode* pn, JSOp op, bool isCall = false);
 
-    MOZ_MUST_USE bool emitCallee(ParseNode* callee, ParseNode* call, bool spread, bool* callop);
+    MOZ_MUST_USE bool emitCalleeAndThis(ParseNode* callee, ParseNode* call,
+                                        bool isCall, bool isNew);
 
     MOZ_MUST_USE bool emitPipeline(ParseNode* pn);