Bug 1611777 - Part 5: Remove unnecessary super-handling in optional delete. r=yulia
authorAndré Bargull <andre.bargull@gmail.com>
Wed, 29 Jan 2020 16:24:50 +0000
changeset 512096 9dba40e8b408fed3e4acd5c05b568f4dc51a8991
parent 512095 95890e60c691ce8977bd1fe8287215d9312bc3ee
child 512097 4a8a350bba27258f5821dec1e37157e39375e3d1
push id37072
push usercsabou@mozilla.com
push dateThu, 30 Jan 2020 15:44:43 +0000
treeherdermozilla-central@f97c48da9cee [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersyulia
bugs1611777
milestone74.0a1
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 1611777 - Part 5: Remove unnecessary super-handling in optional delete. r=yulia The child node of a DeleteOptionalChainExpr node can't be a super-property accessor, so we can remove this code. Drive-by: Reindent some stack comments. Differential Revision: https://phabricator.services.mozilla.com/D61152
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/FullParseHandler.h
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -6763,33 +6763,33 @@ bool BytecodeEmitter::emitDeleteOptional
   OptionalEmitter oe(this, bytecodeSection().stackDepth());
 
   ParseNode* kid = deleteNode->kid();
   switch (kid->getKind()) {
     case ParseNodeKind::ElemExpr:
     case ParseNodeKind::OptionalElemExpr: {
       auto* elemExpr = &kid->as<PropertyByValueBase>();
       if (!emitDeleteElementInOptChain(elemExpr, oe)) {
-        //              [stack] # If shortcircuit
-        //              [stack] UNDEFINED-OR-NULL
-        //              [stack] # otherwise
-        //              [stack] TRUE
+        //          [stack] # If shortcircuit
+        //          [stack] UNDEFINED-OR-NULL
+        //          [stack] # otherwise
+        //          [stack] SUCCEEDED
         return false;
       }
 
       break;
     }
     case ParseNodeKind::DotExpr:
     case ParseNodeKind::OptionalDotExpr: {
       auto* propExpr = &kid->as<PropertyAccessBase>();
       if (!emitDeletePropertyInOptChain(propExpr, oe)) {
-        //              [stack] # If shortcircuit
-        //              [stack] UNDEFINED-OR-NULL
-        //              [stack] # otherwise
-        //              [stack] TRUE
+        //          [stack] # If shortcircuit
+        //          [stack] UNDEFINED-OR-NULL
+        //          [stack] # otherwise
+        //          [stack] SUCCEEDED
         return false;
       }
       break;
     }
     default:
       MOZ_ASSERT_UNREACHABLE("Unrecognized optional delete ParseNodeKind");
   }
 
@@ -6801,70 +6801,53 @@ bool BytecodeEmitter::emitDeleteOptional
     return false;
   }
 
   return true;
 }
 
 bool BytecodeEmitter::emitDeletePropertyInOptChain(PropertyAccessBase* propExpr,
                                                    OptionalEmitter& oe) {
-  bool isSuper = propExpr->is<PropertyAccess>() &&
-                 propExpr->as<PropertyAccess>().isSuper();
-  PropOpEmitter poe(
-      this, PropOpEmitter::Kind::Delete,
-      isSuper ? PropOpEmitter::ObjKind::Super : PropOpEmitter::ObjKind::Other);
-
-  if (isSuper) {
-    // The expression |delete super.foo;| has to evaluate |super.foo|,
-    // which could throw if |this| hasn't yet been set by a |super(...)|
-    // call or the super-base is not an object, before throwing a
-    // ReferenceError for attempting to delete a super-reference.
-    UnaryNode* base = &propExpr->expression().as<UnaryNode>();
-    if (!emitGetThisForSuperBase(base)) {
-      //            [stack] THIS
-      return false;
-    }
-  } else {
-    if (!poe.prepareForObj()) {
-      //            [stack]
-      return false;
-    }
-    if (!emitOptionalTree(&propExpr->expression(), oe)) {
+  MOZ_ASSERT_IF(propExpr->is<PropertyAccess>(),
+                !propExpr->as<PropertyAccess>().isSuper());
+  PropOpEmitter poe(this, PropOpEmitter::Kind::Delete,
+                    PropOpEmitter::ObjKind::Other);
+
+  if (!poe.prepareForObj()) {
+    //              [stack]
+    return false;
+  }
+  if (!emitOptionalTree(&propExpr->expression(), oe)) {
+    //              [stack] OBJ
+    return false;
+  }
+  if (propExpr->isKind(ParseNodeKind::OptionalDotExpr)) {
+    if (!oe.emitJumpShortCircuit()) {
+      //            [stack] # if Jump
+      //            [stack] UNDEFINED-OR-NULL
+      //            [stack] # otherwise
       //            [stack] OBJ
       return false;
     }
-    if (propExpr->isKind(ParseNodeKind::OptionalDotExpr)) {
-      if (!oe.emitJumpShortCircuit()) {
-        //            [stack] # if Jump
-        //            [stack] UNDEFINED-OR-NULL
-        //            [stack] # otherwise
-        //            [stack] OBJ
-        return false;
-      }
-    }
   }
 
   if (!poe.emitDelete(propExpr->key().atom())) {
-    //              [stack] # if Super
-    //              [stack] THIS
-    //              [stack] # otherwise
     //              [stack] SUCCEEDED
     return false;
   }
 
   return true;
 }
 
 bool BytecodeEmitter::emitDeleteElementInOptChain(PropertyByValueBase* elemExpr,
                                                   OptionalEmitter& oe) {
-  bool isSuper = elemExpr->is<PropertyByValue>() &&
-                 elemExpr->as<PropertyByValue>().isSuper();
-  ElemOpEmitter eoe(
-      this, ElemOpEmitter::Kind::Delete,
-      isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other);
+  MOZ_ASSERT_IF(elemExpr->is<PropertyByValue>(),
+                !elemExpr->as<PropertyByValue>().isSuper());
+  ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Delete,
+                    ElemOpEmitter::ObjKind::Other);
 
   if (!eoe.prepareForObj()) {
     //              [stack]
     return false;
   }
 
   if (!emitOptionalTree(&elemExpr->expression(), oe)) {
     //              [stack] OBJ
@@ -6887,19 +6870,16 @@ bool BytecodeEmitter::emitDeleteElementI
   }
 
   if (!emitOptionalTree(&elemExpr->key(), oe)) {
     //              [stack] OBJ KEY
     return false;
   }
 
   if (!eoe.emitDelete()) {
-    //              [stack] # if Super
-    //              [stack] THIS
-    //              [stack] # otherwise
     //              [stack] SUCCEEDED
     return false;
   }
 
   return true;
 }
 
 static const char* SelfHostedCallFunctionName(JSAtom* name, JSContext* cx) {
--- a/js/src/frontend/FullParseHandler.h
+++ b/js/src/frontend/FullParseHandler.h
@@ -253,17 +253,17 @@ class FullParseHandler {
     }
 
     if (expr->isKind(ParseNodeKind::ElemExpr)) {
       return newUnary(ParseNodeKind::DeleteElemExpr, begin, expr);
     }
 
     if (expr->isKind(ParseNodeKind::OptionalChain)) {
       Node kid = expr->as<UnaryNode>().kid();
-      // Handle property deletion explictly. OptionalCall is handled
+      // Handle property deletion explicitly. OptionalCall is handled
       // via DeleteExpr.
       if (kid->isKind(ParseNodeKind::DotExpr) ||
           kid->isKind(ParseNodeKind::OptionalDotExpr) ||
           kid->isKind(ParseNodeKind::ElemExpr) ||
           kid->isKind(ParseNodeKind::OptionalElemExpr)) {
         return newUnary(ParseNodeKind::DeleteOptionalChainExpr, begin, kid);
       }
     }