High firefox Logic Error 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionJIT miscompilation in the JavaScript Engine: JIT component
ComponentSpiderMonkey
Bug ClassLogic Error
Tracker2020906
Fix commit0629c75d9760 (firefox) +33/-37
CISA KEVNot listed
Creditedmaxpl0it working with Trend Micro Zero Day Initiative
Disclosed2026-03-24

Changed Functions

FunctionChangeNotes
if
js/src/jit/IonAnalysis.cpp
modified

Files Changed

  • js/src/jit/IonAnalysis.cpp
diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp
index faf679a6f58..407c134f832 100644
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -568,11 +568,9 @@ static bool BlockIsSingleTest(MBasicBlock* phiBlock, MBasicBlock* testBlock,
   *ptest = nullptr;
 
   if (phiBlock != testBlock) {
-    MOZ_ASSERT(phiBlock->numSuccessors() == 1 &&
-               phiBlock->getSuccessor(0) == testBlock);
-    if (!phiBlock->begin()->isGoto()) {
-      return false;
-    }
+    MOZ_RELEASE_ASSERT(phiBlock->lastIns()->isGoto());
+    MOZ_RELEASE_ASSERT(phiBlock->lastIns()->toGoto()->target() == testBlock);
+    MOZ_RELEASE_ASSERT(testBlock->numPredecessors() == 1);
   }
 
   auto iter = testBlock->rbegin();
@@ -686,7 +684,7 @@ static bool IsTestInputMaybeToBool(MTest* test, MDefinition* value) {
   blockResult->setImplicitlyUsedUnchecked();
 
   MInstruction* ins = block->lastIns();
-  MOZ_ASSERT(ins->isGoto());
+  MOZ_RELEASE_ASSERT(ins->isGoto());
   ins->toGoto()->target()->removePredecessor(block);
   block->discardLastIns();
 
@@ -707,15 +705,14 @@ static bool IsTestInputMaybeToBool(MTest* test, MDefinition* value) {
   MInstruction* ins = block->lastIns();
   if (ins->isTest()) {
     MTest* test = ins->toTest();
-    MOZ_ASSERT(test->input() == value);
+    MOZ_RELEASE_ASSERT(test->input() == value);
 
     if (ifTrue != test->ifTrue()) {
       test->ifTrue()->removePredecessor(block);
       if (!ifTrue->addPredecessorSameInputsAs(block, existingPred)) {
         return false;
       }
-      MOZ_ASSERT(test->ifTrue() == test->getSuccessor(0));
-      test->replaceSuccessor(0, ifTrue);
+      test->replaceSuccessor(MTest::TrueBranchIndex, ifTrue);
     }
 
     if (ifFalse != test->ifFalse()) {
@@ -723,14 +720,13 @@ static bool IsTestInputMaybeToBool(MTest* test, MDefinition* value) {
       if (!ifFalse->addPredecessorSameInputsAs(block, existingPred)) {
         return false;
       }
-      MOZ_ASSERT(test->ifFalse() == test->getSuccessor(1));
-      test->replaceSuccessor(1, ifFalse);
+      test->replaceSuccessor(MTest::FalseBranchIndex, ifFalse);
     }
 
     return true;
   }
 
-  MOZ_ASSERT(ins->isGoto());
+  MOZ_RELEASE_ASSERT(ins->isGoto());
   ins->toGoto()->target()->removePredecessor(block);
   block->discardLastIns();
 
@@ -775,8 +771,8 @@ static bool IsDiamondPattern(MBasicBlock* initialBlock) {
     return false;
   }
 
-  MBasicBlock* phiBlock = trueBranch->getSuccessor(0);
-  if (phiBlock != falseBranch->getSuccessor(0)) {
+  MBasicBlock* phiBlock = trueBranch->lastIns()->toGoto()->target();
+  if (phiBlock != falseBranch->lastIns()->toGoto()->target()) {
     return false;
   }
   if (phiBlock->numPredecessors() != 2) {
@@ -820,13 +816,13 @@ static bool IsDiamondPattern(MBasicBlock* initialBlock) {
     return true;
   }
 
-  MBasicBlock* phiBlock = trueBranch->getSuccessor(0);
+  MBasicBlock* phiBlock = trueBranch->lastIns()->toGoto()->target();
   MBasicBlock* testBlock = phiBlock;
-  if (testBlock->numSuccessors() == 1) {
+  if (testBlock->lastIns()->isGoto()) {
     if (testBlock->isLoopBackedge()) {
       return true;
     }
-    testBlock = testBlock->getSuccessor(0);
+    testBlock = testBlock->lastIns()->toGoto()->target();
     if (testBlock->numPredecessors() != 1) {
       return true;
     }
@@ -838,7 +834,7 @@ static bool IsDiamondPattern(MBasicBlock* initialBlock) {
     return true;
   }
 
-  MOZ_ASSERT(phi->numOperands() == 2);
+  MOZ_RELEASE_ASSERT(phi->numOperands() == 2);
 
   // Make sure the test block does not have any outgoing loop backedges.
   if (!SplitCriticalEdgesForBlock(graph, testBlock)) {
@@ -929,8 +925,8 @@ static bool IsTrianglePattern(MBasicBlock* initialBlock) {
   MBasicBlock* trueBranch = initialTest->ifTrue();
   MBasicBlock* falseBranch = initialTest->ifFalse();
 
-  if (trueBranch->numSuccessors() == 1 &&
-      trueBranch->getSuccessor(0) == falseBranch) {
+  if (trueBranch->lastIns()->isGoto() &&
+      trueBranch->lastIns()->toGoto()->target() == falseBranch) {
     if (trueBranch->numPredecessors() != 1) {
       return false;
     }
@@ -940,8 +936,8 @@ static bool IsTrianglePattern(MBasicBlock* initialBlock) {
     return true;
   }
 
-  if (falseBranch->numSuccessors() == 1 &&
-      falseBranch->getSuccessor(0) == trueBranch) {
+  if (falseBranch->lastIns()->isGoto() &&
+      falseBranch->lastIns()->toGoto()->target() == trueBranch) {
     if (trueBranch->numPredecessors() != 2) {
       return false;
     }
@@ -999,19 +995,19 @@ static bool IsTrianglePattern(MBasicBlock* initialBlock) {
   }
 
   MBasicBlock* phiBlock;
-  if (trueBranch->numSuccessors() == 1 &&
-      trueBranch->getSuccessor(0) == falseBranch) {
+  if (trueBranch->lastIns()->isGoto() &&
+      trueBranch->lastIns()->toGoto()->target() == falseBranch) {
     phiBlock = falseBranch;
   } else {
-    MOZ_ASSERT(falseBranch->getSuccessor(0) == trueBranch);
+    MOZ_ASSERT(falseBranch->lastIns()->toGoto()->target() == trueBranch);
     phiBlock = trueBranch;
   }
 
   MBasicBlock* testBlock = phiBlock;
-  if (testBlock->numSuccessors() == 1) {
-    MOZ_ASSERT(!testBlock->isLoopBackedge());
+  if (testBlock->lastIns()->isGoto()) {
+    MOZ_RELEASE_ASSERT(!testBlock->isLoopBackedge());
 
-    testBlock = testBlock->getSuccessor(0);
+    testBlock = testBlock->lastIns()->toGoto()->target();
     if (testBlock->numPredecessors() != 1) {
       return true;
     }
@@ -1023,7 +1019,7 @@ static bool IsTrianglePattern(MBasicBlock* initialBlock) {
     return true;
   }
 
-  MOZ_ASSERT(phi->numOperands() == 2);
+  MOZ_RELEASE_ASSERT(phi->numOperands() == 2);
 
   // If the phi-operand doesn't match the initial input, we can't fold the test.
   auto* phiInputForInitialBlock =
@@ -1194,17 +1190,17 @@ static bool IsTrianglePattern(MBasicBlock* initialBlock) {
   }
 
   MBasicBlock* testBlock = phiBlock;
-  if (testBlock->numSuccessors() == 1) {
+  if (testBlock->lastIns()->isGoto()) {
     if (testBlock->isLoopBackedge()) {
       return true;
     }
-    testBlock = testBlock->getSuccessor(0);
+    testBlock = testBlock->lastIns()->toGoto()->target();
     if (testBlock->numPredecessors() != 1) {
       return true;
     }
   }
 
-  MOZ_ASSERT(!phiBlock->isLoopBackedge());
+  MOZ_RELEASE_ASSERT(!phiBlock->isLoopBackedge());
 
   MPhi* phi = nullptr;
   MTest* finalTest = nullptr;
@@ -1212,7 +1208,7 @@ static bool IsTrianglePattern(MBasicBlock* initialBlock) {
     return true;
   }
 
-  MOZ_ASSERT(phiBlock->numPredecessors() == phi->numOperands());
+  MOZ_RELEASE_ASSERT(phiBlock->numPredecessors() == phi->numOperands());
 
   // If the phi-operand doesn't match the initial input, we can't fold the test.
   auto* phiInputForInitialBlock =
@@ -1243,7 +1239,7 @@ static bool IsTrianglePattern(MBasicBlock* initialBlock) {
       return true;
     }
 
-    MOZ_ASSERT(!pred->isLoopBackedge());
+    MOZ_RELEASE_ASSERT(!pred->isLoopBackedge());
   }
 
   // Ensure we found the single goto block.
@@ -1270,7 +1266,7 @@ static bool IsTrianglePattern(MBasicBlock* initialBlock) {
 
   // Update all test instructions to point to the final target.
   while (phiBlock->numPredecessors()) {
Loading diff…