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 |