| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
| 6 | 6 |
| 7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
| 8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
| 9 #include "src/compiler/ast-loop-assignment-analyzer.h" | 9 #include "src/compiler/ast-loop-assignment-analyzer.h" |
| 10 #include "src/compiler/control-builders.h" | 10 #include "src/compiler/control-builders.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 | 33 |
| 34 // Determines how to combine the frame state with the value | 34 // Determines how to combine the frame state with the value |
| 35 // that is about to be plugged into this AstContext. | 35 // that is about to be plugged into this AstContext. |
| 36 OutputFrameStateCombine GetStateCombine() { | 36 OutputFrameStateCombine GetStateCombine() { |
| 37 return IsEffect() ? OutputFrameStateCombine::Ignore() | 37 return IsEffect() ? OutputFrameStateCombine::Ignore() |
| 38 : OutputFrameStateCombine::Push(); | 38 : OutputFrameStateCombine::Push(); |
| 39 } | 39 } |
| 40 | 40 |
| 41 // Plug a node into this expression context. Call this function in tail | 41 // Plug a node into this expression context. Call this function in tail |
| 42 // position in the Visit functions for expressions. | 42 // position in the Visit functions for expressions. |
| 43 virtual void ProduceValue(Node* value) = 0; | 43 virtual void ProduceValue(Expression* expr, Node* value) = 0; |
| 44 | 44 |
| 45 // Unplugs a node from this expression context. Call this to retrieve the | 45 // Unplugs a node from this expression context. Call this to retrieve the |
| 46 // result of another Visit function that already plugged the context. | 46 // result of another Visit function that already plugged the context. |
| 47 virtual Node* ConsumeValue() = 0; | 47 virtual Node* ConsumeValue() = 0; |
| 48 | 48 |
| 49 // Shortcut for "context->ProduceValue(context->ConsumeValue())". | 49 // Shortcut for "context->ProduceValue(context->ConsumeValue())". |
| 50 void ReplaceValue() { ProduceValue(ConsumeValue()); } | 50 void ReplaceValue(Expression* expr) { ProduceValue(expr, ConsumeValue()); } |
| 51 | 51 |
| 52 protected: | 52 protected: |
| 53 AstContext(AstGraphBuilder* owner, Expression::Context kind); | 53 AstContext(AstGraphBuilder* owner, Expression::Context kind); |
| 54 virtual ~AstContext(); | 54 virtual ~AstContext(); |
| 55 | 55 |
| 56 AstGraphBuilder* owner() const { return owner_; } | 56 AstGraphBuilder* owner() const { return owner_; } |
| 57 Environment* environment() const { return owner_->environment(); } | 57 Environment* environment() const { return owner_->environment(); } |
| 58 | 58 |
| 59 // We want to be able to assert, in a context-specific way, that the stack | 59 // We want to be able to assert, in a context-specific way, that the stack |
| 60 // height makes sense when the context is filled. | 60 // height makes sense when the context is filled. |
| 61 #ifdef DEBUG | 61 #ifdef DEBUG |
| 62 int original_height_; | 62 int original_height_; |
| 63 #endif | 63 #endif |
| 64 | 64 |
| 65 private: | 65 private: |
| 66 Expression::Context kind_; | 66 Expression::Context kind_; |
| 67 AstGraphBuilder* owner_; | 67 AstGraphBuilder* owner_; |
| 68 AstContext* outer_; | 68 AstContext* outer_; |
| 69 }; | 69 }; |
| 70 | 70 |
| 71 | 71 |
| 72 // Context to evaluate expression for its side effects only. | 72 // Context to evaluate expression for its side effects only. |
| 73 class AstGraphBuilder::AstEffectContext final : public AstContext { | 73 class AstGraphBuilder::AstEffectContext final : public AstContext { |
| 74 public: | 74 public: |
| 75 explicit AstEffectContext(AstGraphBuilder* owner) | 75 explicit AstEffectContext(AstGraphBuilder* owner) |
| 76 : AstContext(owner, Expression::kEffect) {} | 76 : AstContext(owner, Expression::kEffect) {} |
| 77 ~AstEffectContext() final; | 77 ~AstEffectContext() final; |
| 78 void ProduceValue(Node* value) final; | 78 void ProduceValue(Expression* expr, Node* value) final; |
| 79 Node* ConsumeValue() final; | 79 Node* ConsumeValue() final; |
| 80 }; | 80 }; |
| 81 | 81 |
| 82 | 82 |
| 83 // Context to evaluate expression for its value (and side effects). | 83 // Context to evaluate expression for its value (and side effects). |
| 84 class AstGraphBuilder::AstValueContext final : public AstContext { | 84 class AstGraphBuilder::AstValueContext final : public AstContext { |
| 85 public: | 85 public: |
| 86 explicit AstValueContext(AstGraphBuilder* owner) | 86 explicit AstValueContext(AstGraphBuilder* owner) |
| 87 : AstContext(owner, Expression::kValue) {} | 87 : AstContext(owner, Expression::kValue) {} |
| 88 ~AstValueContext() final; | 88 ~AstValueContext() final; |
| 89 void ProduceValue(Node* value) final; | 89 void ProduceValue(Expression* expr, Node* value) final; |
| 90 Node* ConsumeValue() final; | 90 Node* ConsumeValue() final; |
| 91 }; | 91 }; |
| 92 | 92 |
| 93 | 93 |
| 94 // Context to evaluate expression for a condition value (and side effects). | 94 // Context to evaluate expression for a condition value (and side effects). |
| 95 class AstGraphBuilder::AstTestContext final : public AstContext { | 95 class AstGraphBuilder::AstTestContext final : public AstContext { |
| 96 public: | 96 public: |
| 97 AstTestContext(AstGraphBuilder* owner, TypeFeedbackId feedback_id) | 97 AstTestContext(AstGraphBuilder* owner, TypeFeedbackId feedback_id) |
| 98 : AstContext(owner, Expression::kTest), feedback_id_(feedback_id) {} | 98 : AstContext(owner, Expression::kTest), feedback_id_(feedback_id) {} |
| 99 ~AstTestContext() final; | 99 ~AstTestContext() final; |
| 100 void ProduceValue(Node* value) final; | 100 void ProduceValue(Expression* expr, Node* value) final; |
| 101 Node* ConsumeValue() final; | 101 Node* ConsumeValue() final; |
| 102 | 102 |
| 103 private: | 103 private: |
| 104 TypeFeedbackId const feedback_id_; | 104 TypeFeedbackId const feedback_id_; |
| 105 }; | 105 }; |
| 106 | 106 |
| 107 | 107 |
| 108 // Scoped class tracking context objects created by the visitor. Represents | 108 // Scoped class tracking context objects created by the visitor. Represents |
| 109 // mutations of the context chain within the function body and allows to | 109 // mutations of the context chain within the function body and allows to |
| 110 // change the current {scope} and {context} during visitation. | 110 // change the current {scope} and {context} during visitation. |
| (...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 961 | 961 |
| 962 AstGraphBuilder::AstValueContext::~AstValueContext() { | 962 AstGraphBuilder::AstValueContext::~AstValueContext() { |
| 963 DCHECK(environment()->stack_height() == original_height_ + 1); | 963 DCHECK(environment()->stack_height() == original_height_ + 1); |
| 964 } | 964 } |
| 965 | 965 |
| 966 | 966 |
| 967 AstGraphBuilder::AstTestContext::~AstTestContext() { | 967 AstGraphBuilder::AstTestContext::~AstTestContext() { |
| 968 DCHECK(environment()->stack_height() == original_height_ + 1); | 968 DCHECK(environment()->stack_height() == original_height_ + 1); |
| 969 } | 969 } |
| 970 | 970 |
| 971 void AstGraphBuilder::AstEffectContext::ProduceValue(Expression* expr, |
| 972 Node* value) { |
| 973 // The value is ignored. |
| 974 owner()->PrepareEagerCheckpoint(expr->id()); |
| 975 } |
| 971 | 976 |
| 972 void AstGraphBuilder::AstEffectContext::ProduceValue(Node* value) { | 977 void AstGraphBuilder::AstValueContext::ProduceValue(Expression* expr, |
| 973 // The value is ignored. | 978 Node* value) { |
| 979 environment()->Push(value); |
| 980 owner()->PrepareEagerCheckpoint(expr->id()); |
| 981 } |
| 982 |
| 983 void AstGraphBuilder::AstTestContext::ProduceValue(Expression* expr, |
| 984 Node* value) { |
| 985 environment()->Push(owner()->BuildToBoolean(value, feedback_id_)); |
| 986 owner()->PrepareEagerCheckpoint(expr->id()); |
| 974 } | 987 } |
| 975 | 988 |
| 976 | 989 |
| 977 void AstGraphBuilder::AstValueContext::ProduceValue(Node* value) { | |
| 978 environment()->Push(value); | |
| 979 } | |
| 980 | |
| 981 | |
| 982 void AstGraphBuilder::AstTestContext::ProduceValue(Node* value) { | |
| 983 environment()->Push(owner()->BuildToBoolean(value, feedback_id_)); | |
| 984 } | |
| 985 | |
| 986 | |
| 987 Node* AstGraphBuilder::AstEffectContext::ConsumeValue() { return nullptr; } | 990 Node* AstGraphBuilder::AstEffectContext::ConsumeValue() { return nullptr; } |
| 988 | 991 |
| 989 | 992 |
| 990 Node* AstGraphBuilder::AstValueContext::ConsumeValue() { | 993 Node* AstGraphBuilder::AstValueContext::ConsumeValue() { |
| 991 return environment()->Pop(); | 994 return environment()->Pop(); |
| 992 } | 995 } |
| 993 | 996 |
| 994 | 997 |
| 995 Node* AstGraphBuilder::AstTestContext::ConsumeValue() { | 998 Node* AstGraphBuilder::AstTestContext::ConsumeValue() { |
| 996 return environment()->Pop(); | 999 return environment()->Pop(); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1064 VisitForValue(exprs->at(i)); | 1067 VisitForValue(exprs->at(i)); |
| 1065 } | 1068 } |
| 1066 } | 1069 } |
| 1067 | 1070 |
| 1068 | 1071 |
| 1069 void AstGraphBuilder::VisitForValue(Expression* expr) { | 1072 void AstGraphBuilder::VisitForValue(Expression* expr) { |
| 1070 AstValueContext for_value(this); | 1073 AstValueContext for_value(this); |
| 1071 if (!CheckStackOverflow()) { | 1074 if (!CheckStackOverflow()) { |
| 1072 expr->Accept(this); | 1075 expr->Accept(this); |
| 1073 } else { | 1076 } else { |
| 1074 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); | 1077 ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant()); |
| 1075 } | 1078 } |
| 1076 } | 1079 } |
| 1077 | 1080 |
| 1078 | 1081 |
| 1079 void AstGraphBuilder::VisitForEffect(Expression* expr) { | 1082 void AstGraphBuilder::VisitForEffect(Expression* expr) { |
| 1080 AstEffectContext for_effect(this); | 1083 AstEffectContext for_effect(this); |
| 1081 if (!CheckStackOverflow()) { | 1084 if (!CheckStackOverflow()) { |
| 1082 expr->Accept(this); | 1085 expr->Accept(this); |
| 1083 } else { | 1086 } else { |
| 1084 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); | 1087 ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant()); |
| 1085 } | 1088 } |
| 1086 } | 1089 } |
| 1087 | 1090 |
| 1088 | 1091 |
| 1089 void AstGraphBuilder::VisitForTest(Expression* expr) { | 1092 void AstGraphBuilder::VisitForTest(Expression* expr) { |
| 1090 AstTestContext for_condition(this, expr->test_id()); | 1093 AstTestContext for_condition(this, expr->test_id()); |
| 1091 if (!CheckStackOverflow()) { | 1094 if (!CheckStackOverflow()) { |
| 1092 expr->Accept(this); | 1095 expr->Accept(this); |
| 1093 } else { | 1096 } else { |
| 1094 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); | 1097 ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant()); |
| 1095 } | 1098 } |
| 1096 } | 1099 } |
| 1097 | 1100 |
| 1098 | 1101 |
| 1099 void AstGraphBuilder::Visit(Expression* expr) { | 1102 void AstGraphBuilder::Visit(Expression* expr) { |
| 1100 // Reuses enclosing AstContext. | 1103 // Reuses enclosing AstContext. |
| 1101 if (!CheckStackOverflow()) { | 1104 if (!CheckStackOverflow()) { |
| 1102 expr->Accept(this); | 1105 expr->Accept(this); |
| 1103 } else { | 1106 } else { |
| 1104 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); | 1107 ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant()); |
| 1105 } | 1108 } |
| 1106 } | 1109 } |
| 1107 | 1110 |
| 1108 | 1111 |
| 1109 void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) { | 1112 void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) { |
| 1110 Variable* variable = decl->proxy()->var(); | 1113 Variable* variable = decl->proxy()->var(); |
| 1111 VariableMode mode = decl->mode(); | 1114 VariableMode mode = decl->mode(); |
| 1112 bool hole_init = mode == CONST || mode == LET; | 1115 bool hole_init = mode == CONST || mode == LET; |
| 1113 switch (variable->location()) { | 1116 switch (variable->location()) { |
| 1114 case VariableLocation::GLOBAL: | 1117 case VariableLocation::GLOBAL: |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1431 PrepareFrameState(value, stmt->FilterId(), | 1434 PrepareFrameState(value, stmt->FilterId(), |
| 1432 OutputFrameStateCombine::Push()); | 1435 OutputFrameStateCombine::Push()); |
| 1433 IfBuilder test_value(this); | 1436 IfBuilder test_value(this); |
| 1434 Node* test_value_cond = | 1437 Node* test_value_cond = |
| 1435 NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), | 1438 NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), |
| 1436 value, jsgraph()->UndefinedConstant()); | 1439 value, jsgraph()->UndefinedConstant()); |
| 1437 test_value.If(test_value_cond, BranchHint::kFalse); | 1440 test_value.If(test_value_cond, BranchHint::kFalse); |
| 1438 test_value.Then(); | 1441 test_value.Then(); |
| 1439 test_value.Else(); | 1442 test_value.Else(); |
| 1440 { | 1443 { |
| 1444 environment()->Push(value); |
| 1445 PrepareEagerCheckpoint(stmt->FilterId()); |
| 1446 value = environment()->Pop(); |
| 1441 // Bind value and do loop body. | 1447 // Bind value and do loop body. |
| 1442 VectorSlotPair feedback = | 1448 VectorSlotPair feedback = |
| 1443 CreateVectorSlotPair(stmt->EachFeedbackSlot()); | 1449 CreateVectorSlotPair(stmt->EachFeedbackSlot()); |
| 1444 VisitForInAssignment(stmt->each(), value, feedback, stmt->FilterId(), | 1450 VisitForInAssignment(stmt->each(), value, feedback, |
| 1445 stmt->AssignmentId()); | 1451 stmt->AssignmentId()); |
| 1446 VisitIterationBody(stmt, &for_loop); | 1452 VisitIterationBody(stmt, &for_loop); |
| 1447 } | 1453 } |
| 1448 test_value.End(); | 1454 test_value.End(); |
| 1449 for_loop.EndBody(); | 1455 for_loop.EndBody(); |
| 1450 | 1456 |
| 1451 // Increment counter and continue. | 1457 // Increment counter and continue. |
| 1452 index = environment()->Peek(0); | 1458 index = environment()->Peek(0); |
| 1453 index = NewNode(javascript()->ForInStep(), index); | 1459 index = NewNode(javascript()->ForInStep(), index); |
| 1454 environment()->Poke(0, index); | 1460 environment()->Poke(0, index); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1582 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { | 1588 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { |
| 1583 // Find or build a shared function info. | 1589 // Find or build a shared function info. |
| 1584 Handle<SharedFunctionInfo> shared_info = | 1590 Handle<SharedFunctionInfo> shared_info = |
| 1585 Compiler::GetSharedFunctionInfo(expr, info()->script(), info()); | 1591 Compiler::GetSharedFunctionInfo(expr, info()->script(), info()); |
| 1586 CHECK(!shared_info.is_null()); // TODO(mstarzinger): Set stack overflow? | 1592 CHECK(!shared_info.is_null()); // TODO(mstarzinger): Set stack overflow? |
| 1587 | 1593 |
| 1588 // Create node to instantiate a new closure. | 1594 // Create node to instantiate a new closure. |
| 1589 PretenureFlag pretenure = expr->pretenure() ? TENURED : NOT_TENURED; | 1595 PretenureFlag pretenure = expr->pretenure() ? TENURED : NOT_TENURED; |
| 1590 const Operator* op = javascript()->CreateClosure(shared_info, pretenure); | 1596 const Operator* op = javascript()->CreateClosure(shared_info, pretenure); |
| 1591 Node* value = NewNode(op); | 1597 Node* value = NewNode(op); |
| 1592 ast_context()->ProduceValue(value); | 1598 ast_context()->ProduceValue(expr, value); |
| 1593 } | 1599 } |
| 1594 | 1600 |
| 1595 | 1601 |
| 1596 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { | 1602 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { |
| 1597 // Visit declarations and class literal in a block scope. | 1603 // Visit declarations and class literal in a block scope. |
| 1598 if (expr->scope()->ContextLocalCount() > 0) { | 1604 if (expr->scope()->ContextLocalCount() > 0) { |
| 1599 Node* context = BuildLocalBlockContext(expr->scope()); | 1605 Node* context = BuildLocalBlockContext(expr->scope()); |
| 1600 ContextScope scope(this, expr->scope(), context); | 1606 ContextScope scope(this, expr->scope(), context); |
| 1601 VisitDeclarations(expr->scope()->declarations()); | 1607 VisitDeclarations(expr->scope()->declarations()); |
| 1602 VisitClassLiteralContents(expr); | 1608 VisitClassLiteralContents(expr); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1697 | 1703 |
| 1698 // Assign to class variable. | 1704 // Assign to class variable. |
| 1699 if (expr->class_variable_proxy() != nullptr) { | 1705 if (expr->class_variable_proxy() != nullptr) { |
| 1700 Variable* var = expr->class_variable_proxy()->var(); | 1706 Variable* var = expr->class_variable_proxy()->var(); |
| 1701 VectorSlotPair feedback = CreateVectorSlotPair( | 1707 VectorSlotPair feedback = CreateVectorSlotPair( |
| 1702 expr->NeedsProxySlot() ? expr->ProxySlot() | 1708 expr->NeedsProxySlot() ? expr->ProxySlot() |
| 1703 : FeedbackVectorSlot::Invalid()); | 1709 : FeedbackVectorSlot::Invalid()); |
| 1704 BuildVariableAssignment(var, literal, Token::INIT, feedback, | 1710 BuildVariableAssignment(var, literal, Token::INIT, feedback, |
| 1705 BailoutId::None()); | 1711 BailoutId::None()); |
| 1706 } | 1712 } |
| 1707 ast_context()->ProduceValue(literal); | 1713 ast_context()->ProduceValue(expr, literal); |
| 1708 } | 1714 } |
| 1709 | 1715 |
| 1710 | 1716 |
| 1711 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { | 1717 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { |
| 1712 UNREACHABLE(); | 1718 UNREACHABLE(); |
| 1713 } | 1719 } |
| 1714 | 1720 |
| 1715 | 1721 |
| 1716 void AstGraphBuilder::VisitDoExpression(DoExpression* expr) { | 1722 void AstGraphBuilder::VisitDoExpression(DoExpression* expr) { |
| 1717 VisitBlock(expr->block()); | 1723 VisitBlock(expr->block()); |
| 1718 VisitVariableProxy(expr->result()); | 1724 VisitVariableProxy(expr->result()); |
| 1719 ast_context()->ReplaceValue(); | 1725 ast_context()->ReplaceValue(expr); |
| 1720 } | 1726 } |
| 1721 | 1727 |
| 1722 | 1728 |
| 1723 void AstGraphBuilder::VisitConditional(Conditional* expr) { | 1729 void AstGraphBuilder::VisitConditional(Conditional* expr) { |
| 1724 IfBuilder compare_if(this); | 1730 IfBuilder compare_if(this); |
| 1725 VisitForTest(expr->condition()); | 1731 VisitForTest(expr->condition()); |
| 1726 Node* condition = environment()->Pop(); | 1732 Node* condition = environment()->Pop(); |
| 1727 compare_if.If(condition); | 1733 compare_if.If(condition); |
| 1728 compare_if.Then(); | 1734 compare_if.Then(); |
| 1729 Visit(expr->then_expression()); | 1735 Visit(expr->then_expression()); |
| 1730 compare_if.Else(); | 1736 compare_if.Else(); |
| 1731 Visit(expr->else_expression()); | 1737 Visit(expr->else_expression()); |
| 1732 compare_if.End(); | 1738 compare_if.End(); |
| 1733 ast_context()->ReplaceValue(); | 1739 // Skip plugging AST evaluation contexts of the test kind. This is to stay in |
| 1740 // sync with full codegen which doesn't prepare the proper bailout point (see |
| 1741 // the implementation of FullCodeGenerator::VisitForControl). |
| 1742 if (ast_context()->IsTest()) return; |
| 1743 ast_context()->ReplaceValue(expr); |
| 1734 } | 1744 } |
| 1735 | 1745 |
| 1736 | 1746 |
| 1737 void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 1747 void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
| 1738 VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot()); | 1748 VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot()); |
| 1739 PrepareEagerCheckpoint(BeforeId(expr)); | 1749 PrepareEagerCheckpoint(BeforeId(expr)); |
| 1740 Node* value = BuildVariableLoad(expr->var(), expr->id(), pair, | 1750 Node* value = BuildVariableLoad(expr->var(), expr->id(), pair, |
| 1741 ast_context()->GetStateCombine()); | 1751 ast_context()->GetStateCombine()); |
| 1742 ast_context()->ProduceValue(value); | 1752 ast_context()->ProduceValue(expr, value); |
| 1743 } | 1753 } |
| 1744 | 1754 |
| 1745 | 1755 |
| 1746 void AstGraphBuilder::VisitLiteral(Literal* expr) { | 1756 void AstGraphBuilder::VisitLiteral(Literal* expr) { |
| 1747 Node* value = jsgraph()->Constant(expr->value()); | 1757 Node* value = jsgraph()->Constant(expr->value()); |
| 1748 ast_context()->ProduceValue(value); | 1758 ast_context()->ProduceValue(expr, value); |
| 1749 } | 1759 } |
| 1750 | 1760 |
| 1751 | 1761 |
| 1752 void AstGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { | 1762 void AstGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 1753 Node* closure = GetFunctionClosure(); | 1763 Node* closure = GetFunctionClosure(); |
| 1754 | 1764 |
| 1755 // Create node to materialize a regular expression literal. | 1765 // Create node to materialize a regular expression literal. |
| 1756 const Operator* op = javascript()->CreateLiteralRegExp( | 1766 const Operator* op = javascript()->CreateLiteralRegExp( |
| 1757 expr->pattern(), expr->flags(), expr->literal_index()); | 1767 expr->pattern(), expr->flags(), expr->literal_index()); |
| 1758 Node* literal = NewNode(op, closure); | 1768 Node* literal = NewNode(op, closure); |
| 1759 PrepareFrameState(literal, expr->id(), ast_context()->GetStateCombine()); | 1769 PrepareFrameState(literal, expr->id(), ast_context()->GetStateCombine()); |
| 1760 ast_context()->ProduceValue(literal); | 1770 ast_context()->ProduceValue(expr, literal); |
| 1761 } | 1771 } |
| 1762 | 1772 |
| 1763 | 1773 |
| 1764 void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { | 1774 void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
| 1765 Node* closure = GetFunctionClosure(); | 1775 Node* closure = GetFunctionClosure(); |
| 1766 | 1776 |
| 1767 // Create node to deep-copy the literal boilerplate. | 1777 // Create node to deep-copy the literal boilerplate. |
| 1768 const Operator* op = javascript()->CreateLiteralObject( | 1778 const Operator* op = javascript()->CreateLiteralObject( |
| 1769 expr->constant_properties(), expr->ComputeFlags(true), | 1779 expr->constant_properties(), expr->ComputeFlags(true), |
| 1770 expr->literal_index(), expr->properties_count()); | 1780 expr->literal_index(), expr->properties_count()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1790 UNREACHABLE(); | 1800 UNREACHABLE(); |
| 1791 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1801 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1792 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1802 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1793 // Fall through. | 1803 // Fall through. |
| 1794 case ObjectLiteral::Property::COMPUTED: { | 1804 case ObjectLiteral::Property::COMPUTED: { |
| 1795 // It is safe to use [[Put]] here because the boilerplate already | 1805 // It is safe to use [[Put]] here because the boilerplate already |
| 1796 // contains computed properties with an uninitialized value. | 1806 // contains computed properties with an uninitialized value. |
| 1797 if (key->value()->IsInternalizedString()) { | 1807 if (key->value()->IsInternalizedString()) { |
| 1798 if (property->emit_store()) { | 1808 if (property->emit_store()) { |
| 1799 VisitForValue(property->value()); | 1809 VisitForValue(property->value()); |
| 1800 PrepareEagerCheckpoint(property->value()->id()); | |
| 1801 Node* value = environment()->Pop(); | 1810 Node* value = environment()->Pop(); |
| 1802 Node* literal = environment()->Top(); | 1811 Node* literal = environment()->Top(); |
| 1803 Handle<Name> name = key->AsPropertyName(); | 1812 Handle<Name> name = key->AsPropertyName(); |
| 1804 VectorSlotPair feedback = | 1813 VectorSlotPair feedback = |
| 1805 CreateVectorSlotPair(property->GetSlot(0)); | 1814 CreateVectorSlotPair(property->GetSlot(0)); |
| 1806 Node* store = BuildNamedStore(literal, name, value, feedback); | 1815 Node* store = BuildNamedStore(literal, name, value, feedback); |
| 1807 PrepareFrameState(store, key->id(), | 1816 PrepareFrameState(store, key->id(), |
| 1808 OutputFrameStateCombine::Ignore()); | 1817 OutputFrameStateCombine::Ignore()); |
| 1809 BuildSetHomeObject(value, literal, property, 1); | 1818 BuildSetHomeObject(value, literal, property, 1); |
| 1810 } else { | 1819 } else { |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1936 Node* attr = jsgraph()->Constant(NONE); | 1945 Node* attr = jsgraph()->Constant(NONE); |
| 1937 const Operator* op = javascript()->CallRuntime( | 1946 const Operator* op = javascript()->CallRuntime( |
| 1938 Runtime::kDefineSetterPropertyUnchecked, 4); | 1947 Runtime::kDefineSetterPropertyUnchecked, 4); |
| 1939 Node* call = NewNode(op, receiver, key, value, attr); | 1948 Node* call = NewNode(op, receiver, key, value, attr); |
| 1940 PrepareFrameState(call, BailoutId::None()); | 1949 PrepareFrameState(call, BailoutId::None()); |
| 1941 break; | 1950 break; |
| 1942 } | 1951 } |
| 1943 } | 1952 } |
| 1944 } | 1953 } |
| 1945 | 1954 |
| 1946 ast_context()->ProduceValue(environment()->Pop()); | 1955 ast_context()->ProduceValue(expr, environment()->Pop()); |
| 1947 } | 1956 } |
| 1948 | 1957 |
| 1949 | 1958 |
| 1950 void AstGraphBuilder::VisitObjectLiteralAccessor( | 1959 void AstGraphBuilder::VisitObjectLiteralAccessor( |
| 1951 Node* home_object, ObjectLiteralProperty* property) { | 1960 Node* home_object, ObjectLiteralProperty* property) { |
| 1952 if (property == nullptr) { | 1961 if (property == nullptr) { |
| 1953 VisitForValueOrNull(nullptr); | 1962 VisitForValueOrNull(nullptr); |
| 1954 } else { | 1963 } else { |
| 1955 VisitForValue(property->value()); | 1964 VisitForValue(property->value()); |
| 1956 BuildSetHomeObject(environment()->Top(), home_object, property); | 1965 BuildSetHomeObject(environment()->Top(), home_object, property); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1975 | 1984 |
| 1976 // Create nodes to evaluate all the non-constant subexpressions and to store | 1985 // Create nodes to evaluate all the non-constant subexpressions and to store |
| 1977 // them into the newly cloned array. | 1986 // them into the newly cloned array. |
| 1978 int array_index = 0; | 1987 int array_index = 0; |
| 1979 for (; array_index < expr->values()->length(); array_index++) { | 1988 for (; array_index < expr->values()->length(); array_index++) { |
| 1980 Expression* subexpr = expr->values()->at(array_index); | 1989 Expression* subexpr = expr->values()->at(array_index); |
| 1981 DCHECK(!subexpr->IsSpread()); | 1990 DCHECK(!subexpr->IsSpread()); |
| 1982 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 1991 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
| 1983 | 1992 |
| 1984 VisitForValue(subexpr); | 1993 VisitForValue(subexpr); |
| 1985 { | 1994 VectorSlotPair pair = CreateVectorSlotPair(expr->LiteralFeedbackSlot()); |
| 1986 PrepareEagerCheckpoint(subexpr->id()); | 1995 Node* value = environment()->Pop(); |
| 1987 VectorSlotPair pair = CreateVectorSlotPair(expr->LiteralFeedbackSlot()); | 1996 Node* index = jsgraph()->Constant(array_index); |
| 1988 Node* value = environment()->Pop(); | 1997 Node* literal = environment()->Top(); |
| 1989 Node* index = jsgraph()->Constant(array_index); | 1998 Node* store = BuildKeyedStore(literal, index, value, pair); |
| 1990 Node* literal = environment()->Top(); | 1999 PrepareFrameState(store, expr->GetIdForElement(array_index), |
| 1991 Node* store = BuildKeyedStore(literal, index, value, pair); | 2000 OutputFrameStateCombine::Ignore()); |
| 1992 PrepareFrameState(store, expr->GetIdForElement(array_index), | |
| 1993 OutputFrameStateCombine::Ignore()); | |
| 1994 } | |
| 1995 } | 2001 } |
| 1996 | 2002 |
| 1997 // In case the array literal contains spread expressions it has two parts. The | 2003 // In case the array literal contains spread expressions it has two parts. The |
| 1998 // first part is the "static" array which has a literal index is handled | 2004 // first part is the "static" array which has a literal index is handled |
| 1999 // above. The second part is the part after the first spread expression | 2005 // above. The second part is the part after the first spread expression |
| 2000 // (inclusive) and these elements gets appended to the array. Note that the | 2006 // (inclusive) and these elements gets appended to the array. Note that the |
| 2001 // number elements an iterable produces is unknown ahead of time. | 2007 // number elements an iterable produces is unknown ahead of time. |
| 2002 for (; array_index < expr->values()->length(); array_index++) { | 2008 for (; array_index < expr->values()->length(); array_index++) { |
| 2003 Expression* subexpr = expr->values()->at(array_index); | 2009 Expression* subexpr = expr->values()->at(array_index); |
| 2004 DCHECK(!subexpr->IsSpread()); | 2010 DCHECK(!subexpr->IsSpread()); |
| 2005 | 2011 |
| 2006 VisitForValue(subexpr); | 2012 VisitForValue(subexpr); |
| 2007 { | 2013 { |
| 2008 Node* value = environment()->Pop(); | 2014 Node* value = environment()->Pop(); |
| 2009 Node* array = environment()->Pop(); | 2015 Node* array = environment()->Pop(); |
| 2010 const Operator* op = javascript()->CallRuntime(Runtime::kAppendElement); | 2016 const Operator* op = javascript()->CallRuntime(Runtime::kAppendElement); |
| 2011 Node* result = NewNode(op, array, value); | 2017 Node* result = NewNode(op, array, value); |
| 2012 PrepareFrameState(result, expr->GetIdForElement(array_index)); | 2018 PrepareFrameState(result, expr->GetIdForElement(array_index)); |
| 2013 environment()->Push(result); | 2019 environment()->Push(result); |
| 2014 } | 2020 } |
| 2015 } | 2021 } |
| 2016 | 2022 |
| 2017 ast_context()->ProduceValue(environment()->Pop()); | 2023 ast_context()->ProduceValue(expr, environment()->Pop()); |
| 2018 } | 2024 } |
| 2019 | 2025 |
| 2020 | |
| 2021 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, | 2026 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, |
| 2022 const VectorSlotPair& feedback, | 2027 const VectorSlotPair& feedback, |
| 2023 BailoutId bailout_id_before, | 2028 BailoutId bailout_id) { |
| 2024 BailoutId bailout_id_after) { | |
| 2025 DCHECK(expr->IsValidReferenceExpressionOrThis()); | 2029 DCHECK(expr->IsValidReferenceExpressionOrThis()); |
| 2026 | 2030 |
| 2027 // Left-hand side can only be a property, a global or a variable slot. | 2031 // Left-hand side can only be a property, a global or a variable slot. |
| 2028 Property* property = expr->AsProperty(); | 2032 Property* property = expr->AsProperty(); |
| 2029 LhsKind assign_type = Property::GetAssignType(property); | 2033 LhsKind assign_type = Property::GetAssignType(property); |
| 2030 | 2034 |
| 2031 // Evaluate LHS expression and store the value. | 2035 // Evaluate LHS expression and store the value. |
| 2032 switch (assign_type) { | 2036 switch (assign_type) { |
| 2033 case VARIABLE: { | 2037 case VARIABLE: { |
| 2034 Variable* var = expr->AsVariableProxy()->var(); | 2038 Variable* var = expr->AsVariableProxy()->var(); |
| 2035 environment()->Push(value); | 2039 BuildVariableAssignment(var, value, Token::ASSIGN, feedback, bailout_id); |
| 2036 PrepareEagerCheckpoint(bailout_id_before); | |
| 2037 value = environment()->Pop(); | |
| 2038 BuildVariableAssignment(var, value, Token::ASSIGN, feedback, | |
| 2039 bailout_id_after); | |
| 2040 break; | 2040 break; |
| 2041 } | 2041 } |
| 2042 case NAMED_PROPERTY: { | 2042 case NAMED_PROPERTY: { |
| 2043 environment()->Push(value); | 2043 environment()->Push(value); |
| 2044 VisitForValue(property->obj()); | 2044 VisitForValue(property->obj()); |
| 2045 PrepareEagerCheckpoint(property->obj()->id()); | |
| 2046 Node* object = environment()->Pop(); | 2045 Node* object = environment()->Pop(); |
| 2047 value = environment()->Pop(); | 2046 value = environment()->Pop(); |
| 2048 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2047 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
| 2049 Node* store = BuildNamedStore(object, name, value, feedback); | 2048 Node* store = BuildNamedStore(object, name, value, feedback); |
| 2050 PrepareFrameState(store, bailout_id_after, | 2049 PrepareFrameState(store, bailout_id, OutputFrameStateCombine::Ignore()); |
| 2051 OutputFrameStateCombine::Ignore()); | |
| 2052 break; | 2050 break; |
| 2053 } | 2051 } |
| 2054 case KEYED_PROPERTY: { | 2052 case KEYED_PROPERTY: { |
| 2055 environment()->Push(value); | 2053 environment()->Push(value); |
| 2056 VisitForValue(property->obj()); | 2054 VisitForValue(property->obj()); |
| 2057 VisitForValue(property->key()); | 2055 VisitForValue(property->key()); |
| 2058 PrepareEagerCheckpoint(property->key()->id()); | |
| 2059 Node* key = environment()->Pop(); | 2056 Node* key = environment()->Pop(); |
| 2060 Node* object = environment()->Pop(); | 2057 Node* object = environment()->Pop(); |
| 2061 value = environment()->Pop(); | 2058 value = environment()->Pop(); |
| 2062 Node* store = BuildKeyedStore(object, key, value, feedback); | 2059 Node* store = BuildKeyedStore(object, key, value, feedback); |
| 2063 PrepareFrameState(store, bailout_id_after, | 2060 PrepareFrameState(store, bailout_id, OutputFrameStateCombine::Ignore()); |
| 2064 OutputFrameStateCombine::Ignore()); | |
| 2065 break; | 2061 break; |
| 2066 } | 2062 } |
| 2067 case NAMED_SUPER_PROPERTY: { | 2063 case NAMED_SUPER_PROPERTY: { |
| 2068 environment()->Push(value); | 2064 environment()->Push(value); |
| 2069 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | 2065 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
| 2070 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | 2066 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); |
| 2071 PrepareEagerCheckpoint(property->obj()->id()); | |
| 2072 Node* home_object = environment()->Pop(); | 2067 Node* home_object = environment()->Pop(); |
| 2073 Node* receiver = environment()->Pop(); | 2068 Node* receiver = environment()->Pop(); |
| 2074 value = environment()->Pop(); | 2069 value = environment()->Pop(); |
| 2075 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2070 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
| 2076 Node* store = BuildNamedSuperStore(receiver, home_object, name, value); | 2071 Node* store = BuildNamedSuperStore(receiver, home_object, name, value); |
| 2077 PrepareFrameState(store, bailout_id_after, | 2072 PrepareFrameState(store, bailout_id, OutputFrameStateCombine::Ignore()); |
| 2078 OutputFrameStateCombine::Ignore()); | |
| 2079 break; | 2073 break; |
| 2080 } | 2074 } |
| 2081 case KEYED_SUPER_PROPERTY: { | 2075 case KEYED_SUPER_PROPERTY: { |
| 2082 environment()->Push(value); | 2076 environment()->Push(value); |
| 2083 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | 2077 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
| 2084 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | 2078 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); |
| 2085 VisitForValue(property->key()); | 2079 VisitForValue(property->key()); |
| 2086 PrepareEagerCheckpoint(property->key()->id()); | |
| 2087 Node* key = environment()->Pop(); | 2080 Node* key = environment()->Pop(); |
| 2088 Node* home_object = environment()->Pop(); | 2081 Node* home_object = environment()->Pop(); |
| 2089 Node* receiver = environment()->Pop(); | 2082 Node* receiver = environment()->Pop(); |
| 2090 value = environment()->Pop(); | 2083 value = environment()->Pop(); |
| 2091 Node* store = BuildKeyedSuperStore(receiver, home_object, key, value); | 2084 Node* store = BuildKeyedSuperStore(receiver, home_object, key, value); |
| 2092 PrepareFrameState(store, bailout_id_after, | 2085 PrepareFrameState(store, bailout_id, OutputFrameStateCombine::Ignore()); |
| 2093 OutputFrameStateCombine::Ignore()); | |
| 2094 break; | 2086 break; |
| 2095 } | 2087 } |
| 2096 } | 2088 } |
| 2097 } | 2089 } |
| 2098 | 2090 |
| 2099 | 2091 |
| 2100 void AstGraphBuilder::VisitAssignment(Assignment* expr) { | 2092 void AstGraphBuilder::VisitAssignment(Assignment* expr) { |
| 2101 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); | 2093 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); |
| 2102 | 2094 |
| 2103 // Left-hand side can only be a property, a global or a variable slot. | 2095 // Left-hand side can only be a property, a global or a variable slot. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2127 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | 2119 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
| 2128 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | 2120 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); |
| 2129 break; | 2121 break; |
| 2130 case KEYED_SUPER_PROPERTY: | 2122 case KEYED_SUPER_PROPERTY: |
| 2131 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | 2123 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
| 2132 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | 2124 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); |
| 2133 VisitForValue(property->key()); | 2125 VisitForValue(property->key()); |
| 2134 break; | 2126 break; |
| 2135 } | 2127 } |
| 2136 | 2128 |
| 2137 BailoutId before_store_id = BailoutId::None(); | |
| 2138 // Evaluate the value and potentially handle compound assignments by loading | 2129 // Evaluate the value and potentially handle compound assignments by loading |
| 2139 // the left-hand side value and performing a binary operation. | 2130 // the left-hand side value and performing a binary operation. |
| 2140 if (expr->is_compound()) { | 2131 if (expr->is_compound()) { |
| 2141 Node* old_value = nullptr; | 2132 Node* old_value = nullptr; |
| 2142 switch (assign_type) { | 2133 switch (assign_type) { |
| 2143 case VARIABLE: { | 2134 case VARIABLE: { |
| 2144 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 2135 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
| 2145 VectorSlotPair pair = | 2136 VectorSlotPair pair = |
| 2146 CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 2137 CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
| 2147 PrepareEagerCheckpoint(BeforeId(proxy)); | 2138 PrepareEagerCheckpoint(BeforeId(proxy)); |
| 2148 old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair, | 2139 old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair, |
| 2149 OutputFrameStateCombine::Push()); | 2140 OutputFrameStateCombine::Push()); |
| 2150 break; | 2141 break; |
| 2151 } | 2142 } |
| 2152 case NAMED_PROPERTY: { | 2143 case NAMED_PROPERTY: { |
| 2153 Node* object = environment()->Top(); | 2144 Node* object = environment()->Top(); |
| 2154 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2145 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
| 2155 VectorSlotPair pair = | 2146 VectorSlotPair pair = |
| 2156 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2147 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
| 2157 PrepareEagerCheckpoint(property->obj()->id()); | |
| 2158 old_value = BuildNamedLoad(object, name, pair); | 2148 old_value = BuildNamedLoad(object, name, pair); |
| 2159 PrepareFrameState(old_value, property->LoadId(), | 2149 PrepareFrameState(old_value, property->LoadId(), |
| 2160 OutputFrameStateCombine::Push()); | 2150 OutputFrameStateCombine::Push()); |
| 2161 break; | 2151 break; |
| 2162 } | 2152 } |
| 2163 case KEYED_PROPERTY: { | 2153 case KEYED_PROPERTY: { |
| 2164 Node* key = environment()->Top(); | 2154 Node* key = environment()->Top(); |
| 2165 Node* object = environment()->Peek(1); | 2155 Node* object = environment()->Peek(1); |
| 2166 VectorSlotPair pair = | 2156 VectorSlotPair pair = |
| 2167 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2157 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
| 2168 PrepareEagerCheckpoint(property->key()->id()); | |
| 2169 old_value = BuildKeyedLoad(object, key, pair); | 2158 old_value = BuildKeyedLoad(object, key, pair); |
| 2170 PrepareFrameState(old_value, property->LoadId(), | 2159 PrepareFrameState(old_value, property->LoadId(), |
| 2171 OutputFrameStateCombine::Push()); | 2160 OutputFrameStateCombine::Push()); |
| 2172 break; | 2161 break; |
| 2173 } | 2162 } |
| 2174 case NAMED_SUPER_PROPERTY: { | 2163 case NAMED_SUPER_PROPERTY: { |
| 2175 Node* home_object = environment()->Top(); | 2164 Node* home_object = environment()->Top(); |
| 2176 Node* receiver = environment()->Peek(1); | 2165 Node* receiver = environment()->Peek(1); |
| 2177 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2166 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
| 2178 VectorSlotPair pair = | 2167 VectorSlotPair pair = |
| 2179 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2168 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
| 2180 PrepareEagerCheckpoint(property->obj()->id()); | |
| 2181 old_value = BuildNamedSuperLoad(receiver, home_object, name, pair); | 2169 old_value = BuildNamedSuperLoad(receiver, home_object, name, pair); |
| 2182 PrepareFrameState(old_value, property->LoadId(), | 2170 PrepareFrameState(old_value, property->LoadId(), |
| 2183 OutputFrameStateCombine::Push()); | 2171 OutputFrameStateCombine::Push()); |
| 2184 break; | 2172 break; |
| 2185 } | 2173 } |
| 2186 case KEYED_SUPER_PROPERTY: { | 2174 case KEYED_SUPER_PROPERTY: { |
| 2187 Node* key = environment()->Top(); | 2175 Node* key = environment()->Top(); |
| 2188 Node* home_object = environment()->Peek(1); | 2176 Node* home_object = environment()->Peek(1); |
| 2189 Node* receiver = environment()->Peek(2); | 2177 Node* receiver = environment()->Peek(2); |
| 2190 VectorSlotPair pair = | 2178 VectorSlotPair pair = |
| 2191 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2179 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
| 2192 PrepareEagerCheckpoint(property->key()->id()); | |
| 2193 old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair); | 2180 old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair); |
| 2194 PrepareFrameState(old_value, property->LoadId(), | 2181 PrepareFrameState(old_value, property->LoadId(), |
| 2195 OutputFrameStateCombine::Push()); | 2182 OutputFrameStateCombine::Push()); |
| 2196 break; | 2183 break; |
| 2197 } | 2184 } |
| 2198 } | 2185 } |
| 2199 environment()->Push(old_value); | 2186 environment()->Push(old_value); |
| 2200 VisitForValue(expr->value()); | 2187 VisitForValue(expr->value()); |
| 2201 Node* value; | 2188 Node* value; |
| 2202 { | 2189 { |
| 2203 FrameStateBeforeAndAfter states(this, expr->value()->id()); | 2190 FrameStateBeforeAndAfter states(this, expr->value()->id()); |
| 2204 Node* right = environment()->Pop(); | 2191 Node* right = environment()->Pop(); |
| 2205 Node* left = environment()->Pop(); | 2192 Node* left = environment()->Pop(); |
| 2206 value = | 2193 value = |
| 2207 BuildBinaryOp(left, right, expr->binary_op(), | 2194 BuildBinaryOp(left, right, expr->binary_op(), |
| 2208 expr->binary_operation()->BinaryOperationFeedbackId()); | 2195 expr->binary_operation()->BinaryOperationFeedbackId()); |
| 2209 states.AddToNode(value, expr->binary_operation()->id(), | 2196 states.AddToNode(value, expr->binary_operation()->id(), |
| 2210 OutputFrameStateCombine::Push()); | 2197 OutputFrameStateCombine::Push()); |
| 2211 } | 2198 } |
| 2212 environment()->Push(value); | 2199 environment()->Push(value); |
| 2213 if (needs_frame_state_before) { | 2200 if (needs_frame_state_before) { |
| 2214 before_store_id = expr->binary_operation()->id(); | 2201 PrepareEagerCheckpoint(expr->binary_operation()->id()); |
| 2215 } | 2202 } |
| 2216 } else { | 2203 } else { |
| 2217 VisitForValue(expr->value()); | 2204 VisitForValue(expr->value()); |
| 2218 if (needs_frame_state_before) { | |
| 2219 before_store_id = expr->value()->id(); | |
| 2220 } | |
| 2221 } | 2205 } |
| 2222 | 2206 |
| 2223 // Store the value. | 2207 // Store the value. |
| 2224 PrepareEagerCheckpoint(before_store_id); | |
| 2225 Node* value = environment()->Pop(); | 2208 Node* value = environment()->Pop(); |
| 2226 VectorSlotPair feedback = CreateVectorSlotPair(expr->AssignmentSlot()); | 2209 VectorSlotPair feedback = CreateVectorSlotPair(expr->AssignmentSlot()); |
| 2227 switch (assign_type) { | 2210 switch (assign_type) { |
| 2228 case VARIABLE: { | 2211 case VARIABLE: { |
| 2229 Variable* variable = expr->target()->AsVariableProxy()->var(); | 2212 Variable* variable = expr->target()->AsVariableProxy()->var(); |
| 2230 BuildVariableAssignment(variable, value, expr->op(), feedback, expr->id(), | 2213 BuildVariableAssignment(variable, value, expr->op(), feedback, expr->id(), |
| 2231 ast_context()->GetStateCombine()); | 2214 ast_context()->GetStateCombine()); |
| 2232 break; | 2215 break; |
| 2233 } | 2216 } |
| 2234 case NAMED_PROPERTY: { | 2217 case NAMED_PROPERTY: { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2256 case KEYED_SUPER_PROPERTY: { | 2239 case KEYED_SUPER_PROPERTY: { |
| 2257 Node* key = environment()->Pop(); | 2240 Node* key = environment()->Pop(); |
| 2258 Node* home_object = environment()->Pop(); | 2241 Node* home_object = environment()->Pop(); |
| 2259 Node* receiver = environment()->Pop(); | 2242 Node* receiver = environment()->Pop(); |
| 2260 Node* store = BuildKeyedSuperStore(receiver, home_object, key, value); | 2243 Node* store = BuildKeyedSuperStore(receiver, home_object, key, value); |
| 2261 PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine()); | 2244 PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine()); |
| 2262 break; | 2245 break; |
| 2263 } | 2246 } |
| 2264 } | 2247 } |
| 2265 | 2248 |
| 2266 ast_context()->ProduceValue(value); | 2249 ast_context()->ProduceValue(expr, value); |
| 2267 } | 2250 } |
| 2268 | 2251 |
| 2269 | 2252 |
| 2270 void AstGraphBuilder::VisitYield(Yield* expr) { | 2253 void AstGraphBuilder::VisitYield(Yield* expr) { |
| 2271 // Generator functions are supported only by going through Ignition first. | 2254 // Generator functions are supported only by going through Ignition first. |
| 2272 SetStackOverflow(); | 2255 SetStackOverflow(); |
| 2273 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); | 2256 ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant()); |
| 2274 } | 2257 } |
| 2275 | 2258 |
| 2276 | 2259 |
| 2277 void AstGraphBuilder::VisitThrow(Throw* expr) { | 2260 void AstGraphBuilder::VisitThrow(Throw* expr) { |
| 2278 VisitForValue(expr->exception()); | 2261 VisitForValue(expr->exception()); |
| 2279 Node* exception = environment()->Pop(); | 2262 Node* exception = environment()->Pop(); |
| 2280 Node* value = BuildThrowError(exception, expr->id()); | 2263 Node* value = BuildThrowError(exception, expr->id()); |
| 2281 ast_context()->ProduceValue(value); | 2264 ast_context()->ProduceValue(expr, value); |
| 2282 } | 2265 } |
| 2283 | 2266 |
| 2284 | 2267 |
| 2285 void AstGraphBuilder::VisitProperty(Property* expr) { | 2268 void AstGraphBuilder::VisitProperty(Property* expr) { |
| 2286 Node* value = nullptr; | 2269 Node* value = nullptr; |
| 2287 LhsKind property_kind = Property::GetAssignType(expr); | 2270 LhsKind property_kind = Property::GetAssignType(expr); |
| 2288 VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot()); | 2271 VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot()); |
| 2289 switch (property_kind) { | 2272 switch (property_kind) { |
| 2290 case VARIABLE: | 2273 case VARIABLE: |
| 2291 UNREACHABLE(); | 2274 UNREACHABLE(); |
| 2292 break; | 2275 break; |
| 2293 case NAMED_PROPERTY: { | 2276 case NAMED_PROPERTY: { |
| 2294 VisitForValue(expr->obj()); | 2277 VisitForValue(expr->obj()); |
| 2295 PrepareEagerCheckpoint(expr->obj()->id()); | |
| 2296 Node* object = environment()->Pop(); | 2278 Node* object = environment()->Pop(); |
| 2297 Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); | 2279 Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); |
| 2298 value = BuildNamedLoad(object, name, pair); | 2280 value = BuildNamedLoad(object, name, pair); |
| 2299 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2281 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 2300 break; | 2282 break; |
| 2301 } | 2283 } |
| 2302 case KEYED_PROPERTY: { | 2284 case KEYED_PROPERTY: { |
| 2303 VisitForValue(expr->obj()); | 2285 VisitForValue(expr->obj()); |
| 2304 VisitForValue(expr->key()); | 2286 VisitForValue(expr->key()); |
| 2305 PrepareEagerCheckpoint(expr->key()->id()); | |
| 2306 Node* key = environment()->Pop(); | 2287 Node* key = environment()->Pop(); |
| 2307 Node* object = environment()->Pop(); | 2288 Node* object = environment()->Pop(); |
| 2308 value = BuildKeyedLoad(object, key, pair); | 2289 value = BuildKeyedLoad(object, key, pair); |
| 2309 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2290 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 2310 break; | 2291 break; |
| 2311 } | 2292 } |
| 2312 case NAMED_SUPER_PROPERTY: { | 2293 case NAMED_SUPER_PROPERTY: { |
| 2313 VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2294 VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
| 2314 VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object()); | 2295 VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object()); |
| 2315 PrepareEagerCheckpoint(expr->obj()->id()); | |
| 2316 Node* home_object = environment()->Pop(); | 2296 Node* home_object = environment()->Pop(); |
| 2317 Node* receiver = environment()->Pop(); | 2297 Node* receiver = environment()->Pop(); |
| 2318 Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); | 2298 Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); |
| 2319 value = BuildNamedSuperLoad(receiver, home_object, name, pair); | 2299 value = BuildNamedSuperLoad(receiver, home_object, name, pair); |
| 2320 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2300 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 2321 break; | 2301 break; |
| 2322 } | 2302 } |
| 2323 case KEYED_SUPER_PROPERTY: { | 2303 case KEYED_SUPER_PROPERTY: { |
| 2324 VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2304 VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
| 2325 VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object()); | 2305 VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object()); |
| 2326 VisitForValue(expr->key()); | 2306 VisitForValue(expr->key()); |
| 2327 PrepareEagerCheckpoint(expr->key()->id()); | |
| 2328 Node* key = environment()->Pop(); | 2307 Node* key = environment()->Pop(); |
| 2329 Node* home_object = environment()->Pop(); | 2308 Node* home_object = environment()->Pop(); |
| 2330 Node* receiver = environment()->Pop(); | 2309 Node* receiver = environment()->Pop(); |
| 2331 value = BuildKeyedSuperLoad(receiver, home_object, key, pair); | 2310 value = BuildKeyedSuperLoad(receiver, home_object, key, pair); |
| 2332 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2311 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 2333 break; | 2312 break; |
| 2334 } | 2313 } |
| 2335 } | 2314 } |
| 2336 ast_context()->ProduceValue(value); | 2315 ast_context()->ProduceValue(expr, value); |
| 2337 } | 2316 } |
| 2338 | 2317 |
| 2339 | 2318 |
| 2340 void AstGraphBuilder::VisitCall(Call* expr) { | 2319 void AstGraphBuilder::VisitCall(Call* expr) { |
| 2341 Expression* callee = expr->expression(); | 2320 Expression* callee = expr->expression(); |
| 2342 Call::CallType call_type = expr->GetCallType(isolate()); | 2321 Call::CallType call_type = expr->GetCallType(isolate()); |
| 2343 | 2322 |
| 2344 // Prepare the callee and the receiver to the function call. This depends on | 2323 // Prepare the callee and the receiver to the function call. This depends on |
| 2345 // the semantics of the underlying call type. | 2324 // the semantics of the underlying call type. |
| 2346 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; | 2325 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2369 receiver_value = NewNode(common()->Projection(1), pair); | 2348 receiver_value = NewNode(common()->Projection(1), pair); |
| 2370 PrepareFrameState(pair, expr->LookupId(), | 2349 PrepareFrameState(pair, expr->LookupId(), |
| 2371 OutputFrameStateCombine::Push(2)); | 2350 OutputFrameStateCombine::Push(2)); |
| 2372 break; | 2351 break; |
| 2373 } | 2352 } |
| 2374 case Call::NAMED_PROPERTY_CALL: { | 2353 case Call::NAMED_PROPERTY_CALL: { |
| 2375 Property* property = callee->AsProperty(); | 2354 Property* property = callee->AsProperty(); |
| 2376 VectorSlotPair feedback = | 2355 VectorSlotPair feedback = |
| 2377 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2356 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
| 2378 VisitForValue(property->obj()); | 2357 VisitForValue(property->obj()); |
| 2379 PrepareEagerCheckpoint(property->obj()->id()); | |
| 2380 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2358 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
| 2381 Node* object = environment()->Top(); | 2359 Node* object = environment()->Top(); |
| 2382 callee_value = BuildNamedLoad(object, name, feedback); | 2360 callee_value = BuildNamedLoad(object, name, feedback); |
| 2383 PrepareFrameState(callee_value, property->LoadId(), | 2361 PrepareFrameState(callee_value, property->LoadId(), |
| 2384 OutputFrameStateCombine::Push()); | 2362 OutputFrameStateCombine::Push()); |
| 2385 // Note that a property call requires the receiver to be wrapped into | 2363 // Note that a property call requires the receiver to be wrapped into |
| 2386 // an object for sloppy callees. However the receiver is guaranteed | 2364 // an object for sloppy callees. However the receiver is guaranteed |
| 2387 // not to be null or undefined at this point. | 2365 // not to be null or undefined at this point. |
| 2388 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined; | 2366 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined; |
| 2389 receiver_value = environment()->Pop(); | 2367 receiver_value = environment()->Pop(); |
| 2390 break; | 2368 break; |
| 2391 } | 2369 } |
| 2392 case Call::KEYED_PROPERTY_CALL: { | 2370 case Call::KEYED_PROPERTY_CALL: { |
| 2393 Property* property = callee->AsProperty(); | 2371 Property* property = callee->AsProperty(); |
| 2394 VectorSlotPair feedback = | 2372 VectorSlotPair feedback = |
| 2395 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2373 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
| 2396 VisitForValue(property->obj()); | 2374 VisitForValue(property->obj()); |
| 2397 VisitForValue(property->key()); | 2375 VisitForValue(property->key()); |
| 2398 PrepareEagerCheckpoint(property->key()->id()); | |
| 2399 Node* key = environment()->Pop(); | 2376 Node* key = environment()->Pop(); |
| 2400 Node* object = environment()->Top(); | 2377 Node* object = environment()->Top(); |
| 2401 callee_value = BuildKeyedLoad(object, key, feedback); | 2378 callee_value = BuildKeyedLoad(object, key, feedback); |
| 2402 PrepareFrameState(callee_value, property->LoadId(), | 2379 PrepareFrameState(callee_value, property->LoadId(), |
| 2403 OutputFrameStateCombine::Push()); | 2380 OutputFrameStateCombine::Push()); |
| 2404 // Note that a property call requires the receiver to be wrapped into | 2381 // Note that a property call requires the receiver to be wrapped into |
| 2405 // an object for sloppy callees. However the receiver is guaranteed | 2382 // an object for sloppy callees. However the receiver is guaranteed |
| 2406 // not to be null or undefined at this point. | 2383 // not to be null or undefined at this point. |
| 2407 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined; | 2384 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined; |
| 2408 receiver_value = environment()->Pop(); | 2385 receiver_value = environment()->Pop(); |
| 2409 break; | 2386 break; |
| 2410 } | 2387 } |
| 2411 case Call::NAMED_SUPER_PROPERTY_CALL: { | 2388 case Call::NAMED_SUPER_PROPERTY_CALL: { |
| 2412 Property* property = callee->AsProperty(); | 2389 Property* property = callee->AsProperty(); |
| 2413 SuperPropertyReference* super_ref = | 2390 SuperPropertyReference* super_ref = |
| 2414 property->obj()->AsSuperPropertyReference(); | 2391 property->obj()->AsSuperPropertyReference(); |
| 2415 VisitForValue(super_ref->home_object()); | 2392 VisitForValue(super_ref->home_object()); |
| 2416 VisitForValue(super_ref->this_var()); | 2393 VisitForValue(super_ref->this_var()); |
| 2417 Node* home = environment()->Peek(1); | 2394 Node* home = environment()->Peek(1); |
| 2418 Node* object = environment()->Top(); | 2395 Node* object = environment()->Top(); |
| 2419 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2396 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
| 2420 PrepareEagerCheckpoint(property->obj()->id()); | |
| 2421 callee_value = BuildNamedSuperLoad(object, home, name, VectorSlotPair()); | 2397 callee_value = BuildNamedSuperLoad(object, home, name, VectorSlotPair()); |
| 2422 PrepareFrameState(callee_value, property->LoadId(), | 2398 PrepareFrameState(callee_value, property->LoadId(), |
| 2423 OutputFrameStateCombine::Push()); | 2399 OutputFrameStateCombine::Push()); |
| 2424 // Note that a property call requires the receiver to be wrapped into | 2400 // Note that a property call requires the receiver to be wrapped into |
| 2425 // an object for sloppy callees. Since the receiver is not the target of | 2401 // an object for sloppy callees. Since the receiver is not the target of |
| 2426 // the load, it could very well be null or undefined at this point. | 2402 // the load, it could very well be null or undefined at this point. |
| 2427 receiver_value = environment()->Pop(); | 2403 receiver_value = environment()->Pop(); |
| 2428 environment()->Drop(1); | 2404 environment()->Drop(1); |
| 2429 break; | 2405 break; |
| 2430 } | 2406 } |
| 2431 case Call::KEYED_SUPER_PROPERTY_CALL: { | 2407 case Call::KEYED_SUPER_PROPERTY_CALL: { |
| 2432 Property* property = callee->AsProperty(); | 2408 Property* property = callee->AsProperty(); |
| 2433 SuperPropertyReference* super_ref = | 2409 SuperPropertyReference* super_ref = |
| 2434 property->obj()->AsSuperPropertyReference(); | 2410 property->obj()->AsSuperPropertyReference(); |
| 2435 VisitForValue(super_ref->home_object()); | 2411 VisitForValue(super_ref->home_object()); |
| 2436 VisitForValue(super_ref->this_var()); | 2412 VisitForValue(super_ref->this_var()); |
| 2437 environment()->Push(environment()->Top()); // Duplicate this_var. | 2413 environment()->Push(environment()->Top()); // Duplicate this_var. |
| 2438 environment()->Push(environment()->Peek(2)); // Duplicate home_obj. | 2414 environment()->Push(environment()->Peek(2)); // Duplicate home_obj. |
| 2439 VisitForValue(property->key()); | 2415 VisitForValue(property->key()); |
| 2440 Node* key = environment()->Pop(); | 2416 Node* key = environment()->Pop(); |
| 2441 Node* home = environment()->Pop(); | 2417 Node* home = environment()->Pop(); |
| 2442 Node* object = environment()->Pop(); | 2418 Node* object = environment()->Pop(); |
| 2443 PrepareEagerCheckpoint(property->key()->id()); | |
| 2444 callee_value = BuildKeyedSuperLoad(object, home, key, VectorSlotPair()); | 2419 callee_value = BuildKeyedSuperLoad(object, home, key, VectorSlotPair()); |
| 2445 PrepareFrameState(callee_value, property->LoadId(), | 2420 PrepareFrameState(callee_value, property->LoadId(), |
| 2446 OutputFrameStateCombine::Push()); | 2421 OutputFrameStateCombine::Push()); |
| 2447 // Note that a property call requires the receiver to be wrapped into | 2422 // Note that a property call requires the receiver to be wrapped into |
| 2448 // an object for sloppy callees. Since the receiver is not the target of | 2423 // an object for sloppy callees. Since the receiver is not the target of |
| 2449 // the load, it could very well be null or undefined at this point. | 2424 // the load, it could very well be null or undefined at this point. |
| 2450 receiver_value = environment()->Pop(); | 2425 receiver_value = environment()->Pop(); |
| 2451 environment()->Drop(1); | 2426 environment()->Drop(1); |
| 2452 break; | 2427 break; |
| 2453 } | 2428 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2509 OutputFrameStateCombine::PokeAt(arg_count + 1)); | 2484 OutputFrameStateCombine::PokeAt(arg_count + 1)); |
| 2510 | 2485 |
| 2511 // Patch callee on the environment. | 2486 // Patch callee on the environment. |
| 2512 environment()->Poke(arg_count + 1, new_callee); | 2487 environment()->Poke(arg_count + 1, new_callee); |
| 2513 } | 2488 } |
| 2514 | 2489 |
| 2515 // Create node to perform the function call. | 2490 // Create node to perform the function call. |
| 2516 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot()); | 2491 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot()); |
| 2517 const Operator* call = javascript()->CallFunction( | 2492 const Operator* call = javascript()->CallFunction( |
| 2518 args->length() + 2, feedback, receiver_hint, expr->tail_call_mode()); | 2493 args->length() + 2, feedback, receiver_hint, expr->tail_call_mode()); |
| 2519 PrepareEagerCheckpoint(expr->CallId()); | 2494 PrepareEagerCheckpoint(possibly_eval ? expr->EvalId() : expr->CallId()); |
| 2520 Node* value = ProcessArguments(call, args->length() + 2); | 2495 Node* value = ProcessArguments(call, args->length() + 2); |
| 2521 environment()->Push(value->InputAt(0)); // The callee passed to the call. | 2496 environment()->Push(value->InputAt(0)); // The callee passed to the call. |
| 2522 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); | 2497 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); |
| 2523 environment()->Drop(1); | 2498 environment()->Drop(1); |
| 2524 ast_context()->ProduceValue(value); | 2499 ast_context()->ProduceValue(expr, value); |
| 2525 } | 2500 } |
| 2526 | 2501 |
| 2527 | 2502 |
| 2528 void AstGraphBuilder::VisitCallSuper(Call* expr) { | 2503 void AstGraphBuilder::VisitCallSuper(Call* expr) { |
| 2529 SuperCallReference* super = expr->expression()->AsSuperCallReference(); | 2504 SuperCallReference* super = expr->expression()->AsSuperCallReference(); |
| 2530 DCHECK_NOT_NULL(super); | 2505 DCHECK_NOT_NULL(super); |
| 2531 | 2506 |
| 2532 // Prepare the callee to the super call. | 2507 // Prepare the callee to the super call. |
| 2533 VisitForValue(super->this_function_var()); | 2508 VisitForValue(super->this_function_var()); |
| 2534 Node* this_function = environment()->Pop(); | 2509 Node* this_function = environment()->Pop(); |
| 2535 const Operator* op = | 2510 const Operator* op = |
| 2536 javascript()->CallRuntime(Runtime::kInlineGetSuperConstructor, 1); | 2511 javascript()->CallRuntime(Runtime::kInlineGetSuperConstructor, 1); |
| 2537 Node* super_function = NewNode(op, this_function); | 2512 Node* super_function = NewNode(op, this_function); |
| 2538 environment()->Push(super_function); | 2513 environment()->Push(super_function); |
| 2539 | 2514 |
| 2540 // Evaluate all arguments to the super call. | 2515 // Evaluate all arguments to the super call. |
| 2541 ZoneList<Expression*>* args = expr->arguments(); | 2516 ZoneList<Expression*>* args = expr->arguments(); |
| 2542 VisitForValues(args); | 2517 VisitForValues(args); |
| 2543 | 2518 |
| 2544 // The new target is loaded from the {new.target} variable. | 2519 // The new target is loaded from the {new.target} variable. |
| 2545 VisitForValue(super->new_target_var()); | 2520 VisitForValue(super->new_target_var()); |
| 2546 | 2521 |
| 2547 // Create node to perform the super call. | 2522 // Create node to perform the super call. |
| 2548 const Operator* call = | 2523 const Operator* call = |
| 2549 javascript()->CallConstruct(args->length() + 2, VectorSlotPair()); | 2524 javascript()->CallConstruct(args->length() + 2, VectorSlotPair()); |
| 2550 PrepareEagerCheckpoint(super->new_target_var()->id()); | |
| 2551 Node* value = ProcessArguments(call, args->length() + 2); | 2525 Node* value = ProcessArguments(call, args->length() + 2); |
| 2552 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); | 2526 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); |
| 2553 ast_context()->ProduceValue(value); | 2527 ast_context()->ProduceValue(expr, value); |
| 2554 } | 2528 } |
| 2555 | 2529 |
| 2556 | 2530 |
| 2557 void AstGraphBuilder::VisitCallNew(CallNew* expr) { | 2531 void AstGraphBuilder::VisitCallNew(CallNew* expr) { |
| 2558 VisitForValue(expr->expression()); | 2532 VisitForValue(expr->expression()); |
| 2559 | 2533 |
| 2560 // Evaluate all arguments to the construct call. | 2534 // Evaluate all arguments to the construct call. |
| 2561 ZoneList<Expression*>* args = expr->arguments(); | 2535 ZoneList<Expression*>* args = expr->arguments(); |
| 2562 VisitForValues(args); | 2536 VisitForValues(args); |
| 2563 | 2537 |
| 2564 // The baseline compiler doesn't push the new.target, so we need to record | |
| 2565 // the frame state before the push. | |
| 2566 PrepareEagerCheckpoint(args->is_empty() ? expr->expression()->id() | |
| 2567 : args->last()->id()); | |
| 2568 | |
| 2569 // The new target is the same as the callee. | 2538 // The new target is the same as the callee. |
| 2570 environment()->Push(environment()->Peek(args->length())); | 2539 environment()->Push(environment()->Peek(args->length())); |
| 2571 | 2540 |
| 2572 // Create node to perform the construct call. | 2541 // Create node to perform the construct call. |
| 2573 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallNewFeedbackSlot()); | 2542 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallNewFeedbackSlot()); |
| 2574 const Operator* call = | 2543 const Operator* call = |
| 2575 javascript()->CallConstruct(args->length() + 2, feedback); | 2544 javascript()->CallConstruct(args->length() + 2, feedback); |
| 2576 Node* value = ProcessArguments(call, args->length() + 2); | 2545 Node* value = ProcessArguments(call, args->length() + 2); |
| 2577 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); | 2546 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); |
| 2578 ast_context()->ProduceValue(value); | 2547 ast_context()->ProduceValue(expr, value); |
| 2579 } | 2548 } |
| 2580 | 2549 |
| 2581 | 2550 |
| 2582 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { | 2551 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { |
| 2583 // The callee and the receiver both have to be pushed onto the operand stack | 2552 // The callee and the receiver both have to be pushed onto the operand stack |
| 2584 // before arguments are being evaluated. | 2553 // before arguments are being evaluated. |
| 2585 Node* callee_value = BuildLoadNativeContextField(expr->context_index()); | 2554 Node* callee_value = BuildLoadNativeContextField(expr->context_index()); |
| 2586 Node* receiver_value = jsgraph()->UndefinedConstant(); | 2555 Node* receiver_value = jsgraph()->UndefinedConstant(); |
| 2587 | 2556 |
| 2588 environment()->Push(callee_value); | 2557 environment()->Push(callee_value); |
| 2589 environment()->Push(receiver_value); | 2558 environment()->Push(receiver_value); |
| 2590 | 2559 |
| 2591 // Evaluate all arguments to the JS runtime call. | 2560 // Evaluate all arguments to the JS runtime call. |
| 2592 ZoneList<Expression*>* args = expr->arguments(); | 2561 ZoneList<Expression*>* args = expr->arguments(); |
| 2593 VisitForValues(args); | 2562 VisitForValues(args); |
| 2594 | 2563 |
| 2595 // Create node to perform the JS runtime call. | 2564 // Create node to perform the JS runtime call. |
| 2596 const Operator* call = javascript()->CallFunction(args->length() + 2); | 2565 const Operator* call = javascript()->CallFunction(args->length() + 2); |
| 2597 PrepareEagerCheckpoint(expr->CallId()); | 2566 PrepareEagerCheckpoint(expr->CallId()); |
| 2598 Node* value = ProcessArguments(call, args->length() + 2); | 2567 Node* value = ProcessArguments(call, args->length() + 2); |
| 2599 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2568 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 2600 ast_context()->ProduceValue(value); | 2569 ast_context()->ProduceValue(expr, value); |
| 2601 } | 2570 } |
| 2602 | 2571 |
| 2603 | 2572 |
| 2604 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | 2573 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
| 2605 // Handle calls to runtime functions implemented in JavaScript separately as | 2574 // Handle calls to runtime functions implemented in JavaScript separately as |
| 2606 // the call follows JavaScript ABI and the callee is statically unknown. | 2575 // the call follows JavaScript ABI and the callee is statically unknown. |
| 2607 if (expr->is_jsruntime()) { | 2576 if (expr->is_jsruntime()) { |
| 2608 return VisitCallJSRuntime(expr); | 2577 return VisitCallJSRuntime(expr); |
| 2609 } | 2578 } |
| 2610 | 2579 |
| 2611 // Evaluate all arguments to the runtime call. | 2580 // Evaluate all arguments to the runtime call. |
| 2612 ZoneList<Expression*>* args = expr->arguments(); | 2581 ZoneList<Expression*>* args = expr->arguments(); |
| 2613 VisitForValues(args); | 2582 VisitForValues(args); |
| 2614 | 2583 |
| 2615 // Create node to perform the runtime call. | 2584 // Create node to perform the runtime call. |
| 2616 Runtime::FunctionId functionId = expr->function()->function_id; | 2585 Runtime::FunctionId functionId = expr->function()->function_id; |
| 2617 const Operator* call = javascript()->CallRuntime(functionId, args->length()); | 2586 const Operator* call = javascript()->CallRuntime(functionId, args->length()); |
| 2618 PrepareEagerCheckpoint(expr->CallId()); | 2587 if (expr->function()->intrinsic_type == Runtime::IntrinsicType::RUNTIME || |
| 2588 expr->function()->function_id == Runtime::kInlineCall) { |
| 2589 PrepareEagerCheckpoint(expr->CallId()); |
| 2590 } |
| 2619 Node* value = ProcessArguments(call, args->length()); | 2591 Node* value = ProcessArguments(call, args->length()); |
| 2620 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2592 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 2621 ast_context()->ProduceValue(value); | 2593 ast_context()->ProduceValue(expr, value); |
| 2622 } | 2594 } |
| 2623 | 2595 |
| 2624 | 2596 |
| 2625 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { | 2597 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { |
| 2626 switch (expr->op()) { | 2598 switch (expr->op()) { |
| 2627 case Token::DELETE: | 2599 case Token::DELETE: |
| 2628 return VisitDelete(expr); | 2600 return VisitDelete(expr); |
| 2629 case Token::VOID: | 2601 case Token::VOID: |
| 2630 return VisitVoid(expr); | 2602 return VisitVoid(expr); |
| 2631 case Token::TYPEOF: | 2603 case Token::TYPEOF: |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2659 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 2631 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 2660 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 2632 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
| 2661 PrepareEagerCheckpoint(BeforeId(proxy)); | 2633 PrepareEagerCheckpoint(BeforeId(proxy)); |
| 2662 old_value = BuildVariableLoad(proxy->var(), expr->expression()->id(), | 2634 old_value = BuildVariableLoad(proxy->var(), expr->expression()->id(), |
| 2663 pair, OutputFrameStateCombine::Push()); | 2635 pair, OutputFrameStateCombine::Push()); |
| 2664 stack_depth = 0; | 2636 stack_depth = 0; |
| 2665 break; | 2637 break; |
| 2666 } | 2638 } |
| 2667 case NAMED_PROPERTY: { | 2639 case NAMED_PROPERTY: { |
| 2668 VisitForValue(property->obj()); | 2640 VisitForValue(property->obj()); |
| 2669 PrepareEagerCheckpoint(property->obj()->id()); | |
| 2670 Node* object = environment()->Top(); | 2641 Node* object = environment()->Top(); |
| 2671 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2642 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
| 2672 VectorSlotPair pair = | 2643 VectorSlotPair pair = |
| 2673 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2644 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
| 2674 old_value = BuildNamedLoad(object, name, pair); | 2645 old_value = BuildNamedLoad(object, name, pair); |
| 2675 PrepareFrameState(old_value, property->LoadId(), | 2646 PrepareFrameState(old_value, property->LoadId(), |
| 2676 OutputFrameStateCombine::Push()); | 2647 OutputFrameStateCombine::Push()); |
| 2677 stack_depth = 1; | 2648 stack_depth = 1; |
| 2678 break; | 2649 break; |
| 2679 } | 2650 } |
| 2680 case KEYED_PROPERTY: { | 2651 case KEYED_PROPERTY: { |
| 2681 VisitForValue(property->obj()); | 2652 VisitForValue(property->obj()); |
| 2682 VisitForValue(property->key()); | 2653 VisitForValue(property->key()); |
| 2683 PrepareEagerCheckpoint(property->key()->id()); | |
| 2684 Node* key = environment()->Top(); | 2654 Node* key = environment()->Top(); |
| 2685 Node* object = environment()->Peek(1); | 2655 Node* object = environment()->Peek(1); |
| 2686 VectorSlotPair pair = | 2656 VectorSlotPair pair = |
| 2687 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2657 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
| 2688 old_value = BuildKeyedLoad(object, key, pair); | 2658 old_value = BuildKeyedLoad(object, key, pair); |
| 2689 PrepareFrameState(old_value, property->LoadId(), | 2659 PrepareFrameState(old_value, property->LoadId(), |
| 2690 OutputFrameStateCombine::Push()); | 2660 OutputFrameStateCombine::Push()); |
| 2691 stack_depth = 2; | 2661 stack_depth = 2; |
| 2692 break; | 2662 break; |
| 2693 } | 2663 } |
| 2694 case NAMED_SUPER_PROPERTY: { | 2664 case NAMED_SUPER_PROPERTY: { |
| 2695 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | 2665 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
| 2696 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | 2666 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); |
| 2697 PrepareEagerCheckpoint(property->obj()->id()); | |
| 2698 Node* home_object = environment()->Top(); | 2667 Node* home_object = environment()->Top(); |
| 2699 Node* receiver = environment()->Peek(1); | 2668 Node* receiver = environment()->Peek(1); |
| 2700 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2669 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
| 2701 VectorSlotPair pair = | 2670 VectorSlotPair pair = |
| 2702 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2671 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
| 2703 old_value = BuildNamedSuperLoad(receiver, home_object, name, pair); | 2672 old_value = BuildNamedSuperLoad(receiver, home_object, name, pair); |
| 2704 PrepareFrameState(old_value, property->LoadId(), | 2673 PrepareFrameState(old_value, property->LoadId(), |
| 2705 OutputFrameStateCombine::Push()); | 2674 OutputFrameStateCombine::Push()); |
| 2706 stack_depth = 2; | 2675 stack_depth = 2; |
| 2707 break; | 2676 break; |
| 2708 } | 2677 } |
| 2709 case KEYED_SUPER_PROPERTY: { | 2678 case KEYED_SUPER_PROPERTY: { |
| 2710 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | 2679 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
| 2711 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | 2680 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); |
| 2712 VisitForValue(property->key()); | 2681 VisitForValue(property->key()); |
| 2713 PrepareEagerCheckpoint(property->obj()->id()); | |
| 2714 Node* key = environment()->Top(); | 2682 Node* key = environment()->Top(); |
| 2715 Node* home_object = environment()->Peek(1); | 2683 Node* home_object = environment()->Peek(1); |
| 2716 Node* receiver = environment()->Peek(2); | 2684 Node* receiver = environment()->Peek(2); |
| 2717 VectorSlotPair pair = | 2685 VectorSlotPair pair = |
| 2718 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2686 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
| 2719 old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair); | 2687 old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair); |
| 2720 PrepareFrameState(old_value, property->LoadId(), | 2688 PrepareFrameState(old_value, property->LoadId(), |
| 2721 OutputFrameStateCombine::Push()); | 2689 OutputFrameStateCombine::Push()); |
| 2722 stack_depth = 3; | 2690 stack_depth = 3; |
| 2723 break; | 2691 break; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2802 PrepareFrameState(store, expr->AssignmentId(), | 2770 PrepareFrameState(store, expr->AssignmentId(), |
| 2803 OutputFrameStateCombine::Ignore()); | 2771 OutputFrameStateCombine::Ignore()); |
| 2804 environment()->Pop(); | 2772 environment()->Pop(); |
| 2805 break; | 2773 break; |
| 2806 } | 2774 } |
| 2807 } | 2775 } |
| 2808 | 2776 |
| 2809 // Restore old value for postfix expressions. | 2777 // Restore old value for postfix expressions. |
| 2810 if (is_postfix) value = environment()->Pop(); | 2778 if (is_postfix) value = environment()->Pop(); |
| 2811 | 2779 |
| 2812 ast_context()->ProduceValue(value); | 2780 ast_context()->ProduceValue(expr, value); |
| 2813 } | 2781 } |
| 2814 | 2782 |
| 2815 | 2783 |
| 2816 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { | 2784 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { |
| 2817 switch (expr->op()) { | 2785 switch (expr->op()) { |
| 2818 case Token::COMMA: | 2786 case Token::COMMA: |
| 2819 return VisitComma(expr); | 2787 return VisitComma(expr); |
| 2820 case Token::OR: | 2788 case Token::OR: |
| 2821 case Token::AND: | 2789 case Token::AND: |
| 2822 return VisitLogicalExpression(expr); | 2790 return VisitLogicalExpression(expr); |
| 2823 default: { | 2791 default: { |
| 2824 VisitForValue(expr->left()); | 2792 VisitForValue(expr->left()); |
| 2825 VisitForValue(expr->right()); | 2793 VisitForValue(expr->right()); |
| 2826 FrameStateBeforeAndAfter states(this, expr->right()->id()); | 2794 FrameStateBeforeAndAfter states(this, expr->right()->id()); |
| 2827 Node* right = environment()->Pop(); | 2795 Node* right = environment()->Pop(); |
| 2828 Node* left = environment()->Pop(); | 2796 Node* left = environment()->Pop(); |
| 2829 Node* value = BuildBinaryOp(left, right, expr->op(), | 2797 Node* value = BuildBinaryOp(left, right, expr->op(), |
| 2830 expr->BinaryOperationFeedbackId()); | 2798 expr->BinaryOperationFeedbackId()); |
| 2831 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); | 2799 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); |
| 2832 ast_context()->ProduceValue(value); | 2800 ast_context()->ProduceValue(expr, value); |
| 2833 } | 2801 } |
| 2834 } | 2802 } |
| 2835 } | 2803 } |
| 2836 | 2804 |
| 2837 void AstGraphBuilder::VisitLiteralCompareNil(CompareOperation* expr, | 2805 void AstGraphBuilder::VisitLiteralCompareNil(CompareOperation* expr, |
| 2838 Expression* sub_expr, | 2806 Expression* sub_expr, |
| 2839 Node* nil_value) { | 2807 Node* nil_value) { |
| 2840 const Operator* op = nullptr; | 2808 const Operator* op = nullptr; |
| 2841 switch (expr->op()) { | 2809 switch (expr->op()) { |
| 2842 case Token::EQ: | 2810 case Token::EQ: |
| 2843 op = javascript()->Equal(CompareOperationHints::Any()); | 2811 op = javascript()->Equal(CompareOperationHints::Any()); |
| 2844 break; | 2812 break; |
| 2845 case Token::EQ_STRICT: | 2813 case Token::EQ_STRICT: |
| 2846 op = javascript()->StrictEqual(CompareOperationHints::Any()); | 2814 op = javascript()->StrictEqual(CompareOperationHints::Any()); |
| 2847 break; | 2815 break; |
| 2848 default: | 2816 default: |
| 2849 UNREACHABLE(); | 2817 UNREACHABLE(); |
| 2850 } | 2818 } |
| 2851 VisitForValue(sub_expr); | 2819 VisitForValue(sub_expr); |
| 2852 PrepareEagerCheckpoint(sub_expr->id()); | |
| 2853 Node* value_to_compare = environment()->Pop(); | 2820 Node* value_to_compare = environment()->Pop(); |
| 2854 Node* value = NewNode(op, value_to_compare, nil_value); | 2821 Node* value = NewNode(op, value_to_compare, nil_value); |
| 2855 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2822 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 2856 return ast_context()->ProduceValue(value); | 2823 return ast_context()->ProduceValue(expr, value); |
| 2857 } | 2824 } |
| 2858 | 2825 |
| 2859 void AstGraphBuilder::VisitLiteralCompareTypeof(CompareOperation* expr, | 2826 void AstGraphBuilder::VisitLiteralCompareTypeof(CompareOperation* expr, |
| 2860 Expression* sub_expr, | 2827 Expression* sub_expr, |
| 2861 Handle<String> check) { | 2828 Handle<String> check) { |
| 2862 VisitTypeofExpression(sub_expr); | 2829 VisitTypeofExpression(sub_expr); |
| 2863 PrepareEagerCheckpoint(sub_expr->id()); | |
| 2864 Node* typeof_arg = NewNode(javascript()->TypeOf(), environment()->Pop()); | 2830 Node* typeof_arg = NewNode(javascript()->TypeOf(), environment()->Pop()); |
| 2865 Node* value = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), | 2831 Node* value = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), |
| 2866 typeof_arg, jsgraph()->Constant(check)); | 2832 typeof_arg, jsgraph()->Constant(check)); |
| 2867 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2833 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 2868 return ast_context()->ProduceValue(value); | 2834 return ast_context()->ProduceValue(expr, value); |
| 2869 } | 2835 } |
| 2870 | 2836 |
| 2871 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { | 2837 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
| 2872 // Check for a few fast cases. The AST visiting behavior must be in sync | 2838 // Check for a few fast cases. The AST visiting behavior must be in sync |
| 2873 // with the full codegen: We don't push both left and right values onto | 2839 // with the full codegen: We don't push both left and right values onto |
| 2874 // the expression stack when one side is a special-case literal. | 2840 // the expression stack when one side is a special-case literal. |
| 2875 Expression* sub_expr = nullptr; | 2841 Expression* sub_expr = nullptr; |
| 2876 Handle<String> check; | 2842 Handle<String> check; |
| 2877 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { | 2843 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { |
| 2878 return VisitLiteralCompareTypeof(expr, sub_expr, check); | 2844 return VisitLiteralCompareTypeof(expr, sub_expr, check); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2928 op = nullptr; | 2894 op = nullptr; |
| 2929 UNREACHABLE(); | 2895 UNREACHABLE(); |
| 2930 } | 2896 } |
| 2931 VisitForValue(expr->left()); | 2897 VisitForValue(expr->left()); |
| 2932 VisitForValue(expr->right()); | 2898 VisitForValue(expr->right()); |
| 2933 FrameStateBeforeAndAfter states(this, expr->right()->id()); | 2899 FrameStateBeforeAndAfter states(this, expr->right()->id()); |
| 2934 Node* right = environment()->Pop(); | 2900 Node* right = environment()->Pop(); |
| 2935 Node* left = environment()->Pop(); | 2901 Node* left = environment()->Pop(); |
| 2936 Node* value = NewNode(op, left, right); | 2902 Node* value = NewNode(op, left, right); |
| 2937 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); | 2903 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); |
| 2938 ast_context()->ProduceValue(value); | 2904 ast_context()->ProduceValue(expr, value); |
| 2939 } | 2905 } |
| 2940 | 2906 |
| 2941 | 2907 |
| 2942 void AstGraphBuilder::VisitSpread(Spread* expr) { | 2908 void AstGraphBuilder::VisitSpread(Spread* expr) { |
| 2943 // Handled entirely by the parser itself. | 2909 // Handled entirely by the parser itself. |
| 2944 UNREACHABLE(); | 2910 UNREACHABLE(); |
| 2945 } | 2911 } |
| 2946 | 2912 |
| 2947 | 2913 |
| 2948 void AstGraphBuilder::VisitEmptyParentheses(EmptyParentheses* expr) { | 2914 void AstGraphBuilder::VisitEmptyParentheses(EmptyParentheses* expr) { |
| 2949 // Handled entirely by the parser itself. | 2915 // Handled entirely by the parser itself. |
| 2950 UNREACHABLE(); | 2916 UNREACHABLE(); |
| 2951 } | 2917 } |
| 2952 | 2918 |
| 2953 | 2919 |
| 2954 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) { | 2920 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) { |
| 2955 Node* value = GetFunctionClosure(); | 2921 Node* value = GetFunctionClosure(); |
| 2956 ast_context()->ProduceValue(value); | 2922 ast_context()->ProduceValue(expr, value); |
| 2957 } | 2923 } |
| 2958 | 2924 |
| 2959 | 2925 |
| 2960 void AstGraphBuilder::VisitSuperPropertyReference( | 2926 void AstGraphBuilder::VisitSuperPropertyReference( |
| 2961 SuperPropertyReference* expr) { | 2927 SuperPropertyReference* expr) { |
| 2962 Node* value = BuildThrowUnsupportedSuperError(expr->id()); | 2928 Node* value = BuildThrowUnsupportedSuperError(expr->id()); |
| 2963 ast_context()->ProduceValue(value); | 2929 ast_context()->ProduceValue(expr, value); |
| 2964 } | 2930 } |
| 2965 | 2931 |
| 2966 | 2932 |
| 2967 void AstGraphBuilder::VisitSuperCallReference(SuperCallReference* expr) { | 2933 void AstGraphBuilder::VisitSuperCallReference(SuperCallReference* expr) { |
| 2968 // Handled by VisitCall | 2934 // Handled by VisitCall |
| 2969 UNREACHABLE(); | 2935 UNREACHABLE(); |
| 2970 } | 2936 } |
| 2971 | 2937 |
| 2972 | 2938 |
| 2973 void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { | 2939 void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3034 VisitForValue(property->obj()); | 3000 VisitForValue(property->obj()); |
| 3035 VisitForValue(property->key()); | 3001 VisitForValue(property->key()); |
| 3036 Node* key = environment()->Pop(); | 3002 Node* key = environment()->Pop(); |
| 3037 Node* object = environment()->Pop(); | 3003 Node* object = environment()->Pop(); |
| 3038 value = NewNode(javascript()->DeleteProperty(language_mode()), object, key); | 3004 value = NewNode(javascript()->DeleteProperty(language_mode()), object, key); |
| 3039 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 3005 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 3040 } else { | 3006 } else { |
| 3041 VisitForEffect(expr->expression()); | 3007 VisitForEffect(expr->expression()); |
| 3042 value = jsgraph()->TrueConstant(); | 3008 value = jsgraph()->TrueConstant(); |
| 3043 } | 3009 } |
| 3044 ast_context()->ProduceValue(value); | 3010 ast_context()->ProduceValue(expr, value); |
| 3045 } | 3011 } |
| 3046 | 3012 |
| 3047 | 3013 |
| 3048 void AstGraphBuilder::VisitVoid(UnaryOperation* expr) { | 3014 void AstGraphBuilder::VisitVoid(UnaryOperation* expr) { |
| 3049 VisitForEffect(expr->expression()); | 3015 VisitForEffect(expr->expression()); |
| 3050 Node* value = jsgraph()->UndefinedConstant(); | 3016 Node* value = jsgraph()->UndefinedConstant(); |
| 3051 ast_context()->ProduceValue(value); | 3017 ast_context()->ProduceValue(expr, value); |
| 3052 } | 3018 } |
| 3053 | 3019 |
| 3054 void AstGraphBuilder::VisitTypeofExpression(Expression* expr) { | 3020 void AstGraphBuilder::VisitTypeofExpression(Expression* expr) { |
| 3055 if (expr->IsVariableProxy()) { | 3021 if (expr->IsVariableProxy()) { |
| 3056 // Typeof does not throw a reference error on global variables, hence we | 3022 // Typeof does not throw a reference error on global variables, hence we |
| 3057 // perform a non-contextual load in case the operand is a variable proxy. | 3023 // perform a non-contextual load in case the operand is a variable proxy. |
| 3058 VariableProxy* proxy = expr->AsVariableProxy(); | 3024 VariableProxy* proxy = expr->AsVariableProxy(); |
| 3059 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 3025 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
| 3060 PrepareEagerCheckpoint(BeforeId(proxy)); | 3026 PrepareEagerCheckpoint(BeforeId(proxy)); |
| 3061 Node* load = | 3027 Node* load = |
| 3062 BuildVariableLoad(proxy->var(), expr->id(), pair, | 3028 BuildVariableLoad(proxy->var(), expr->id(), pair, |
| 3063 OutputFrameStateCombine::Push(), INSIDE_TYPEOF); | 3029 OutputFrameStateCombine::Push(), INSIDE_TYPEOF); |
| 3064 environment()->Push(load); | 3030 environment()->Push(load); |
| 3065 } else { | 3031 } else { |
| 3066 VisitForValue(expr); | 3032 VisitForValue(expr); |
| 3067 } | 3033 } |
| 3068 } | 3034 } |
| 3069 | 3035 |
| 3070 void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) { | 3036 void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) { |
| 3071 VisitTypeofExpression(expr->expression()); | 3037 VisitTypeofExpression(expr->expression()); |
| 3072 Node* value = NewNode(javascript()->TypeOf(), environment()->Pop()); | 3038 Node* value = NewNode(javascript()->TypeOf(), environment()->Pop()); |
| 3073 ast_context()->ProduceValue(value); | 3039 ast_context()->ProduceValue(expr, value); |
| 3074 } | 3040 } |
| 3075 | 3041 |
| 3076 | 3042 |
| 3077 void AstGraphBuilder::VisitNot(UnaryOperation* expr) { | 3043 void AstGraphBuilder::VisitNot(UnaryOperation* expr) { |
| 3078 VisitForValue(expr->expression()); | 3044 VisitForTest(expr->expression()); |
| 3079 Node* operand = environment()->Pop(); | 3045 Node* input = environment()->Pop(); |
| 3080 Node* input = BuildToBoolean(operand, expr->expression()->test_id()); | |
| 3081 Node* value = NewNode(common()->Select(MachineRepresentation::kTagged), input, | 3046 Node* value = NewNode(common()->Select(MachineRepresentation::kTagged), input, |
| 3082 jsgraph()->FalseConstant(), jsgraph()->TrueConstant()); | 3047 jsgraph()->FalseConstant(), jsgraph()->TrueConstant()); |
| 3083 ast_context()->ProduceValue(value); | 3048 // Skip plugging AST evaluation contexts of the test kind. This is to stay in |
| 3049 // sync with full codegen which doesn't prepare the proper bailout point (see |
| 3050 // the implementation of FullCodeGenerator::VisitForControl). |
| 3051 if (ast_context()->IsTest()) return environment()->Push(value); |
| 3052 ast_context()->ProduceValue(expr, value); |
| 3084 } | 3053 } |
| 3085 | 3054 |
| 3086 | 3055 |
| 3087 void AstGraphBuilder::VisitComma(BinaryOperation* expr) { | 3056 void AstGraphBuilder::VisitComma(BinaryOperation* expr) { |
| 3088 VisitForEffect(expr->left()); | 3057 VisitForEffect(expr->left()); |
| 3089 Visit(expr->right()); | 3058 Visit(expr->right()); |
| 3090 ast_context()->ReplaceValue(); | 3059 ast_context()->ReplaceValue(expr); |
| 3091 } | 3060 } |
| 3092 | 3061 |
| 3093 | 3062 |
| 3094 void AstGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) { | 3063 void AstGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) { |
| 3095 bool is_logical_and = expr->op() == Token::AND; | 3064 bool is_logical_and = expr->op() == Token::AND; |
| 3096 IfBuilder compare_if(this); | 3065 IfBuilder compare_if(this); |
| 3097 VisitForValue(expr->left()); | 3066 // Only use an AST evaluation context of the value kind when this expression |
| 3098 Node* condition = environment()->Top(); | 3067 // is evaluated as value as well. Otherwise stick to a test context which is |
| 3099 compare_if.If(BuildToBoolean(condition, expr->left()->test_id())); | 3068 // in sync with full codegen (see FullCodeGenerator::VisitLogicalExpression). |
| 3069 Node* condition = nullptr; |
| 3070 if (ast_context()->IsValue()) { |
| 3071 VisitForValue(expr->left()); |
| 3072 Node* left = environment()->Top(); |
| 3073 condition = BuildToBoolean(left, expr->left()->test_id()); |
| 3074 } else { |
| 3075 VisitForTest(expr->left()); |
| 3076 condition = environment()->Top(); |
| 3077 } |
| 3078 compare_if.If(condition); |
| 3100 compare_if.Then(); | 3079 compare_if.Then(); |
| 3101 if (is_logical_and) { | 3080 if (is_logical_and) { |
| 3102 environment()->Pop(); | 3081 environment()->Pop(); |
| 3103 Visit(expr->right()); | 3082 Visit(expr->right()); |
| 3104 } else if (ast_context()->IsEffect()) { | 3083 } else if (ast_context()->IsEffect()) { |
| 3105 environment()->Pop(); | 3084 environment()->Pop(); |
| 3106 } else if (ast_context()->IsTest()) { | 3085 } else if (ast_context()->IsTest()) { |
| 3107 environment()->Poke(0, jsgraph()->TrueConstant()); | 3086 environment()->Poke(0, jsgraph()->TrueConstant()); |
| 3108 } | 3087 } |
| 3109 compare_if.Else(); | 3088 compare_if.Else(); |
| 3110 if (!is_logical_and) { | 3089 if (!is_logical_and) { |
| 3111 environment()->Pop(); | 3090 environment()->Pop(); |
| 3112 Visit(expr->right()); | 3091 Visit(expr->right()); |
| 3113 } else if (ast_context()->IsEffect()) { | 3092 } else if (ast_context()->IsEffect()) { |
| 3114 environment()->Pop(); | 3093 environment()->Pop(); |
| 3115 } else if (ast_context()->IsTest()) { | 3094 } else if (ast_context()->IsTest()) { |
| 3116 environment()->Poke(0, jsgraph()->FalseConstant()); | 3095 environment()->Poke(0, jsgraph()->FalseConstant()); |
| 3117 } | 3096 } |
| 3118 compare_if.End(); | 3097 compare_if.End(); |
| 3119 ast_context()->ReplaceValue(); | 3098 // Skip plugging AST evaluation contexts of the test kind. This is to stay in |
| 3099 // sync with full codegen which doesn't prepare the proper bailout point (see |
| 3100 // the implementation of FullCodeGenerator::VisitForControl). |
| 3101 if (ast_context()->IsTest()) return; |
| 3102 ast_context()->ReplaceValue(expr); |
| 3120 } | 3103 } |
| 3121 | 3104 |
| 3122 | 3105 |
| 3123 LanguageMode AstGraphBuilder::language_mode() const { | 3106 LanguageMode AstGraphBuilder::language_mode() const { |
| 3124 return current_scope()->language_mode(); | 3107 return current_scope()->language_mode(); |
| 3125 } | 3108 } |
| 3126 | 3109 |
| 3127 | 3110 |
| 3128 VectorSlotPair AstGraphBuilder::CreateVectorSlotPair( | 3111 VectorSlotPair AstGraphBuilder::CreateVectorSlotPair( |
| 3129 FeedbackVectorSlot slot) const { | 3112 FeedbackVectorSlot slot) const { |
| (...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4070 } | 4053 } |
| 4071 } | 4054 } |
| 4072 | 4055 |
| 4073 void AstGraphBuilder::PrepareEagerCheckpoint(BailoutId ast_id) { | 4056 void AstGraphBuilder::PrepareEagerCheckpoint(BailoutId ast_id) { |
| 4074 if (environment()->GetEffectDependency()->opcode() == IrOpcode::kCheckpoint) { | 4057 if (environment()->GetEffectDependency()->opcode() == IrOpcode::kCheckpoint) { |
| 4075 // We skip preparing a checkpoint if there already is one the current effect | 4058 // We skip preparing a checkpoint if there already is one the current effect |
| 4076 // dependency. This is just an optimization and not need for correctness. | 4059 // dependency. This is just an optimization and not need for correctness. |
| 4077 return; | 4060 return; |
| 4078 } | 4061 } |
| 4079 if (ast_id != BailoutId::None()) { | 4062 if (ast_id != BailoutId::None()) { |
| 4063 DCHECK(info()->shared_info()->VerifyBailoutId(ast_id)); |
| 4080 Node* node = NewNode(common()->Checkpoint()); | 4064 Node* node = NewNode(common()->Checkpoint()); |
| 4081 DCHECK_EQ(IrOpcode::kDead, | 4065 DCHECK_EQ(IrOpcode::kDead, |
| 4082 NodeProperties::GetFrameStateInput(node, 0)->opcode()); | 4066 NodeProperties::GetFrameStateInput(node, 0)->opcode()); |
| 4083 NodeProperties::ReplaceFrameStateInput(node, 0, | 4067 NodeProperties::ReplaceFrameStateInput(node, 0, |
| 4084 environment()->Checkpoint(ast_id)); | 4068 environment()->Checkpoint(ast_id)); |
| 4085 } | 4069 } |
| 4086 } | 4070 } |
| 4087 | 4071 |
| 4088 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( | 4072 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( |
| 4089 IterationStatement* stmt) { | 4073 IterationStatement* stmt) { |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4388 // Phi does not exist yet, introduce one. | 4372 // Phi does not exist yet, introduce one. |
| 4389 value = NewPhi(inputs, value, control); | 4373 value = NewPhi(inputs, value, control); |
| 4390 value->ReplaceInput(inputs - 1, other); | 4374 value->ReplaceInput(inputs - 1, other); |
| 4391 } | 4375 } |
| 4392 return value; | 4376 return value; |
| 4393 } | 4377 } |
| 4394 | 4378 |
| 4395 } // namespace compiler | 4379 } // namespace compiler |
| 4396 } // namespace internal | 4380 } // namespace internal |
| 4397 } // namespace v8 | 4381 } // namespace v8 |
| OLD | NEW |