OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/ast.h" | 5 #include "src/ast.h" |
6 #include "src/messages.h" | 6 #include "src/messages.h" |
7 #include "src/parser.h" | 7 #include "src/parser.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 | 10 |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 // and add it to the initialization statement block. | 164 // and add it to the initialization statement block. |
165 initialize = | 165 initialize = |
166 factory()->NewCallRuntime(Runtime::kInitializeVarGlobal, arguments, | 166 factory()->NewCallRuntime(Runtime::kInitializeVarGlobal, arguments, |
167 descriptor_->declaration_pos); | 167 descriptor_->declaration_pos); |
168 } else { | 168 } else { |
169 initialize = NULL; | 169 initialize = NULL; |
170 } | 170 } |
171 } | 171 } |
172 | 172 |
173 if (initialize != NULL) { | 173 if (initialize != NULL) { |
174 block_->AddStatement( | 174 block_->statements()->Add( |
175 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), | 175 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), |
176 zone()); | 176 zone()); |
177 } | 177 } |
178 } else if (value != nullptr && (descriptor_->needs_init || | 178 } else if (value != nullptr && (descriptor_->needs_init || |
179 IsLexicalVariableMode(descriptor_->mode))) { | 179 IsLexicalVariableMode(descriptor_->mode))) { |
180 // Constant initializations always assign to the declared constant which | 180 // Constant initializations always assign to the declared constant which |
181 // is always at the function scope level. This is only relevant for | 181 // is always at the function scope level. This is only relevant for |
182 // dynamically looked-up variables and constants (the | 182 // dynamically looked-up variables and constants (the |
183 // start context for constant lookups is always the function context, | 183 // start context for constant lookups is always the function context, |
184 // while it is the top context for var declared variables). Sigh... | 184 // while it is the top context for var declared variables). Sigh... |
185 // For 'let' and 'const' declared variables in harmony mode the | 185 // For 'let' and 'const' declared variables in harmony mode the |
186 // initialization also always assigns to the declared variable. | 186 // initialization also always assigns to the declared variable. |
187 DCHECK_NOT_NULL(proxy); | 187 DCHECK_NOT_NULL(proxy); |
188 DCHECK_NOT_NULL(proxy->var()); | 188 DCHECK_NOT_NULL(proxy->var()); |
189 DCHECK_NOT_NULL(value); | 189 DCHECK_NOT_NULL(value); |
190 Assignment* assignment = factory()->NewAssignment( | 190 Assignment* assignment = factory()->NewAssignment( |
191 descriptor_->init_op, proxy, value, descriptor_->initialization_pos); | 191 descriptor_->init_op, proxy, value, descriptor_->initialization_pos); |
192 block_->AddStatement( | 192 block_->statements()->Add( |
193 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), | 193 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), |
194 zone()); | 194 zone()); |
195 value = NULL; | 195 value = NULL; |
196 } | 196 } |
197 | 197 |
198 // Add an assignment node to the initialization statement block if we still | 198 // Add an assignment node to the initialization statement block if we still |
199 // have a pending initialization value. | 199 // have a pending initialization value. |
200 if (value != NULL) { | 200 if (value != NULL) { |
201 DCHECK(descriptor_->mode == VAR); | 201 DCHECK(descriptor_->mode == VAR); |
202 // 'var' initializations are simply assignments (with all the consequences | 202 // 'var' initializations are simply assignments (with all the consequences |
203 // if they are inside a 'with' statement - they may change a 'with' object | 203 // if they are inside a 'with' statement - they may change a 'with' object |
204 // property). | 204 // property). |
205 VariableProxy* proxy = initialization_scope->NewUnresolved(factory(), name); | 205 VariableProxy* proxy = initialization_scope->NewUnresolved(factory(), name); |
206 Assignment* assignment = factory()->NewAssignment( | 206 Assignment* assignment = factory()->NewAssignment( |
207 descriptor_->init_op, proxy, value, descriptor_->initialization_pos); | 207 descriptor_->init_op, proxy, value, descriptor_->initialization_pos); |
208 block_->AddStatement( | 208 block_->statements()->Add( |
209 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), | 209 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), |
210 zone()); | 210 zone()); |
211 } | 211 } |
212 } | 212 } |
213 | 213 |
214 | 214 |
215 Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) { | 215 Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) { |
216 auto temp = descriptor_->parser->scope_->NewTemporary( | 216 auto temp = descriptor_->parser->scope_->NewTemporary( |
217 ast_value_factory()->empty_string()); | 217 ast_value_factory()->empty_string()); |
218 if (value != nullptr) { | 218 if (value != nullptr) { |
219 auto assignment = factory()->NewAssignment( | 219 auto assignment = factory()->NewAssignment( |
220 Token::ASSIGN, factory()->NewVariableProxy(temp), value, | 220 Token::ASSIGN, factory()->NewVariableProxy(temp), value, |
221 RelocInfo::kNoPosition); | 221 RelocInfo::kNoPosition); |
222 | 222 |
223 block_->AddStatement( | 223 block_->statements()->Add( |
224 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), | 224 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), |
225 zone()); | 225 zone()); |
226 } | 226 } |
227 return temp; | 227 return temp; |
228 } | 228 } |
229 | 229 |
230 | 230 |
231 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern) { | 231 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern) { |
232 auto temp = CreateTempVar(current_value_); | 232 auto temp = CreateTempVar(current_value_); |
233 | 233 |
234 block_->AddStatement(descriptor_->parser->BuildAssertIsCoercible(temp), | 234 block_->statements()->Add(descriptor_->parser->BuildAssertIsCoercible(temp), |
235 zone()); | 235 zone()); |
236 | 236 |
237 for (ObjectLiteralProperty* property : *pattern->properties()) { | 237 for (ObjectLiteralProperty* property : *pattern->properties()) { |
238 RecurseIntoSubpattern( | 238 RecurseIntoSubpattern( |
239 property->value(), | 239 property->value(), |
240 factory()->NewProperty(factory()->NewVariableProxy(temp), | 240 factory()->NewProperty(factory()->NewVariableProxy(temp), |
241 property->key(), RelocInfo::kNoPosition)); | 241 property->key(), RelocInfo::kNoPosition)); |
242 } | 242 } |
243 } | 243 } |
244 | 244 |
245 | 245 |
(...skipping 11 matching lines...) Expand all Loading... |
257 spread = value->AsSpread(); | 257 spread = value->AsSpread(); |
258 break; | 258 break; |
259 } | 259 } |
260 | 260 |
261 // if (!done) { | 261 // if (!done) { |
262 // result = IteratorNext(iterator); | 262 // result = IteratorNext(iterator); |
263 // v = (done = result.done) ? undefined : result.value; | 263 // v = (done = result.done) ? undefined : result.value; |
264 // } | 264 // } |
265 auto next_block = | 265 auto next_block = |
266 factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition); | 266 factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition); |
267 next_block->AddStatement(factory()->NewExpressionStatement( | 267 next_block->statements()->Add( |
268 descriptor_->parser->BuildIteratorNextResult( | 268 factory()->NewExpressionStatement( |
269 factory()->NewVariableProxy(iterator), | 269 descriptor_->parser->BuildIteratorNextResult( |
270 result, RelocInfo::kNoPosition), | 270 factory()->NewVariableProxy(iterator), result, |
271 RelocInfo::kNoPosition), | 271 RelocInfo::kNoPosition), |
272 zone()); | 272 RelocInfo::kNoPosition), |
| 273 zone()); |
273 | 274 |
274 auto assign_to_done = factory()->NewAssignment( | 275 auto assign_to_done = factory()->NewAssignment( |
275 Token::ASSIGN, factory()->NewVariableProxy(done), | 276 Token::ASSIGN, factory()->NewVariableProxy(done), |
276 factory()->NewProperty( | 277 factory()->NewProperty( |
277 factory()->NewVariableProxy(result), | 278 factory()->NewVariableProxy(result), |
278 factory()->NewStringLiteral(ast_value_factory()->done_string(), | 279 factory()->NewStringLiteral(ast_value_factory()->done_string(), |
279 RelocInfo::kNoPosition), | 280 RelocInfo::kNoPosition), |
280 RelocInfo::kNoPosition), | 281 RelocInfo::kNoPosition), |
281 RelocInfo::kNoPosition); | 282 RelocInfo::kNoPosition); |
282 auto next_value = factory()->NewConditional( | 283 auto next_value = factory()->NewConditional( |
283 assign_to_done, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), | 284 assign_to_done, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), |
284 factory()->NewProperty( | 285 factory()->NewProperty( |
285 factory()->NewVariableProxy(result), | 286 factory()->NewVariableProxy(result), |
286 factory()->NewStringLiteral(ast_value_factory()->value_string(), | 287 factory()->NewStringLiteral(ast_value_factory()->value_string(), |
287 RelocInfo::kNoPosition), | 288 RelocInfo::kNoPosition), |
288 RelocInfo::kNoPosition), | 289 RelocInfo::kNoPosition), |
289 RelocInfo::kNoPosition); | 290 RelocInfo::kNoPosition); |
290 next_block->AddStatement( | 291 next_block->statements()->Add( |
291 factory()->NewExpressionStatement( | 292 factory()->NewExpressionStatement( |
292 factory()->NewAssignment(Token::ASSIGN, | 293 factory()->NewAssignment(Token::ASSIGN, |
293 factory()->NewVariableProxy(v), next_value, | 294 factory()->NewVariableProxy(v), next_value, |
294 RelocInfo::kNoPosition), | 295 RelocInfo::kNoPosition), |
295 RelocInfo::kNoPosition), | 296 RelocInfo::kNoPosition), |
296 zone()); | 297 zone()); |
297 | 298 |
298 auto if_statement = factory()->NewIfStatement( | 299 auto if_statement = factory()->NewIfStatement( |
299 factory()->NewUnaryOperation(Token::NOT, | 300 factory()->NewUnaryOperation(Token::NOT, |
300 factory()->NewVariableProxy(done), | 301 factory()->NewVariableProxy(done), |
301 RelocInfo::kNoPosition), | 302 RelocInfo::kNoPosition), |
302 next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition), | 303 next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition), |
303 RelocInfo::kNoPosition); | 304 RelocInfo::kNoPosition); |
304 block_->AddStatement(if_statement, zone()); | 305 block_->statements()->Add(if_statement, zone()); |
305 | 306 |
306 if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) { | 307 if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) { |
307 RecurseIntoSubpattern(value, factory()->NewVariableProxy(v)); | 308 RecurseIntoSubpattern(value, factory()->NewVariableProxy(v)); |
308 } | 309 } |
309 } | 310 } |
310 | 311 |
311 if (spread != nullptr) { | 312 if (spread != nullptr) { |
312 // array = []; | 313 // array = []; |
313 // if (!done) %concat_iterable_to_array(array, iterator); | 314 // if (!done) %concat_iterable_to_array(array, iterator); |
314 auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone()); | 315 auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone()); |
(...skipping 12 matching lines...) Expand all Loading... |
327 arguments, RelocInfo::kNoPosition); | 328 arguments, RelocInfo::kNoPosition); |
328 | 329 |
329 auto if_statement = factory()->NewIfStatement( | 330 auto if_statement = factory()->NewIfStatement( |
330 factory()->NewUnaryOperation(Token::NOT, | 331 factory()->NewUnaryOperation(Token::NOT, |
331 factory()->NewVariableProxy(done), | 332 factory()->NewVariableProxy(done), |
332 RelocInfo::kNoPosition), | 333 RelocInfo::kNoPosition), |
333 factory()->NewExpressionStatement(spread_into_array_call, | 334 factory()->NewExpressionStatement(spread_into_array_call, |
334 RelocInfo::kNoPosition), | 335 RelocInfo::kNoPosition), |
335 factory()->NewEmptyStatement(RelocInfo::kNoPosition), | 336 factory()->NewEmptyStatement(RelocInfo::kNoPosition), |
336 RelocInfo::kNoPosition); | 337 RelocInfo::kNoPosition); |
337 block_->AddStatement(if_statement, zone()); | 338 block_->statements()->Add(if_statement, zone()); |
338 | |
339 | 339 |
340 RecurseIntoSubpattern(spread->expression(), | 340 RecurseIntoSubpattern(spread->expression(), |
341 factory()->NewVariableProxy(array)); | 341 factory()->NewVariableProxy(array)); |
342 } | 342 } |
343 } | 343 } |
344 | 344 |
345 | 345 |
346 void Parser::PatternRewriter::VisitAssignment(Assignment* node) { | 346 void Parser::PatternRewriter::VisitAssignment(Assignment* node) { |
347 // let {<pattern> = <init>} = <value> | 347 // let {<pattern> = <init>} = <value> |
348 // becomes | 348 // becomes |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 NOT_A_PATTERN(TryFinallyStatement) | 411 NOT_A_PATTERN(TryFinallyStatement) |
412 NOT_A_PATTERN(UnaryOperation) | 412 NOT_A_PATTERN(UnaryOperation) |
413 NOT_A_PATTERN(VariableDeclaration) | 413 NOT_A_PATTERN(VariableDeclaration) |
414 NOT_A_PATTERN(WhileStatement) | 414 NOT_A_PATTERN(WhileStatement) |
415 NOT_A_PATTERN(WithStatement) | 415 NOT_A_PATTERN(WithStatement) |
416 NOT_A_PATTERN(Yield) | 416 NOT_A_PATTERN(Yield) |
417 | 417 |
418 #undef NOT_A_PATTERN | 418 #undef NOT_A_PATTERN |
419 } // namespace internal | 419 } // namespace internal |
420 } // namespace v8 | 420 } // namespace v8 |
OLD | NEW |