Revision: 9169
Author:   [email protected]
Date:     Wed Sep  7 05:19:49 2011
Log:      Merge r9160 to the 3.5 branch.

This change fixes a crash in generated code for abrupt exit from with or
catch inside finally.

[email protected]
BUG=
TEST=

Review URL: http://codereview.chromium.org/7840026
http://code.google.com/p/v8/source/detail?r=9169

Added:
 /branches/3.5/test/mjsunit/regress/regress-95485.js
Modified:
 /branches/3.5/src/arm/full-codegen-arm.cc
 /branches/3.5/src/full-codegen.cc
 /branches/3.5/src/ia32/full-codegen-ia32.cc
 /branches/3.5/src/mips/full-codegen-mips.cc
 /branches/3.5/src/version.cc
 /branches/3.5/src/x64/full-codegen-x64.cc

=======================================
--- /dev/null
+++ /branches/3.5/test/mjsunit/regress/regress-95485.js Wed Sep 7 05:19:49 2011
@@ -0,0 +1,42 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+function Test() {
+  var left  = 'XXX';
+  var right = 'YYY';
+  for (var i = 0; i < 3; i++) {
+    var cons = left + right;
+    var substring = cons.substring(2, 4);
+    try {
+      with ({Test: i})
+          continue;
+    } finally { }
+  }
+  return substring;
+}
+
+assertEquals('XY', Test());
=======================================
--- /branches/3.5/src/arm/full-codegen-arm.cc   Wed Aug 31 02:03:56 2011
+++ /branches/3.5/src/arm/full-codegen-arm.cc   Wed Sep  7 05:19:49 2011
@@ -4265,6 +4265,34 @@
   __ mov(r1, Operand(r1, ASR, 1));  // Un-smi-tag value.
   __ add(pc, r1, Operand(masm_->CodeObject()));
 }
+
+
+#undef __
+
+#define __ ACCESS_MASM(masm())
+
+FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit(
+    int* stack_depth,
+    int* context_length) {
+  // The macros used here must preserve the result register.
+
+  // Because the handler block contains the context of the finally
+  // code, we can restore it directly from there for the finally code
+  // rather than iteratively unwinding contexts via their previous
+  // links.
+  __ Drop(*stack_depth);  // Down to the handler block.
+  if (*context_length > 0) {
+    // Restore the context to its dedicated register and the stack.
+    __ ldr(cp, MemOperand(sp, StackHandlerConstants::kContextOffset));
+    __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  }
+  __ PopTryHandler();
+  __ bl(finally_entry_);
+
+  *stack_depth = 0;
+  *context_length = 0;
+  return previous_;
+}


 #undef __
=======================================
--- /branches/3.5/src/full-codegen.cc   Mon Aug 22 04:03:23 2011
+++ /branches/3.5/src/full-codegen.cc   Wed Sep  7 05:19:49 2011
@@ -1334,25 +1334,6 @@
   decrement_stack_height();
   // Never returns here.
 }
-
-
-FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit(
-    int* stack_depth,
-    int* context_length) {
-  // The macros used here must preserve the result register.
-  __ Drop(*stack_depth);
-  __ PopTryHandler();
-  *stack_depth = 0;
-
-  Register context = FullCodeGenerator::context_register();
-  while (*context_length > 0) {
-    codegen_->LoadContextField(context, Context::PREVIOUS_INDEX);
-    --(*context_length);
-  }
-
-  __ Call(finally_entry_);
-  return previous_;
-}


 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit(
=======================================
--- /branches/3.5/src/ia32/full-codegen-ia32.cc Wed Aug 31 02:03:56 2011
+++ /branches/3.5/src/ia32/full-codegen-ia32.cc Wed Sep  7 05:19:49 2011
@@ -4323,6 +4323,34 @@
   __ add(Operand(edx), Immediate(masm_->CodeObject()));
   __ jmp(Operand(edx));
 }
+
+
+#undef __
+
+#define __ ACCESS_MASM(masm())
+
+FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit(
+    int* stack_depth,
+    int* context_length) {
+  // The macros used here must preserve the result register.
+
+  // Because the handler block contains the context of the finally
+  // code, we can restore it directly from there for the finally code
+  // rather than iteratively unwinding contexts via their previous
+  // links.
+  __ Drop(*stack_depth);  // Down to the handler block.
+  if (*context_length > 0) {
+    // Restore the context to its dedicated register and the stack.
+    __ mov(esi, Operand(esp, StackHandlerConstants::kContextOffset));
+    __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi);
+  }
+  __ PopTryHandler();
+  __ call(finally_entry_);
+
+  *stack_depth = 0;
+  *context_length = 0;
+  return previous_;
+}


 #undef __
=======================================
--- /branches/3.5/src/mips/full-codegen-mips.cc Wed Aug 31 02:03:56 2011
+++ /branches/3.5/src/mips/full-codegen-mips.cc Wed Sep  7 05:19:49 2011
@@ -4218,6 +4218,34 @@
   __ Addu(at, a1, Operand(masm_->CodeObject()));
   __ Jump(at);
 }
+
+
+#undef __
+
+#define __ ACCESS_MASM(masm())
+
+FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit(
+    int* stack_depth,
+    int* context_length) {
+  // The macros used here must preserve the result register.
+
+  // Because the handler block contains the context of the finally
+  // code, we can restore it directly from there for the finally code
+  // rather than iteratively unwinding contexts via their previous
+  // links.
+  __ Drop(*stack_depth);  // Down to the handler block.
+  if (*context_length > 0) {
+    // Restore the context to its dedicated register and the stack.
+    __ lw(cp, MemOperand(sp, StackHandlerConstants::kContextOffset));
+    __ sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  }
+  __ PopTryHandler();
+  __ Call(finally_entry_);
+
+  *stack_depth = 0;
+  *context_length = 0;
+  return previous_;
+}


 #undef __
=======================================
--- /branches/3.5/src/version.cc        Wed Sep  7 05:07:36 2011
+++ /branches/3.5/src/version.cc        Wed Sep  7 05:19:49 2011
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     5
 #define BUILD_NUMBER      10
-#define PATCH_LEVEL       4
+#define PATCH_LEVEL       5
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
=======================================
--- /branches/3.5/src/x64/full-codegen-x64.cc   Wed Aug 31 02:03:56 2011
+++ /branches/3.5/src/x64/full-codegen-x64.cc   Wed Sep  7 05:19:49 2011
@@ -4207,6 +4207,33 @@

 #undef __

+#define __ ACCESS_MASM(masm())
+
+FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit(
+    int* stack_depth,
+    int* context_length) {
+  // The macros used here must preserve the result register.
+
+  // Because the handler block contains the context of the finally
+  // code, we can restore it directly from there for the finally code
+  // rather than iteratively unwinding contexts via their previous
+  // links.
+  __ Drop(*stack_depth);  // Down to the handler block.
+  if (*context_length > 0) {
+    // Restore the context to its dedicated register and the stack.
+    __ movq(rsi, Operand(rsp, StackHandlerConstants::kContextOffset));
+    __ movq(Operand(rbp, StandardFrameConstants::kContextOffset), rsi);
+  }
+  __ PopTryHandler();
+  __ call(finally_entry_);
+
+  *stack_depth = 0;
+  *context_length = 0;
+  return previous_;
+}
+
+
+#undef __

 } }  // namespace v8::internal

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to