Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: src/parsing/parser.cc

Issue 1980483003: [es6] Reintroduce the instanceof operator in the backends. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Igors comments. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698