Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(309)

Side by Side Diff: src/rewriter.cc

Issue 1361403003: Implement ES6 completion semantics (--harmony-completion). (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Proper rebase. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parser.cc ('k') | test/mjsunit/es6/block-for.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/rewriter.h" 5 #include "src/rewriter.h"
6 6
7 #include "src/ast.h" 7 #include "src/ast.h"
8 #include "src/parser.h" 8 #include "src/parser.h"
9 #include "src/scopes.h" 9 #include "src/scopes.h"
10 10
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 AstNodeFactory factory_; 55 AstNodeFactory factory_;
56 56
57 // Returns ".result = value" 57 // Returns ".result = value"
58 Expression* SetResult(Expression* value) { 58 Expression* SetResult(Expression* value) {
59 result_assigned_ = true; 59 result_assigned_ = true;
60 VariableProxy* result_proxy = factory()->NewVariableProxy(result_); 60 VariableProxy* result_proxy = factory()->NewVariableProxy(result_);
61 return factory()->NewAssignment( 61 return factory()->NewAssignment(
62 Token::ASSIGN, result_proxy, value, RelocInfo::kNoPosition); 62 Token::ASSIGN, result_proxy, value, RelocInfo::kNoPosition);
63 } 63 }
64 64
65 // Inserts '.result = undefined' in front of the given statement.
66 Statement* AssignUndefinedBefore(Statement* s);
67
65 // Node visitors. 68 // Node visitors.
66 #define DEF_VISIT(type) virtual void Visit##type(type* node) override; 69 #define DEF_VISIT(type) virtual void Visit##type(type* node) override;
67 AST_NODE_LIST(DEF_VISIT) 70 AST_NODE_LIST(DEF_VISIT)
68 #undef DEF_VISIT 71 #undef DEF_VISIT
69 72
70 void VisitIterationStatement(IterationStatement* stmt); 73 void VisitIterationStatement(IterationStatement* stmt);
71 74
72 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); 75 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
73 }; 76 };
74 77
75 78
79 Statement* Processor::AssignUndefinedBefore(Statement* s) {
80 Expression* result_proxy = factory()->NewVariableProxy(result_);
81 Expression* undef = factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
82 Expression* assignment = factory()->NewAssignment(
83 Token::ASSIGN, result_proxy, undef, RelocInfo::kNoPosition);
84 Block* b = factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
85 b->statements()->Add(
86 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
87 zone());
88 b->statements()->Add(s, zone());
89 return b;
90 }
91
92
76 void Processor::Process(ZoneList<Statement*>* statements) { 93 void Processor::Process(ZoneList<Statement*>* statements) {
77 for (int i = statements->length() - 1; i >= 0; --i) { 94 for (int i = statements->length() - 1; i >= 0; --i) {
78 Visit(statements->at(i)); 95 Visit(statements->at(i));
79 statements->Set(i, replacement_); 96 statements->Set(i, replacement_);
80 } 97 }
81 } 98 }
82 99
83 100
84 void Processor::VisitBlock(Block* node) { 101 void Processor::VisitBlock(Block* node) {
85 // An initializer block is the rewritten form of a variable declaration 102 // An initializer block is the rewritten form of a variable declaration
(...skipping 23 matching lines...) Expand all
109 // Rewrite both branches. 126 // Rewrite both branches.
110 bool set_after = is_set_; 127 bool set_after = is_set_;
111 Visit(node->then_statement()); 128 Visit(node->then_statement());
112 node->set_then_statement(replacement_); 129 node->set_then_statement(replacement_);
113 bool set_in_then = is_set_; 130 bool set_in_then = is_set_;
114 is_set_ = set_after; 131 is_set_ = set_after;
115 Visit(node->else_statement()); 132 Visit(node->else_statement());
116 node->set_else_statement(replacement_); 133 node->set_else_statement(replacement_);
117 is_set_ = is_set_ && set_in_then; 134 is_set_ = is_set_ && set_in_then;
118 replacement_ = node; 135 replacement_ = node;
136
137 if (FLAG_harmony_completion && !is_set_) {
138 is_set_ = true;
139 replacement_ = AssignUndefinedBefore(node);
140 }
119 } 141 }
120 142
121 143
122 void Processor::VisitIterationStatement(IterationStatement* node) { 144 void Processor::VisitIterationStatement(IterationStatement* node) {
123 // Rewrite the body. 145 // Rewrite the body.
124 bool set_after = is_set_; 146 bool set_after = is_set_;
125 is_set_ = false; // We are in a loop, so we can't rely on [set_after]. 147 is_set_ = false; // We are in a loop, so we can't rely on [set_after].
126 Visit(node->body()); 148 Visit(node->body());
127 node->set_body(replacement_); 149 node->set_body(replacement_);
128 is_set_ = is_set_ && set_after; 150 is_set_ = is_set_ && set_after;
129 replacement_ = node; 151 replacement_ = node;
152
153 if (FLAG_harmony_completion && !is_set_) {
154 is_set_ = true;
155 replacement_ = AssignUndefinedBefore(node);
156 }
130 } 157 }
131 158
132 159
133 void Processor::VisitDoWhileStatement(DoWhileStatement* node) { 160 void Processor::VisitDoWhileStatement(DoWhileStatement* node) {
134 VisitIterationStatement(node); 161 VisitIterationStatement(node);
135 } 162 }
136 163
137 164
138 void Processor::VisitWhileStatement(WhileStatement* node) { 165 void Processor::VisitWhileStatement(WhileStatement* node) {
139 VisitIterationStatement(node); 166 VisitIterationStatement(node);
(...skipping 19 matching lines...) Expand all
159 // Rewrite both try and catch block. 186 // Rewrite both try and catch block.
160 bool set_after = is_set_; 187 bool set_after = is_set_;
161 Visit(node->try_block()); 188 Visit(node->try_block());
162 node->set_try_block(static_cast<Block*>(replacement_)); 189 node->set_try_block(static_cast<Block*>(replacement_));
163 bool set_in_try = is_set_; 190 bool set_in_try = is_set_;
164 is_set_ = set_after; 191 is_set_ = set_after;
165 Visit(node->catch_block()); 192 Visit(node->catch_block());
166 node->set_catch_block(static_cast<Block*>(replacement_)); 193 node->set_catch_block(static_cast<Block*>(replacement_));
167 is_set_ = is_set_ && set_in_try; 194 is_set_ = is_set_ && set_in_try;
168 replacement_ = node; 195 replacement_ = node;
196
197 if (FLAG_harmony_completion && !is_set_) {
198 is_set_ = true;
199 replacement_ = AssignUndefinedBefore(node);
200 }
169 } 201 }
170 202
171 203
172 void Processor::VisitTryFinallyStatement(TryFinallyStatement* node) { 204 void Processor::VisitTryFinallyStatement(TryFinallyStatement* node) {
173 // Rewrite both try and finally block (in reverse order). 205 // Rewrite both try and finally block (in reverse order).
174 bool set_after = is_set_; 206 bool set_after = is_set_;
175 is_set_ = true; // Don't normally need to assign in finally block. 207 is_set_ = true; // Don't normally need to assign in finally block.
176 Visit(node->finally_block()); 208 Visit(node->finally_block());
177 node->set_finally_block(replacement_->AsBlock()); 209 node->set_finally_block(replacement_->AsBlock());
178 { // Save .result value at the beginning of the finally block and restore it 210 { // Save .result value at the beginning of the finally block and restore it
(...skipping 12 matching lines...) Expand all
191 0, factory()->NewExpressionStatement(save, RelocInfo::kNoPosition), 223 0, factory()->NewExpressionStatement(save, RelocInfo::kNoPosition),
192 zone()); 224 zone());
193 node->finally_block()->statements()->Add( 225 node->finally_block()->statements()->Add(
194 factory()->NewExpressionStatement(restore, RelocInfo::kNoPosition), 226 factory()->NewExpressionStatement(restore, RelocInfo::kNoPosition),
195 zone()); 227 zone());
196 } 228 }
197 is_set_ = set_after; 229 is_set_ = set_after;
198 Visit(node->try_block()); 230 Visit(node->try_block());
199 node->set_try_block(replacement_->AsBlock()); 231 node->set_try_block(replacement_->AsBlock());
200 replacement_ = node; 232 replacement_ = node;
233
234 if (FLAG_harmony_completion && !is_set_) {
235 is_set_ = true;
236 replacement_ = AssignUndefinedBefore(node);
237 }
201 } 238 }
202 239
203 240
204 void Processor::VisitSwitchStatement(SwitchStatement* node) { 241 void Processor::VisitSwitchStatement(SwitchStatement* node) {
205 // Rewrite statements in all case clauses (in reverse order). 242 // Rewrite statements in all case clauses (in reverse order).
206 ZoneList<CaseClause*>* clauses = node->cases(); 243 ZoneList<CaseClause*>* clauses = node->cases();
207 bool set_after = is_set_; 244 bool set_after = is_set_;
208 for (int i = clauses->length() - 1; i >= 0; --i) { 245 for (int i = clauses->length() - 1; i >= 0; --i) {
209 CaseClause* clause = clauses->at(i); 246 CaseClause* clause = clauses->at(i);
210 Process(clause->statements()); 247 Process(clause->statements());
211 } 248 }
212 is_set_ = is_set_ && set_after; 249 is_set_ = is_set_ && set_after;
213 replacement_ = node; 250 replacement_ = node;
251
252 if (FLAG_harmony_completion && !is_set_) {
253 is_set_ = true;
254 replacement_ = AssignUndefinedBefore(node);
255 }
214 } 256 }
215 257
216 258
217 void Processor::VisitContinueStatement(ContinueStatement* node) { 259 void Processor::VisitContinueStatement(ContinueStatement* node) {
218 is_set_ = false; 260 is_set_ = false;
219 replacement_ = node; 261 replacement_ = node;
220 } 262 }
221 263
222 264
223 void Processor::VisitBreakStatement(BreakStatement* node) { 265 void Processor::VisitBreakStatement(BreakStatement* node) {
224 is_set_ = false; 266 is_set_ = false;
225 replacement_ = node; 267 replacement_ = node;
226 } 268 }
227 269
228 270
229 void Processor::VisitWithStatement(WithStatement* node) { 271 void Processor::VisitWithStatement(WithStatement* node) {
230 Visit(node->statement()); 272 Visit(node->statement());
231 node->set_statement(replacement_); 273 node->set_statement(replacement_);
232 replacement_ = node; 274 replacement_ = node;
275
276 if (FLAG_harmony_completion && !is_set_) {
277 is_set_ = true;
278 replacement_ = AssignUndefinedBefore(node);
279 }
233 } 280 }
234 281
235 282
236 void Processor::VisitSloppyBlockFunctionStatement( 283 void Processor::VisitSloppyBlockFunctionStatement(
237 SloppyBlockFunctionStatement* node) { 284 SloppyBlockFunctionStatement* node) {
238 Visit(node->statement()); 285 Visit(node->statement());
239 node->set_statement(replacement_); 286 node->set_statement(replacement_);
240 replacement_ = node; 287 replacement_ = node;
241 } 288 }
242 289
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 body->Add(result_statement, info->zone()); 354 body->Add(result_statement, info->zone());
308 } 355 }
309 } 356 }
310 357
311 return true; 358 return true;
312 } 359 }
313 360
314 361
315 } // namespace internal 362 } // namespace internal
316 } // namespace v8 363 } // namespace v8
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | test/mjsunit/es6/block-for.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698