Index: src/ast/ast.h |
diff --git a/src/ast/ast.h b/src/ast/ast.h |
index 8c9ef323ad29b422fb735a92c0ba154e905cac9e..73d52a6a1cca9ae9b0a6b853ac9764985e7ad83f 100644 |
--- a/src/ast/ast.h |
+++ b/src/ast/ast.h |
@@ -505,7 +505,9 @@ class DoExpression final : public Expression { |
DECLARE_NODE_TYPE(DoExpression) |
Block* block() { return block_; } |
+ void set_block(Block* b) { block_ = b; } |
VariableProxy* result() { return result_; } |
+ void set_result(VariableProxy* v) { result_ = v; } |
void MarkTail() override { block_->MarkTail(); } |
@@ -583,6 +585,7 @@ class FunctionDeclaration final : public Declaration { |
DECLARE_NODE_TYPE(FunctionDeclaration) |
FunctionLiteral* fun() const { return fun_; } |
+ void set_fun(FunctionLiteral* f) { fun_ = f; } |
InitializationFlag initialization() const override { |
return kCreatedInitialized; |
} |
@@ -706,6 +709,7 @@ class DoWhileStatement final : public IterationStatement { |
} |
Expression* cond() const { return cond_; } |
+ void set_cond(Expression* e) { cond_ = e; } |
static int num_ids() { return parent_num_ids() + 2; } |
BailoutId ContinueId() const override { return BailoutId(local_id(0)); } |
@@ -734,6 +738,7 @@ class WhileStatement final : public IterationStatement { |
} |
Expression* cond() const { return cond_; } |
+ void set_cond(Expression* e) { cond_ = e; } |
static int num_ids() { return parent_num_ids() + 1; } |
BailoutId ContinueId() const override { return EntryId(); } |
@@ -770,6 +775,10 @@ class ForStatement final : public IterationStatement { |
Expression* cond() const { return cond_; } |
Statement* next() const { return next_; } |
+ void set_init(Statement* s) { init_ = s; } |
+ void set_cond(Expression* e) { cond_ = e; } |
+ void set_next(Statement* s) { next_ = s; } |
+ |
static int num_ids() { return parent_num_ids() + 2; } |
BailoutId ContinueId() const override { return BailoutId(local_id(0)); } |
BailoutId StackCheckId() const override { return BodyId(); } |
@@ -808,6 +817,9 @@ class ForEachStatement : public IterationStatement { |
Expression* each() const { return each_; } |
Expression* subject() const { return subject_; } |
+ void set_each(Expression* e) { each_ = e; } |
+ void set_subject(Expression* e) { subject_ = e; } |
+ |
void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, |
FeedbackVectorSlotCache* cache) override; |
FeedbackVectorSlot EachFeedbackSlot() const { return each_slot_; } |
@@ -912,6 +924,11 @@ class ForOfStatement final : public ForEachStatement { |
return assign_each_; |
} |
+ void set_assign_iterator(Expression* e) { assign_iterator_ = e; } |
+ void set_next_result(Expression* e) { next_result_ = e; } |
+ void set_result_done(Expression* e) { result_done_ = e; } |
+ void set_assign_each(Expression* e) { assign_each_ = e; } |
nickie
2016/01/11 10:24:18
Small fix #1: these four lines had inadvertently b
|
+ |
BailoutId ContinueId() const override { return EntryId(); } |
BailoutId StackCheckId() const override { return BackEdgeId(); } |
@@ -1000,6 +1017,8 @@ class ReturnStatement final : public JumpStatement { |
Expression* expression() const { return expression_; } |
+ void set_expression(Expression* e) { expression_ = e; } |
+ |
protected: |
explicit ReturnStatement(Zone* zone, Expression* expression, int pos) |
: JumpStatement(zone, pos), expression_(expression) { } |
@@ -1015,6 +1034,7 @@ class WithStatement final : public Statement { |
Scope* scope() { return scope_; } |
Expression* expression() const { return expression_; } |
+ void set_expression(Expression* e) { expression_ = e; } |
Statement* statement() const { return statement_; } |
void set_statement(Statement* s) { statement_ = s; } |
@@ -1059,6 +1079,7 @@ class CaseClause final : public Expression { |
CHECK(!is_default()); |
return label_; |
} |
+ void set_label(Expression* e) { label_ = e; } |
Label* body_target() { return &body_target_; } |
ZoneList<Statement*>* statements() const { return statements_; } |
@@ -1100,6 +1121,8 @@ class SwitchStatement final : public BreakableStatement { |
Expression* tag() const { return tag_; } |
ZoneList<CaseClause*>* cases() const { return cases_; } |
+ void set_tag(Expression* t) { tag_ = t; } |
+ |
void MarkTail() override { |
if (!cases_->is_empty()) cases_->last()->MarkTail(); |
} |
@@ -1132,6 +1155,7 @@ class IfStatement final : public Statement { |
Statement* then_statement() const { return then_statement_; } |
Statement* else_statement() const { return else_statement_; } |
+ void set_condition(Expression* e) { condition_ = e; } |
void set_then_statement(Statement* s) { then_statement_ = s; } |
void set_else_statement(Statement* s) { else_statement_ = s; } |
@@ -1426,6 +1450,9 @@ class ObjectLiteralProperty final : public ZoneObject { |
Expression* value() { return value_; } |
Kind kind() { return kind_; } |
+ void set_key(Expression* e) { key_ = e; } |
+ void set_value(Expression* e) { value_ = e; } |
+ |
// Type feedback information. |
bool IsMonomorphic() { return !receiver_type_.is_null(); } |
Handle<Map> GetReceiverType() { return receiver_type_; } |
@@ -1799,6 +1826,9 @@ class Property final : public Expression { |
Expression* obj() const { return obj_; } |
Expression* key() const { return key_; } |
+ void set_obj(Expression* e) { obj_ = e; } |
+ void set_key(Expression* e) { key_ = e; } |
+ |
static int num_ids() { return parent_num_ids() + 1; } |
BailoutId LoadId() const { return BailoutId(local_id(0)); } |
@@ -1890,6 +1920,8 @@ class Call final : public Expression { |
Expression* expression() const { return expression_; } |
ZoneList<Expression*>* arguments() const { return arguments_; } |
+ void set_expression(Expression* e) { expression_ = e; } |
+ |
// Type feedback information. |
void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, |
FeedbackVectorSlotCache* cache) override; |
@@ -2009,6 +2041,8 @@ class CallNew final : public Expression { |
Expression* expression() const { return expression_; } |
ZoneList<Expression*>* arguments() const { return arguments_; } |
+ void set_expression(Expression* e) { expression_ = e; } |
+ |
// Type feedback information. |
void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, |
FeedbackVectorSlotCache* cache) override { |
@@ -2118,6 +2152,7 @@ class UnaryOperation final : public Expression { |
Token::Value op() const { return op_; } |
Expression* expression() const { return expression_; } |
+ void set_expression(Expression* e) { expression_ = e; } |
// For unary not (Token::NOT), the AST ids where true and false will |
// actually be materialized, respectively. |
@@ -2148,7 +2183,9 @@ class BinaryOperation final : public Expression { |
Token::Value op() const { return static_cast<Token::Value>(op_); } |
Expression* left() const { return left_; } |
+ void set_left(Expression* e) { left_ = e; } |
Expression* right() const { return right_; } |
+ void set_right(Expression* e) { right_ = e; } |
Handle<AllocationSite> allocation_site() const { return allocation_site_; } |
void set_allocation_site(Handle<AllocationSite> allocation_site) { |
allocation_site_ = allocation_site; |
@@ -2223,6 +2260,7 @@ class CountOperation final : public Expression { |
} |
Expression* expression() const { return expression_; } |
+ void set_expression(Expression* e) { expression_ = e; } |
bool IsMonomorphic() override { return receiver_types_.length() == 1; } |
SmallMapList* GetReceiverTypes() override { return &receiver_types_; } |
@@ -2292,6 +2330,9 @@ class CompareOperation final : public Expression { |
Expression* left() const { return left_; } |
Expression* right() const { return right_; } |
+ void set_left(Expression* e) { left_ = e; } |
+ void set_right(Expression* e) { right_ = e; } |
+ |
// Type feedback information. |
static int num_ids() { return parent_num_ids() + 1; } |
TypeFeedbackId CompareOperationFeedbackId() const { |
@@ -2333,6 +2374,7 @@ class Spread final : public Expression { |
DECLARE_NODE_TYPE(Spread) |
Expression* expression() const { return expression_; } |
+ void set_expression(Expression* e) { expression_ = e; } |
static int num_ids() { return parent_num_ids(); } |
@@ -2356,6 +2398,10 @@ class Conditional final : public Expression { |
Expression* then_expression() const { return then_expression_; } |
Expression* else_expression() const { return else_expression_; } |
+ void set_condition(Expression* e) { condition_ = e; } |
+ void set_then_expression(Expression* e) { then_expression_ = e; } |
+ void set_else_expression(Expression* e) { else_expression_ = e; } |
+ |
void MarkTail() override { |
then_expression_->MarkTail(); |
else_expression_->MarkTail(); |
@@ -2395,6 +2441,9 @@ class Assignment final : public Expression { |
Expression* target() const { return target_; } |
Expression* value() const { return value_; } |
+ void set_target(Expression* e) { target_ = e; } |
+ void set_value(Expression* e) { value_ = e; } |
+ |
BinaryOperation* binary_operation() const { return binary_operation_; } |
// This check relies on the definition order of token in token.h. |
@@ -2467,6 +2516,8 @@ class RewritableAssignmentExpression : public Expression { |
Expression* expression() { return expr_; } |
bool is_rewritten() const { return is_rewritten_; } |
+ void set_expression(Expression* e) { expr_ = e; } |
+ |
void Rewrite(Expression* new_expression) { |
DCHECK(!is_rewritten()); |
DCHECK_NOT_NULL(new_expression); |
@@ -2505,6 +2556,9 @@ class Yield final : public Expression { |
Expression* expression() const { return expression_; } |
Kind yield_kind() const { return yield_kind_; } |
+ void set_generator_object(Expression* e) { generator_object_ = e; } |
+ void set_expression(Expression* e) { expression_ = e; } |
+ |
// Type feedback information. |
bool HasFeedbackSlots() const { return yield_kind() == kDelegating; } |
void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, |
@@ -2548,6 +2602,7 @@ class Throw final : public Expression { |
DECLARE_NODE_TYPE(Throw) |
Expression* exception() const { return exception_; } |
+ void set_exception(Expression* e) { exception_ = e; } |
protected: |
Throw(Zone* zone, Expression* exception, int pos) |
@@ -2767,7 +2822,9 @@ class ClassLiteral final : public Expression { |
Scope* scope() const { return scope_; } |
VariableProxy* class_variable_proxy() const { return class_variable_proxy_; } |
Expression* extends() const { return extends_; } |
+ void set_extends(Expression* e) { extends_ = e; } |
FunctionLiteral* constructor() const { return constructor_; } |
+ void set_constructor(FunctionLiteral* f) { constructor_ = f; } |
ZoneList<Property*>* properties() const { return properties_; } |
int start_position() const { return position(); } |
int end_position() const { return end_position_; } |
@@ -2858,7 +2915,9 @@ class SuperPropertyReference final : public Expression { |
DECLARE_NODE_TYPE(SuperPropertyReference) |
VariableProxy* this_var() const { return this_var_; } |
+ void set_this_var(VariableProxy* v) { this_var_ = v; } |
Expression* home_object() const { return home_object_; } |
+ void set_home_object(Expression* e) { home_object_ = e; } |
protected: |
SuperPropertyReference(Zone* zone, VariableProxy* this_var, |
@@ -2879,8 +2938,11 @@ class SuperCallReference final : public Expression { |
DECLARE_NODE_TYPE(SuperCallReference) |
VariableProxy* this_var() const { return this_var_; } |
+ void set_this_var(VariableProxy* v) { this_var_ = v; } |
VariableProxy* new_target_var() const { return new_target_var_; } |
+ void set_new_target_var(VariableProxy* v) { new_target_var_ = v; } |
VariableProxy* this_function_var() const { return this_function_var_; } |
+ void set_this_function_var(VariableProxy* v) { this_function_var_ = v; } |
protected: |
SuperCallReference(Zone* zone, VariableProxy* this_var, |
@@ -3324,6 +3386,69 @@ class AstVisitor BASE_EMBEDDED { |
uintptr_t stack_limit_; \ |
bool stack_overflow_ |
+#define DEFINE_AST_REWRITER_SUBCLASS_MEMBERS() \ |
+ public: \ |
+ AstNode* Rewrite(AstNode* node) { \ |
+ DCHECK_NULL(replacement_); \ |
+ DCHECK_NOT_NULL(node); \ |
+ Visit(node); \ |
+ if (HasStackOverflow()) return node; \ |
nickie
2016/01/11 10:24:18
Small fix #2: in case of failure, a non-null node
|
+ if (replacement_ == nullptr) return node; \ |
+ AstNode* result = replacement_; \ |
+ replacement_ = nullptr; \ |
+ return result; \ |
+ } \ |
+ \ |
+ private: \ |
+ void InitializeAstRewriter(Isolate* isolate) { \ |
+ InitializeAstVisitor(isolate); \ |
+ replacement_ = nullptr; \ |
+ } \ |
+ \ |
+ void InitializeAstRewriter(uintptr_t stack_limit) { \ |
+ InitializeAstVisitor(stack_limit); \ |
+ replacement_ = nullptr; \ |
+ } \ |
+ \ |
+ DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); \ |
+ \ |
+ protected: \ |
+ AstNode* replacement_ |
+ |
+// Generic macro for rewriting things; `GET` is the expression to be |
+// rewritten; `SET` is a command that should do the rewriting, i.e. |
+// something sensible with the variable called `replacement`. |
+#define AST_REWRITE(Type, GET, SET) \ |
+ do { \ |
+ DCHECK(!HasStackOverflow()); \ |
+ DCHECK_NULL(replacement_); \ |
+ Visit(GET); \ |
+ if (HasStackOverflow()) return; \ |
+ if (replacement_ == nullptr) break; \ |
+ Type* replacement = reinterpret_cast<Type*>(replacement_); \ |
+ do { \ |
+ SET; \ |
+ } while (false); \ |
+ replacement_ = nullptr; \ |
+ } while (false) |
+ |
+// Macro for rewriting object properties; it assumes that `object` has |
+// `property` with a public getter and setter. |
+#define AST_REWRITE_PROPERTY(Type, object, property) \ |
+ do { \ |
+ auto _obj = (object); \ |
+ AST_REWRITE(Type, _obj->property(), _obj->set_##property(replacement)); \ |
+ } while (false) |
+ |
+// Macro for rewriting list elements; it assumes that `list` has methods |
+// `at` and `Set`. |
+#define AST_REWRITE_LIST_ELEMENT(Type, list, index) \ |
+ do { \ |
+ auto _list = (list); \ |
+ auto _index = (index); \ |
+ AST_REWRITE(Type, _list->at(_index), _list->Set(_index, replacement)); \ |
+ } while (false) |
+ |
// ---------------------------------------------------------------------------- |
// AstNode factory |