Add missing BailoutId and FrameState to with statements.
authormstarzinger <mstarzinger@chromium.org>
Thu, 22 Jan 2015 10:57:30 +0000 (02:57 -0800)
committerCommit bot <commit-bot@chromium.org>
Thu, 22 Jan 2015 10:57:42 +0000 (10:57 +0000)
R=bmeurer@chromium.org
TEST=mjsunit/regress/regress-crbug-450642
BUG=chromium:450642
LOG=N

Review URL: https://codereview.chromium.org/865833002

Cr-Commit-Position: refs/heads/master@{#26218}

src/ast-numbering.cc
src/ast.h
src/compiler/ast-graph-builder.cc
src/compiler/linkage.cc
src/compiler/operator-properties.cc
src/full-codegen.cc
test/mjsunit/regress/regress-crbug-450642.js [new file with mode: 0644]
test/unittests/compiler/js-operator-unittest.cc

index 70ba5cb..d9882ae 100644 (file)
@@ -291,6 +291,7 @@ void AstNumberingVisitor::VisitCallRuntime(CallRuntime* node) {
 void AstNumberingVisitor::VisitWithStatement(WithStatement* node) {
   IncrementNodeCount();
   DisableOptimization(kWithStatement);
+  node->set_base_id(ReserveIdRange(WithStatement::num_ids()));
   Visit(node->expression());
   Visit(node->statement());
 }
index dd49416..a797272 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -1102,19 +1102,32 @@ class WithStatement FINAL : public Statement {
   Expression* expression() const { return expression_; }
   Statement* statement() const { return statement_; }
 
+  void set_base_id(int id) { base_id_ = id; }
+  static int num_ids() { return parent_num_ids() + 1; }
+  BailoutId EntryId() const { return BailoutId(local_id(0)); }
+
  protected:
-  WithStatement(
-      Zone* zone, Scope* scope,
-      Expression* expression, Statement* statement, int pos)
+  WithStatement(Zone* zone, Scope* scope, Expression* expression,
+                Statement* statement, int pos)
       : Statement(zone, pos),
         scope_(scope),
         expression_(expression),
-        statement_(statement) { }
+        statement_(statement),
+        base_id_(BailoutId::None().ToInt()) {}
+  static int parent_num_ids() { return 0; }
+
+  int base_id() const {
+    DCHECK(!BailoutId(base_id_).IsNone());
+    return base_id_;
+  }
 
  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
   Scope* scope_;
   Expression* expression_;
   Statement* statement_;
+  int base_id_;
 };
 
 
index f001455..4177a75 100644 (file)
@@ -542,6 +542,7 @@ void AstGraphBuilder::VisitWithStatement(WithStatement* stmt) {
   Node* value = environment()->Pop();
   const Operator* op = javascript()->CreateWithContext();
   Node* context = NewNode(op, value, GetFunctionClosure());
+  PrepareFrameState(context, stmt->EntryId());
   ContextScope scope(this, stmt->scope(), context);
   Visit(stmt->statement());
 }
@@ -1083,8 +1084,7 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
           const Operator* op =
               javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
           Node* set_prototype = NewNode(op, receiver, value);
-          // SetPrototype should not lazy deopt on an object
-          // literal.
+          // SetPrototype should not lazy deopt on an object literal.
           PrepareFrameState(set_prototype, BailoutId::None());
         }
         break;
index 80f3fe8..d786169 100644 (file)
@@ -190,6 +190,7 @@ bool Linkage::NeedsFrameState(Runtime::FunctionId function) {
     case Runtime::kPreventExtensions:
     case Runtime::kPromiseRejectEvent:
     case Runtime::kPromiseRevokeReject:
+    case Runtime::kPushWithContext:
     case Runtime::kRegExpInitializeAndCompile:
     case Runtime::kRegExpExecMultiple:
     case Runtime::kResolvePossiblyDirectEval:
index 09d964b..319ed97 100644 (file)
@@ -57,22 +57,25 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) {
     case IrOpcode::kJSBitwiseOr:
     case IrOpcode::kJSBitwiseXor:
     case IrOpcode::kJSDivide:
-    case IrOpcode::kJSLoadNamed:
-    case IrOpcode::kJSLoadProperty:
     case IrOpcode::kJSModulus:
     case IrOpcode::kJSMultiply:
     case IrOpcode::kJSShiftLeft:
     case IrOpcode::kJSShiftRight:
     case IrOpcode::kJSShiftRightLogical:
-    case IrOpcode::kJSStoreNamed:
-    case IrOpcode::kJSStoreProperty:
     case IrOpcode::kJSSubtract:
 
+    // Context operations
+    case IrOpcode::kJSCreateWithContext:
+
     // Conversions
     case IrOpcode::kJSToObject:
     case IrOpcode::kJSToNumber:
 
-    // Other
+    // Properties
+    case IrOpcode::kJSLoadNamed:
+    case IrOpcode::kJSLoadProperty:
+    case IrOpcode::kJSStoreNamed:
+    case IrOpcode::kJSStoreProperty:
     case IrOpcode::kJSDeleteProperty:
       return true;
 
index 0d1ff4f..86b781e 100644 (file)
@@ -1236,6 +1236,7 @@ void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) {
   PushFunctionArgumentForContextAllocation();
   __ CallRuntime(Runtime::kPushWithContext, 2);
   StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
+  PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
 
   Scope* saved_scope = scope();
   scope_ = stmt->scope();
diff --git a/test/mjsunit/regress/regress-crbug-450642.js b/test/mjsunit/regress/regress-crbug-450642.js
new file mode 100644 (file)
index 0000000..7f821e0
--- /dev/null
@@ -0,0 +1,5 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+assertThrows(function() { with (undefined) {} }, TypeError);
index 912f984..7d48906 100644 (file)
@@ -77,7 +77,7 @@ const SharedOperator kSharedOperators[] = {
     SHARED(InstanceOf, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
     SHARED(Debugger, Operator::kNoProperties, 0, 0, 1, 1, 0, 1),
     SHARED(CreateFunctionContext, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
-    SHARED(CreateWithContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1),
+    SHARED(CreateWithContext, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
     SHARED(CreateBlockContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1),
     SHARED(CreateModuleContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1),
     SHARED(CreateScriptContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1)