OLD | NEW |
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/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/ast-expression-rewriter.h" | 9 #include "src/ast/ast-expression-rewriter.h" |
10 #include "src/ast/ast-expression-visitor.h" | 10 #include "src/ast/ast-expression-visitor.h" |
(...skipping 6274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6285 do_block->statements()->Add(get_value, zone); | 6285 do_block->statements()->Add(get_value, zone); |
6286 | 6286 |
6287 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); | 6287 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); |
6288 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); | 6288 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); |
6289 Rewriter::Rewrite(parser_, yield_star, avfactory); | 6289 Rewriter::Rewrite(parser_, yield_star, avfactory); |
6290 } | 6290 } |
6291 | 6291 |
6292 return yield_star; | 6292 return yield_star; |
6293 } | 6293 } |
6294 | 6294 |
| 6295 // Desugaring of (lhs) instanceof (rhs) |
| 6296 // ==================================== |
| 6297 // |
| 6298 // We desugar instanceof into a load of property @@hasInstance on the rhs. |
| 6299 // We end up with roughly the following code (O, C): |
| 6300 // |
| 6301 // do { |
| 6302 // let O = lhs; |
| 6303 // let C = rhs; |
| 6304 // if (!IS_RECEIVER(C)) throw MakeTypeError(kNonObjectInInstanceOfCheck); |
| 6305 // let handler_result = C[Symbol.hasInstance]; |
| 6306 // if (handler_result === undefined) { |
| 6307 // if (!IS_CALLABLE(C)) { |
| 6308 // throw MakeTypeError(kCalledNonCallableInstanceOf); |
| 6309 // } |
| 6310 // handler_result = %ordinary_has_instance(C, O); |
| 6311 // } else { |
| 6312 // handler_result = !!(%_Call(handler_result, C, O)); |
| 6313 // } |
| 6314 // handler_result; |
| 6315 // } |
| 6316 // |
| 6317 Expression* ParserTraits::RewriteInstanceof(Expression* lhs, Expression* rhs, |
| 6318 int pos) { |
| 6319 const int nopos = RelocInfo::kNoPosition; |
| 6320 |
| 6321 auto factory = parser_->factory(); |
| 6322 auto avfactory = parser_->ast_value_factory(); |
| 6323 auto scope = parser_->scope_; |
| 6324 auto zone = parser_->zone(); |
| 6325 |
| 6326 // let O = lhs; |
| 6327 Variable* var_O = scope->NewTemporary(avfactory->empty_string()); |
| 6328 Statement* get_O; |
| 6329 { |
| 6330 Expression* O_proxy = factory->NewVariableProxy(var_O); |
| 6331 Expression* assignment = |
| 6332 factory->NewAssignment(Token::ASSIGN, O_proxy, lhs, nopos); |
| 6333 get_O = factory->NewExpressionStatement(assignment, nopos); |
| 6334 } |
| 6335 |
| 6336 // let C = lhs; |
| 6337 Variable* var_C = scope->NewTemporary(avfactory->empty_string()); |
| 6338 Statement* get_C; |
| 6339 { |
| 6340 Expression* C_proxy = factory->NewVariableProxy(var_C); |
| 6341 Expression* assignment = |
| 6342 factory->NewAssignment(Token::ASSIGN, C_proxy, rhs, nopos); |
| 6343 get_C = factory->NewExpressionStatement(assignment, nopos); |
| 6344 } |
| 6345 |
| 6346 // if (!IS_RECEIVER(C)) throw MakeTypeError(kNonObjectInInstanceOfCheck); |
| 6347 Statement* validate_C; |
| 6348 { |
| 6349 auto args = new (zone) ZoneList<Expression*>(1, zone); |
| 6350 args->Add(factory->NewVariableProxy(var_C), zone); |
| 6351 Expression* is_receiver_call = |
| 6352 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); |
| 6353 Expression* call = |
| 6354 NewThrowTypeError(MessageTemplate::kNonObjectInInstanceOfCheck, |
| 6355 avfactory->empty_string(), nopos); |
| 6356 Statement* throw_call = factory->NewExpressionStatement(call, nopos); |
| 6357 |
| 6358 validate_C = |
| 6359 factory->NewIfStatement(is_receiver_call, |
| 6360 factory->NewEmptyStatement(nopos), |
| 6361 throw_call, |
| 6362 nopos); |
| 6363 } |
| 6364 |
| 6365 // let handler_result = C[Symbol.hasInstance]; |
| 6366 Variable* var_handler_result = scope->NewTemporary(avfactory->empty_string()); |
| 6367 Statement* initialize_handler; |
| 6368 { |
| 6369 Expression* hasInstance_symbol_literal = |
| 6370 factory->NewSymbolLiteral("hasInstance_symbol", RelocInfo::kNoPosition); |
| 6371 Expression* prop = factory->NewProperty(factory->NewVariableProxy(var_C), |
| 6372 hasInstance_symbol_literal, pos); |
| 6373 Expression* handler_proxy = factory->NewVariableProxy(var_handler_result); |
| 6374 Expression* assignment = |
| 6375 factory->NewAssignment(Token::ASSIGN, handler_proxy, prop, nopos); |
| 6376 initialize_handler = factory->NewExpressionStatement(assignment, nopos); |
| 6377 } |
| 6378 |
| 6379 // if (handler_result === undefined) { |
| 6380 // if (!IS_CALLABLE(C)) { |
| 6381 // throw MakeTypeError(kCalledNonCallableInstanceOf); |
| 6382 // } |
| 6383 // result = %ordinary_has_instance(C, O); |
| 6384 // } else { |
| 6385 // handler_result = !!%_Call(handler_result, C, O); |
| 6386 // } |
| 6387 Statement* call_handler; |
| 6388 { |
| 6389 Expression* condition = factory->NewCompareOperation( |
| 6390 Token::EQ_STRICT, factory->NewVariableProxy(var_handler_result), |
| 6391 factory->NewUndefinedLiteral(nopos), nopos); |
| 6392 |
| 6393 Block* then_side = factory->NewBlock(nullptr, 2, false, nopos); |
| 6394 { |
| 6395 Expression* throw_expr = |
| 6396 NewThrowTypeError(MessageTemplate::kCalledNonCallableInstanceOf, |
| 6397 avfactory->empty_string(), nopos); |
| 6398 Statement* validate_C = CheckCallable(var_C, throw_expr); |
| 6399 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone); |
| 6400 args->Add(factory->NewVariableProxy(var_C), zone); |
| 6401 args->Add(factory->NewVariableProxy(var_O), zone); |
| 6402 CallRuntime* call = factory->NewCallRuntime( |
| 6403 Context::ORDINARY_HAS_INSTANCE_INDEX, args, pos); |
| 6404 Expression* result_proxy = factory->NewVariableProxy(var_handler_result); |
| 6405 Expression* assignment = |
| 6406 factory->NewAssignment(Token::ASSIGN, result_proxy, call, nopos); |
| 6407 Statement* assignment_return = |
| 6408 factory->NewExpressionStatement(assignment, nopos); |
| 6409 |
| 6410 then_side->statements()->Add(validate_C, zone); |
| 6411 then_side->statements()->Add(assignment_return, zone); |
| 6412 } |
| 6413 |
| 6414 Statement* else_side; |
| 6415 { |
| 6416 auto args = new (zone) ZoneList<Expression*>(3, zone); |
| 6417 args->Add(factory->NewVariableProxy(var_handler_result), zone); |
| 6418 args->Add(factory->NewVariableProxy(var_C), zone); |
| 6419 args->Add(factory->NewVariableProxy(var_O), zone); |
| 6420 Expression* call = |
| 6421 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
| 6422 Expression* inner_not = |
| 6423 factory->NewUnaryOperation(Token::NOT, call, nopos); |
| 6424 Expression* outer_not = |
| 6425 factory->NewUnaryOperation(Token::NOT, inner_not, nopos); |
| 6426 Expression* result_proxy = factory->NewVariableProxy(var_handler_result); |
| 6427 Expression* assignment = |
| 6428 factory->NewAssignment(Token::ASSIGN, result_proxy, outer_not, nopos); |
| 6429 |
| 6430 else_side = factory->NewExpressionStatement(assignment, nopos); |
| 6431 } |
| 6432 call_handler = |
| 6433 factory->NewIfStatement(condition, then_side, else_side, nopos); |
| 6434 } |
| 6435 |
| 6436 // do { ... } |
| 6437 DoExpression* instanceof; |
| 6438 { |
| 6439 Block* block = factory->NewBlock(nullptr, 5, true, nopos); |
| 6440 block->statements()->Add(get_O, zone); |
| 6441 block->statements()->Add(get_C, zone); |
| 6442 block->statements()->Add(validate_C, zone); |
| 6443 block->statements()->Add(initialize_handler, zone); |
| 6444 block->statements()->Add(call_handler, zone); |
| 6445 |
| 6446 // Here is the desugared instanceof. |
| 6447 instanceof = factory->NewDoExpression(block, var_handler_result, nopos); |
| 6448 Rewriter::Rewrite(parser_, instanceof, avfactory); |
| 6449 } |
| 6450 |
| 6451 return instanceof; |
| 6452 } |
| 6453 |
| 6454 Statement* ParserTraits::CheckCallable(Variable* var, Expression* error) { |
| 6455 auto factory = parser_->factory(); |
| 6456 auto avfactory = parser_->ast_value_factory(); |
| 6457 const int nopos = RelocInfo::kNoPosition; |
| 6458 Statement* validate_var; |
| 6459 { |
| 6460 Expression* type_of = factory->NewUnaryOperation( |
| 6461 Token::TYPEOF, factory->NewVariableProxy(var), nopos); |
| 6462 Expression* function_literal = |
| 6463 factory->NewStringLiteral(avfactory->function_string(), nopos); |
| 6464 Expression* condition = factory->NewCompareOperation( |
| 6465 Token::EQ_STRICT, type_of, function_literal, nopos); |
| 6466 |
| 6467 Statement* throw_call = factory->NewExpressionStatement(error, nopos); |
| 6468 |
| 6469 validate_var = factory->NewIfStatement( |
| 6470 condition, factory->NewEmptyStatement(nopos), throw_call, nopos); |
| 6471 } |
| 6472 return validate_var; |
| 6473 } |
6295 | 6474 |
6296 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, | 6475 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, |
6297 Variable* iterator, | 6476 Variable* iterator, |
6298 Expression* input, | 6477 Expression* input, |
6299 Variable* var_output) { | 6478 Variable* var_output) { |
6300 // | 6479 // |
6301 // This function adds four statements to [statements], corresponding to the | 6480 // This function adds four statements to [statements], corresponding to the |
6302 // following code: | 6481 // following code: |
6303 // | 6482 // |
6304 // let iteratorReturn = iterator.return; | 6483 // let iteratorReturn = iterator.return; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6433 Expression* assignment = factory->NewAssignment( | 6612 Expression* assignment = factory->NewAssignment( |
6434 Token::ASSIGN, return_proxy, property, nopos); | 6613 Token::ASSIGN, return_proxy, property, nopos); |
6435 get_return = factory->NewExpressionStatement(assignment, nopos); | 6614 get_return = factory->NewExpressionStatement(assignment, nopos); |
6436 } | 6615 } |
6437 | 6616 |
6438 // if (!IS_CALLABLE(iteratorReturn)) { | 6617 // if (!IS_CALLABLE(iteratorReturn)) { |
6439 // throw MakeTypeError(kReturnMethodNotCallable); | 6618 // throw MakeTypeError(kReturnMethodNotCallable); |
6440 // } | 6619 // } |
6441 Statement* check_return_callable; | 6620 Statement* check_return_callable; |
6442 { | 6621 { |
6443 Expression* type_of = factory->NewUnaryOperation( | 6622 Expression* throw_expr = NewThrowTypeError( |
6444 Token::TYPEOF, factory->NewVariableProxy(var_return), nopos); | |
6445 Expression* function_literal = factory->NewStringLiteral( | |
6446 avfactory->function_string(), nopos); | |
6447 Expression* condition = factory->NewCompareOperation( | |
6448 Token::EQ_STRICT, type_of, function_literal, nopos); | |
6449 | |
6450 Expression* call = NewThrowTypeError( | |
6451 MessageTemplate::kReturnMethodNotCallable, | 6623 MessageTemplate::kReturnMethodNotCallable, |
6452 avfactory->empty_string(), nopos); | 6624 avfactory->empty_string(), nopos); |
6453 Statement* throw_call = factory->NewExpressionStatement(call, nopos); | 6625 check_return_callable = CheckCallable(var_return, throw_expr); |
6454 | |
6455 check_return_callable = factory->NewIfStatement( | |
6456 condition, factory->NewEmptyStatement(nopos), throw_call, nopos); | |
6457 } | 6626 } |
6458 | 6627 |
6459 // output = %_Call(iteratorReturn, iterator); | 6628 // output = %_Call(iteratorReturn, iterator); |
6460 Statement* call_return; | 6629 Statement* call_return; |
6461 { | 6630 { |
6462 auto args = new (zone) ZoneList<Expression*>(2, zone); | 6631 auto args = new (zone) ZoneList<Expression*>(2, zone); |
6463 args->Add(factory->NewVariableProxy(var_return), zone); | 6632 args->Add(factory->NewVariableProxy(var_return), zone); |
6464 args->Add(factory->NewVariableProxy(iterator), zone); | 6633 args->Add(factory->NewVariableProxy(iterator), zone); |
6465 Expression* call = | 6634 Expression* call = |
6466 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 6635 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6731 new_body->statements()->Add(loop->body(), zone); | 6900 new_body->statements()->Add(loop->body(), zone); |
6732 new_body->statements()->Add(set_completion_normal, zone); | 6901 new_body->statements()->Add(set_completion_normal, zone); |
6733 | 6902 |
6734 loop->set_body(new_body); | 6903 loop->set_body(new_body); |
6735 return final_loop; | 6904 return final_loop; |
6736 } | 6905 } |
6737 | 6906 |
6738 | 6907 |
6739 } // namespace internal | 6908 } // namespace internal |
6740 } // namespace v8 | 6909 } // namespace v8 |
OLD | NEW |