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