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); |