فهرست منبع

TryFinally Fix: Add ByteCodeOffset to BrOnException added from finally to early exit

Without ByteCodeOffset, post-op bailout can pick up bytecodeoffset from the next instruction which is in a different eh region, this can cause problems in the interpreter.

Fixes OS#12751051
Meghana Gupta 8 سال پیش
والد
کامیت
5fa19f9649
2فایلهای تغییر یافته به همراه31 افزوده شده و 0 حذف شده
  1. 2 0
      lib/Backend/FlowGraph.cpp
  2. 29 0
      test/EH/tryfinallytests.js

+ 2 - 0
lib/Backend/FlowGraph.cpp

@@ -693,6 +693,7 @@ void FlowGraph::InsertEdgeFromFinallyToEarlyExit(BasicBlock *finallyEndBlock, IR
 
         IR::BranchInstr *brToExit = IR::BranchInstr::New(Js::OpCode::BrOnException, exitLabel, this->func);
         brToExit->m_brFinallyToEarlyExit = true;
+        brToExit->SetByteCodeOffset(lastInstr);
         leaveLabel->InsertBefore(brToExit);
 
         this->AddBlock(brLabel, brToExit, finallyEndBlock->GetNext(), finallyEndBlock /*prevBlock*/);
@@ -704,6 +705,7 @@ void FlowGraph::InsertEdgeFromFinallyToEarlyExit(BasicBlock *finallyEndBlock, IR
     {
         // If the Leave/LeaveNull at the end of finally was preceeded by a Label, we reuse the block inserting BrOnException to early exit in it
         IR::BranchInstr *brToExit = IR::BranchInstr::New(Js::OpCode::BrOnException, exitLabel, this->func);
+        brToExit->SetByteCodeOffset(lastInstr);
         brToExit->m_brFinallyToEarlyExit = true;
         leaveLabel->InsertBefore(brToExit);
         this->AddEdge(finallyEndBlock, exitLabel->GetBasicBlock());

+ 29 - 0
test/EH/tryfinallytests.js

@@ -79,6 +79,30 @@ function test5() {
   }
 }
 
+function test4() {
+  var obj0 = {};
+  var obj1 = {};
+  var arrObj0 = {};
+  var func0 = function () {
+  };
+  var func2 = function () {
+  };
+  obj0.method1 = func0;
+  obj1.method1 = func2;
+  var ary = Array();
+  var protoObj1 = Object(obj1);
+  while (typeof 11) {
+    protoObj1.method1(obj0.method1(ary.unshift((Object.defineProperty(obj1, 'prop1', {})))));
+    try {
+    } catch (ex) {
+      continue;
+    } finally {
+      obj1.prop1 = typeof arrObj0.length;
+      break;
+    }
+  }
+}
+
 test0();
 test0();
 test0();
@@ -95,8 +119,13 @@ test3();
 test3();
 test3();
 
+test4();
+test4();
+test4();
+
 test5();
 test5();
 test5();
 
+
 WScript.Echo("passed");