Chromium Code Reviews| Index: src/ast/ast.cc |
| diff --git a/src/ast/ast.cc b/src/ast/ast.cc |
| index e9c422e288343a7a740fd14ca585609fed3c67d7..3e5f65f6fa6c3e9763fd17fa64e125f2545af1fa 100644 |
| --- a/src/ast/ast.cc |
| +++ b/src/ast/ast.cc |
| @@ -47,6 +47,49 @@ void AstNode::PrettyPrint(Isolate* isolate) { |
| #endif // DEBUG |
| +#define RETURN_NODE(Node) \ |
| + case k##Node: \ |
| + return static_cast<Node*>(this); |
| + |
| +IterationStatement* AstNode::AsIterationStatement() { |
| + switch (node_type()) { |
| + ITERATION_NODE_LIST(RETURN_NODE); |
| + default: |
| + return nullptr; |
| + } |
| +} |
| + |
| +BreakableStatement* AstNode::AsBreakableStatement() { |
| + switch (node_type()) { |
| + BREAKABLE_NODE_LIST(RETURN_NODE); |
| + ITERATION_NODE_LIST(RETURN_NODE); |
| + default: |
| + return nullptr; |
| + } |
| +} |
| + |
| +MaterializedLiteral* AstNode::AsMaterializedLiteral() { |
| + switch (node_type()) { |
| + LITERAL_NODE_LIST(RETURN_NODE); |
| + default: |
| + return nullptr; |
| + } |
| +} |
| + |
| +#undef RETURN_NODE |
| + |
| +InitializationFlag Declaration::initialization() const { |
| + switch (node_type()) { |
| +#define GENERATE_CASE(Node) \ |
| + case k##Node: \ |
|
Igor Sheludko
2016/07/14 14:02:33
How about adding something like
STATIC_ASSERT(&
Toon Verwaest
2016/07/14 14:19:39
I'd add STATIC_ASSERT(k##Node != kExpression), how
Igor Sheludko
2016/07/14 14:49:30
No, the idea is to ensure that when you call a foo
|
| + return static_cast<const Node*>(this)->initialization(); |
| + DECLARATION_NODE_LIST(GENERATE_CASE); |
| +#undef GENERATE_CASE |
| + default: |
| + UNREACHABLE(); |
| + return kNeedsInitialization; |
| + } |
| +} |
| bool Expression::IsSmiLiteral() const { |
| return IsLiteral() && AsLiteral()->value()->IsSmi(); |
| @@ -57,6 +100,9 @@ bool Expression::IsStringLiteral() const { |
| return IsLiteral() && AsLiteral()->value()->IsString(); |
| } |
| +bool Expression::IsPropertyName() const { |
| + return IsLiteral() && AsLiteral()->IsPropertyName(); |
| +} |
| bool Expression::IsNullLiteral() const { |
| if (!IsLiteral()) return false; |
| @@ -83,12 +129,47 @@ bool Expression::IsUndefinedLiteral() const { |
| var_proxy->raw_name()->IsOneByteEqualTo("undefined"); |
| } |
| +bool Expression::ToBooleanIsTrue() const { |
| + return IsLiteral() && AsLiteral()->ToBooleanIsTrue(); |
| +} |
| + |
| +bool Expression::ToBooleanIsFalse() const { |
| + return IsLiteral() && AsLiteral()->ToBooleanIsFalse(); |
| +} |
| + |
| +bool Expression::IsValidReferenceExpression() const { |
| + return IsProperty() || |
| + (IsVariableProxy() && AsVariableProxy()->IsValidReferenceExpression()); |
| +} |
| bool Expression::IsValidReferenceExpressionOrThis() const { |
| return IsValidReferenceExpression() || |
| (IsVariableProxy() && AsVariableProxy()->is_this()); |
| } |
| +bool Expression::IsAnonymousFunctionDefinition() const { |
| + return (IsFunctionLiteral() && |
| + AsFunctionLiteral()->IsAnonymousFunctionDefinition()) || |
| + (IsClassLiteral() && |
| + AsClassLiteral()->IsAnonymousFunctionDefinition()); |
| +} |
| + |
| +void Expression::MarkTail() { |
| + if (IsConditional()) { |
| + AsConditional()->MarkTail(); |
| + } else if (IsCall()) { |
| + AsCall()->MarkTail(); |
| + } else if (IsBinaryOperation()) { |
| + AsBinaryOperation()->MarkTail(); |
| + } |
| +} |
| + |
| +bool Statement::IsJump() const { |
| + return (IsBlock() && AsBlock()->IsJump()) || |
| + (IsExpressionStatement() && AsExpressionStatement()->IsJump()) || |
| + IsContinueStatement() || IsBreakStatement() || IsReturnStatement() || |
|
Igor Sheludko
2016/07/14 14:02:33
How about following same pattern for all JumpState
Toon Verwaest
2016/07/14 14:19:39
Done.
|
| + (IsIfStatement() && AsIfStatement()->IsJump()); |
| +} |
| VariableProxy::VariableProxy(Zone* zone, Variable* var, int start_position, |
| int end_position) |
| @@ -719,9 +800,71 @@ bool CompareOperation::IsLiteralCompareNull(Expression** expr) { |
| // once we use the common type field in the AST consistently. |
| void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { |
| - set_to_boolean_types(oracle->ToBooleanTypes(test_id())); |
| + if (IsUnaryOperation()) { |
| + AsUnaryOperation()->RecordToBooleanTypeFeedback(oracle); |
| + } else if (IsBinaryOperation()) { |
| + AsBinaryOperation()->RecordToBooleanTypeFeedback(oracle); |
| + } else { |
| + set_to_boolean_types(oracle->ToBooleanTypes(test_id())); |
| + } |
| +} |
| + |
| +SmallMapList* Expression::GetReceiverTypes() { |
| + switch (node_type()) { |
| +#define NODE_LIST(V) \ |
| + PROPERTY_NODE_LIST(V) \ |
| + V(Call) |
| +#define GENERATE_CASE(Node) \ |
| + case k##Node: \ |
| + return static_cast<Node*>(this)->GetReceiverTypes(); |
| + NODE_LIST(GENERATE_CASE) |
| +#undef NODE_LIST |
| +#undef GENERATE_CASE |
| + default: |
| + UNREACHABLE(); |
| + return nullptr; |
| + } |
| } |
| +KeyedAccessStoreMode Expression::GetStoreMode() const { |
| + switch (node_type()) { |
| +#define GENERATE_CASE(Node) \ |
| + case k##Node: \ |
| + return static_cast<const Node*>(this)->GetStoreMode(); |
| + PROPERTY_NODE_LIST(GENERATE_CASE) |
| +#undef GENERATE_CASE |
| + default: |
| + UNREACHABLE(); |
| + return STANDARD_STORE; |
| + } |
| +} |
| + |
| +IcCheckType Expression::GetKeyType() const { |
| + switch (node_type()) { |
| +#define GENERATE_CASE(Node) \ |
| + case k##Node: \ |
| + return static_cast<const Node*>(this)->GetKeyType(); |
| + PROPERTY_NODE_LIST(GENERATE_CASE) |
| +#undef GENERATE_CASE |
| + default: |
| + UNREACHABLE(); |
| + return PROPERTY; |
| + } |
| +} |
| + |
| +bool Expression::IsMonomorphic() const { |
| + switch (node_type()) { |
| +#define GENERATE_CASE(Node) \ |
| + case k##Node: \ |
| + return static_cast<const Node*>(this)->IsMonomorphic(); |
| + PROPERTY_NODE_LIST(GENERATE_CASE) |
| + CALL_NODE_LIST(GENERATE_CASE) |
|
Igor Sheludko
2016/07/14 14:02:33
GENERATE_CASE(ObjectLiteralProperty) ?
Toon Verwaest
2016/07/14 14:19:39
ObjectLiteralProperty is not an AstNode. It derive
Igor Sheludko
2016/07/14 14:49:30
Ah, indeed.
|
| +#undef GENERATE_CASE |
| + default: |
| + UNREACHABLE(); |
| + return false; |
| + } |
| +} |
| bool Call::IsUsingCallFeedbackICSlot(Isolate* isolate) const { |
| CallType call_type = GetCallType(isolate); |