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 6270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 |
OLD | NEW |