| 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 6348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6359 do_block->statements()->Add(get_value, zone); | 6359 do_block->statements()->Add(get_value, zone); |
| 6360 | 6360 |
| 6361 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); | 6361 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); |
| 6362 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); | 6362 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); |
| 6363 Rewriter::Rewrite(parser_, yield_star, avfactory); | 6363 Rewriter::Rewrite(parser_, yield_star, avfactory); |
| 6364 } | 6364 } |
| 6365 | 6365 |
| 6366 return yield_star; | 6366 return yield_star; |
| 6367 } | 6367 } |
| 6368 | 6368 |
| 6369 // Desugaring of (lhs) instanceof (rhs) | |
| 6370 // ==================================== | |
| 6371 // | |
| 6372 // We desugar instanceof into a load of property @@hasInstance on the rhs. | |
| 6373 // We end up with roughly the following code (O, C): | |
| 6374 // | |
| 6375 // do { | |
| 6376 // let O = lhs; | |
| 6377 // let C = rhs; | |
| 6378 // if (!IS_RECEIVER(C)) throw MakeTypeError(kNonObjectInInstanceOfCheck); | |
| 6379 // let handler_result = C[Symbol.hasInstance]; | |
| 6380 // if (handler_result === undefined) { | |
| 6381 // if (!IS_CALLABLE(C)) { | |
| 6382 // throw MakeTypeError(kCalledNonCallableInstanceOf); | |
| 6383 // } | |
| 6384 // handler_result = %_GetOrdinaryHasInstance() | |
| 6385 // handler_result = %_Call(handler_result, C, O); | |
| 6386 // } else { | |
| 6387 // handler_result = !!(%_Call(handler_result, C, O)); | |
| 6388 // } | |
| 6389 // handler_result; | |
| 6390 // } | |
| 6391 // | |
| 6392 Expression* ParserTraits::RewriteInstanceof(Expression* lhs, Expression* rhs, | |
| 6393 int pos) { | |
| 6394 const int nopos = RelocInfo::kNoPosition; | |
| 6395 | |
| 6396 auto factory = parser_->factory(); | |
| 6397 auto avfactory = parser_->ast_value_factory(); | |
| 6398 auto scope = parser_->scope_; | |
| 6399 auto zone = parser_->zone(); | |
| 6400 | |
| 6401 // let O = lhs; | |
| 6402 Variable* var_O = scope->NewTemporary(avfactory->empty_string()); | |
| 6403 Statement* get_O; | |
| 6404 { | |
| 6405 Expression* O_proxy = factory->NewVariableProxy(var_O); | |
| 6406 Expression* assignment = | |
| 6407 factory->NewAssignment(Token::ASSIGN, O_proxy, lhs, nopos); | |
| 6408 get_O = factory->NewExpressionStatement(assignment, nopos); | |
| 6409 } | |
| 6410 | |
| 6411 // let C = lhs; | |
| 6412 Variable* var_C = scope->NewTemporary(avfactory->empty_string()); | |
| 6413 Statement* get_C; | |
| 6414 { | |
| 6415 Expression* C_proxy = factory->NewVariableProxy(var_C); | |
| 6416 Expression* assignment = | |
| 6417 factory->NewAssignment(Token::ASSIGN, C_proxy, rhs, nopos); | |
| 6418 get_C = factory->NewExpressionStatement(assignment, nopos); | |
| 6419 } | |
| 6420 | |
| 6421 // if (!IS_RECEIVER(C)) throw MakeTypeError(kNonObjectInInstanceOfCheck); | |
| 6422 Statement* validate_C; | |
| 6423 { | |
| 6424 auto args = new (zone) ZoneList<Expression*>(1, zone); | |
| 6425 args->Add(factory->NewVariableProxy(var_C), zone); | |
| 6426 Expression* is_receiver_call = | |
| 6427 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); | |
| 6428 Expression* call = | |
| 6429 NewThrowTypeError(MessageTemplate::kNonObjectInInstanceOfCheck, | |
| 6430 avfactory->empty_string(), pos); | |
| 6431 Statement* throw_call = factory->NewExpressionStatement(call, pos); | |
| 6432 | |
| 6433 validate_C = | |
| 6434 factory->NewIfStatement(is_receiver_call, | |
| 6435 factory->NewEmptyStatement(nopos), | |
| 6436 throw_call, | |
| 6437 nopos); | |
| 6438 } | |
| 6439 | |
| 6440 // let handler_result = C[Symbol.hasInstance]; | |
| 6441 Variable* var_handler_result = scope->NewTemporary(avfactory->empty_string()); | |
| 6442 Statement* initialize_handler; | |
| 6443 { | |
| 6444 Expression* hasInstance_symbol_literal = | |
| 6445 factory->NewSymbolLiteral("hasInstance_symbol", RelocInfo::kNoPosition); | |
| 6446 Expression* prop = factory->NewProperty(factory->NewVariableProxy(var_C), | |
| 6447 hasInstance_symbol_literal, pos); | |
| 6448 Expression* handler_proxy = factory->NewVariableProxy(var_handler_result); | |
| 6449 Expression* assignment = | |
| 6450 factory->NewAssignment(Token::ASSIGN, handler_proxy, prop, nopos); | |
| 6451 initialize_handler = factory->NewExpressionStatement(assignment, nopos); | |
| 6452 } | |
| 6453 | |
| 6454 // if (handler_result === undefined) { | |
| 6455 // if (!IS_CALLABLE(C)) { | |
| 6456 // throw MakeTypeError(kCalledNonCallableInstanceOf); | |
| 6457 // } | |
| 6458 // handler_result = %_GetOrdinaryHasInstance() | |
| 6459 // handler_result = %_Call(handler_result, C, O); | |
| 6460 // } else { | |
| 6461 // handler_result = !!%_Call(handler_result, C, O); | |
| 6462 // } | |
| 6463 Statement* call_handler; | |
| 6464 { | |
| 6465 Expression* condition = factory->NewCompareOperation( | |
| 6466 Token::EQ_STRICT, factory->NewVariableProxy(var_handler_result), | |
| 6467 factory->NewUndefinedLiteral(nopos), nopos); | |
| 6468 | |
| 6469 Block* then_side = factory->NewBlock(nullptr, 3, false, nopos); | |
| 6470 { | |
| 6471 Expression* throw_expr = | |
| 6472 NewThrowTypeError(MessageTemplate::kCalledNonCallableInstanceOf, | |
| 6473 avfactory->empty_string(), pos); | |
| 6474 Statement* validate_C = CheckCallable(var_C, throw_expr, pos); | |
| 6475 | |
| 6476 ZoneList<Expression*>* empty_args = | |
| 6477 new (zone) ZoneList<Expression*>(0, zone); | |
| 6478 Expression* ordinary_has_instance = factory->NewCallRuntime( | |
| 6479 Runtime::kInlineGetOrdinaryHasInstance, empty_args, pos); | |
| 6480 Expression* handler_proxy = factory->NewVariableProxy(var_handler_result); | |
| 6481 Expression* assignment_handler = factory->NewAssignment( | |
| 6482 Token::ASSIGN, handler_proxy, ordinary_has_instance, nopos); | |
| 6483 Statement* assignment_get_handler = | |
| 6484 factory->NewExpressionStatement(assignment_handler, nopos); | |
| 6485 | |
| 6486 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(3, zone); | |
| 6487 args->Add(factory->NewVariableProxy(var_handler_result), zone); | |
| 6488 args->Add(factory->NewVariableProxy(var_C), zone); | |
| 6489 args->Add(factory->NewVariableProxy(var_O), zone); | |
| 6490 Expression* call = | |
| 6491 factory->NewCallRuntime(Runtime::kInlineCall, args, pos); | |
| 6492 Expression* result_proxy = factory->NewVariableProxy(var_handler_result); | |
| 6493 Expression* assignment = | |
| 6494 factory->NewAssignment(Token::ASSIGN, result_proxy, call, nopos); | |
| 6495 Statement* assignment_return = | |
| 6496 factory->NewExpressionStatement(assignment, nopos); | |
| 6497 | |
| 6498 then_side->statements()->Add(validate_C, zone); | |
| 6499 then_side->statements()->Add(assignment_get_handler, zone); | |
| 6500 then_side->statements()->Add(assignment_return, zone); | |
| 6501 } | |
| 6502 | |
| 6503 Statement* else_side; | |
| 6504 { | |
| 6505 auto args = new (zone) ZoneList<Expression*>(3, zone); | |
| 6506 args->Add(factory->NewVariableProxy(var_handler_result), zone); | |
| 6507 args->Add(factory->NewVariableProxy(var_C), zone); | |
| 6508 args->Add(factory->NewVariableProxy(var_O), zone); | |
| 6509 Expression* call = | |
| 6510 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); | |
| 6511 Expression* inner_not = | |
| 6512 factory->NewUnaryOperation(Token::NOT, call, nopos); | |
| 6513 Expression* outer_not = | |
| 6514 factory->NewUnaryOperation(Token::NOT, inner_not, nopos); | |
| 6515 Expression* result_proxy = factory->NewVariableProxy(var_handler_result); | |
| 6516 Expression* assignment = | |
| 6517 factory->NewAssignment(Token::ASSIGN, result_proxy, outer_not, nopos); | |
| 6518 | |
| 6519 else_side = factory->NewExpressionStatement(assignment, nopos); | |
| 6520 } | |
| 6521 call_handler = | |
| 6522 factory->NewIfStatement(condition, then_side, else_side, nopos); | |
| 6523 } | |
| 6524 | |
| 6525 // do { ... } | |
| 6526 DoExpression* instanceof; | |
| 6527 { | |
| 6528 Block* block = factory->NewBlock(nullptr, 5, true, nopos); | |
| 6529 block->statements()->Add(get_O, zone); | |
| 6530 block->statements()->Add(get_C, zone); | |
| 6531 block->statements()->Add(validate_C, zone); | |
| 6532 block->statements()->Add(initialize_handler, zone); | |
| 6533 block->statements()->Add(call_handler, zone); | |
| 6534 | |
| 6535 // Here is the desugared instanceof. | |
| 6536 instanceof = factory->NewDoExpression(block, var_handler_result, nopos); | |
| 6537 Rewriter::Rewrite(parser_, instanceof, avfactory); | |
| 6538 } | |
| 6539 | |
| 6540 return instanceof; | |
| 6541 } | |
| 6542 | |
| 6543 Statement* ParserTraits::CheckCallable(Variable* var, Expression* error, | 6369 Statement* ParserTraits::CheckCallable(Variable* var, Expression* error, |
| 6544 int pos) { | 6370 int pos) { |
| 6545 auto factory = parser_->factory(); | 6371 auto factory = parser_->factory(); |
| 6546 auto avfactory = parser_->ast_value_factory(); | 6372 auto avfactory = parser_->ast_value_factory(); |
| 6547 const int nopos = RelocInfo::kNoPosition; | 6373 const int nopos = RelocInfo::kNoPosition; |
| 6548 Statement* validate_var; | 6374 Statement* validate_var; |
| 6549 { | 6375 { |
| 6550 Expression* type_of = factory->NewUnaryOperation( | 6376 Expression* type_of = factory->NewUnaryOperation( |
| 6551 Token::TYPEOF, factory->NewVariableProxy(var), nopos); | 6377 Token::TYPEOF, factory->NewVariableProxy(var), nopos); |
| 6552 Expression* function_literal = | 6378 Expression* function_literal = |
| (...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7083 try_block, target); | 6909 try_block, target); |
| 7084 final_loop = target; | 6910 final_loop = target; |
| 7085 } | 6911 } |
| 7086 | 6912 |
| 7087 return final_loop; | 6913 return final_loop; |
| 7088 } | 6914 } |
| 7089 | 6915 |
| 7090 | 6916 |
| 7091 } // namespace internal | 6917 } // namespace internal |
| 7092 } // namespace v8 | 6918 } // namespace v8 |
| OLD | NEW |