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

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

Issue 1692713005: ES6: Desugaring of instanceof to support @@hasInstance (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@blah
Patch Set: Disabled new test for ignition. Created 4 years, 10 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 6270 matching lines...) Expand 10 before | Expand all | Expand 10 after
6281 do_block->statements()->Add(get_value, zone); 6281 do_block->statements()->Add(get_value, zone);
6282 6282
6283 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); 6283 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string());
6284 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); 6284 yield_star = factory->NewDoExpression(do_block, dot_result, nopos);
6285 Rewriter::Rewrite(parser_, yield_star, avfactory); 6285 Rewriter::Rewrite(parser_, yield_star, avfactory);
6286 } 6286 }
6287 6287
6288 return yield_star; 6288 return yield_star;
6289 } 6289 }
6290 6290
6291 // Desugaring of (lhs) instanceof (rhs)
6292 // ====================================
6293 //
6294 // We desugar instanceof into a load of property @@hasInstance on the rhs.
6295 // We end up with roughly the following code (O, C):
6296 //
6297 // do {
6298 // let O = lhs;
6299 // let C = rhs;
6300 // if (!IS_RECEIVER(C)) throw MakeTypeError(kNonObjectInInstanceOfCheck);
6301 // let handler_result = C[Symbol.hasInstance];
6302 // if (handler_result === undefined) {
6303 // if (!IS_CALLABLE(C)) {
6304 // throw MakeTypeError(kCalledNonCallableInstanceOf);
6305 // }
6306 // handler_result = %ordinary_has_instance(C, O);
6307 // } else {
6308 // handler_result = !!(%_Call(handler_result, C, O));
6309 // }
6310 // handler_result;
6311 // }
6312 //
6313 Expression* ParserTraits::RewriteInstanceof(Expression* lhs, Expression* rhs,
6314 int pos) {
6315 const int nopos = RelocInfo::kNoPosition;
6316
6317 auto factory = parser_->factory();
6318 auto avfactory = parser_->ast_value_factory();
6319 auto scope = parser_->scope_;
6320 auto zone = parser_->zone();
6321
6322 // let O = lhs;
6323 Variable* var_O = scope->NewTemporary(avfactory->empty_string());
6324 Statement* get_O;
6325 {
6326 Expression* O_proxy = factory->NewVariableProxy(var_O);
6327 Expression* assignment =
6328 factory->NewAssignment(Token::ASSIGN, O_proxy, lhs, nopos);
6329 get_O = factory->NewExpressionStatement(assignment, nopos);
6330 }
6331
6332 // let C = lhs;
6333 Variable* var_C = scope->NewTemporary(avfactory->empty_string());
6334 Statement* get_C;
6335 {
6336 Expression* C_proxy = factory->NewVariableProxy(var_C);
6337 Expression* assignment =
6338 factory->NewAssignment(Token::ASSIGN, C_proxy, rhs, nopos);
6339 get_C = factory->NewExpressionStatement(assignment, nopos);
6340 }
6341
6342 // if (!IS_RECEIVER(C)) throw MakeTypeError(kNonObjectInInstanceOfCheck);
6343 Statement* validate_C;
6344 {
6345 auto args = new (zone) ZoneList<Expression*>(1, zone);
6346 args->Add(factory->NewVariableProxy(var_C), zone);
6347 Expression* is_receiver_call =
6348 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6349 Expression* call =
6350 NewThrowTypeError(MessageTemplate::kNonObjectInInstanceOfCheck,
6351 avfactory->empty_string(), nopos);
6352 Statement* throw_call = factory->NewExpressionStatement(call, nopos);
6353
6354 validate_C =
6355 factory->NewIfStatement(is_receiver_call,
6356 factory->NewEmptyStatement(nopos),
6357 throw_call,
6358 nopos);
6359 }
6360
6361 // let handler_result = C[Symbol.hasInstance];
6362 Variable* var_handler_result = scope->NewTemporary(avfactory->empty_string());
6363 Statement* initialize_handler;
6364 {
6365 Expression* hasInstance_symbol_literal =
6366 factory->NewSymbolLiteral("hasInstance_symbol", RelocInfo::kNoPosition);
6367 Expression* prop = factory->NewProperty(factory->NewVariableProxy(var_C),
6368 hasInstance_symbol_literal, pos);
6369 Expression* handler_proxy = factory->NewVariableProxy(var_handler_result);
6370 Expression* assignment =
6371 factory->NewAssignment(Token::ASSIGN, handler_proxy, prop, nopos);
6372 initialize_handler = factory->NewExpressionStatement(assignment, nopos);
6373 }
6374
6375 // if (handler_result === undefined) {
6376 // if (!IS_CALLABLE(C)) {
6377 // throw MakeTypeError(kCalledNonCallableInstanceOf);
6378 // }
6379 // result = %ordinary_has_instance(C, O);
6380 // } else {
6381 // handler_result = !!%_Call(handler_result, C, O);
6382 // }
6383 Statement* call_handler;
6384 {
6385 Expression* condition = factory->NewCompareOperation(
6386 Token::EQ_STRICT, factory->NewVariableProxy(var_handler_result),
6387 factory->NewUndefinedLiteral(nopos), nopos);
6388
6389 Block* then_side = factory->NewBlock(nullptr, 2, false, nopos);
6390 {
6391 Expression* throw_expr =
6392 NewThrowTypeError(MessageTemplate::kCalledNonCallableInstanceOf,
6393 avfactory->empty_string(), nopos);
6394 Statement* validate_C = CheckCallable(var_C, throw_expr);
6395 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone);
6396 args->Add(factory->NewVariableProxy(var_C), zone);
6397 args->Add(factory->NewVariableProxy(var_O), zone);
6398 CallRuntime* call = factory->NewCallRuntime(
6399 Context::ORDINARY_HAS_INSTANCE_INDEX, args, pos);
6400 Expression* result_proxy = factory->NewVariableProxy(var_handler_result);
6401 Expression* assignment =
6402 factory->NewAssignment(Token::ASSIGN, result_proxy, call, nopos);
6403 Statement* assignment_return =
6404 factory->NewExpressionStatement(assignment, nopos);
6405
6406 then_side->statements()->Add(validate_C, zone);
6407 then_side->statements()->Add(assignment_return, zone);
6408 }
6409
6410 Statement* else_side;
6411 {
6412 auto args = new (zone) ZoneList<Expression*>(3, zone);
6413 args->Add(factory->NewVariableProxy(var_handler_result), zone);
6414 args->Add(factory->NewVariableProxy(var_C), zone);
6415 args->Add(factory->NewVariableProxy(var_O), zone);
6416 Expression* call =
6417 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6418 Expression* inner_not =
6419 factory->NewUnaryOperation(Token::NOT, call, nopos);
6420 Expression* outer_not =
6421 factory->NewUnaryOperation(Token::NOT, inner_not, nopos);
6422 Expression* result_proxy = factory->NewVariableProxy(var_handler_result);
6423 Expression* assignment =
6424 factory->NewAssignment(Token::ASSIGN, result_proxy, outer_not, nopos);
6425
6426 else_side = factory->NewExpressionStatement(assignment, nopos);
6427 }
6428 call_handler =
6429 factory->NewIfStatement(condition, then_side, else_side, nopos);
6430 }
6431
6432 // do { ... }
6433 DoExpression* instanceof;
6434 {
6435 Block* block = factory->NewBlock(nullptr, 5, true, nopos);
6436 block->statements()->Add(get_O, zone);
6437 block->statements()->Add(get_C, zone);
6438 block->statements()->Add(validate_C, zone);
6439 block->statements()->Add(initialize_handler, zone);
6440 block->statements()->Add(call_handler, zone);
6441
6442 // Here is the desugared instanceof.
6443 instanceof = factory->NewDoExpression(block, var_handler_result, nopos);
6444 Rewriter::Rewrite(parser_, instanceof, avfactory);
6445 }
6446
6447 return instanceof;
6448 }
6449
6450 Statement* ParserTraits::CheckCallable(Variable* var, Expression* error) {
rossberg 2016/02/19 12:19:00 Given that my CL has landed, can you now change Fi
mvstanton 2016/02/19 18:15:59 Done.
6451 auto factory = parser_->factory();
6452 auto avfactory = parser_->ast_value_factory();
6453 const int nopos = RelocInfo::kNoPosition;
6454 Statement* validate_var;
6455 {
6456 Expression* type_of = factory->NewUnaryOperation(
6457 Token::TYPEOF, factory->NewVariableProxy(var), nopos);
6458 Expression* function_literal =
6459 factory->NewStringLiteral(avfactory->function_string(), nopos);
6460 Expression* condition = factory->NewCompareOperation(
6461 Token::EQ_STRICT, type_of, function_literal, nopos);
6462
6463 Statement* throw_call = factory->NewExpressionStatement(error, nopos);
6464
6465 validate_var = factory->NewIfStatement(
6466 condition, factory->NewEmptyStatement(nopos), throw_call, nopos);
6467 }
6468 return validate_var;
6469 }
6291 6470
6292 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, 6471 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements,
6293 Variable* iterator, 6472 Variable* iterator,
6294 Expression* input, 6473 Expression* input,
6295 Variable* var_output) { 6474 Variable* var_output) {
6296 // 6475 //
6297 // This function adds four statements to [statements], corresponding to the 6476 // This function adds four statements to [statements], corresponding to the
6298 // following code: 6477 // following code:
6299 // 6478 //
6300 // let iteratorReturn = iterator.return; 6479 // let iteratorReturn = iterator.return;
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
6727 new_body->statements()->Add(loop->body(), zone); 6906 new_body->statements()->Add(loop->body(), zone);
6728 new_body->statements()->Add(set_completion_normal, zone); 6907 new_body->statements()->Add(set_completion_normal, zone);
6729 6908
6730 loop->set_body(new_body); 6909 loop->set_body(new_body);
6731 return final_loop; 6910 return final_loop;
6732 } 6911 }
6733 6912
6734 6913
6735 } // namespace internal 6914 } // namespace internal
6736 } // namespace v8 6915 } // 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