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 6273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6284 do_block->statements()->Add(get_value, zone); | 6284 do_block->statements()->Add(get_value, zone); |
6285 | 6285 |
6286 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); | 6286 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); |
6287 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); | 6287 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); |
6288 Rewriter::Rewrite(parser_, yield_star, avfactory); | 6288 Rewriter::Rewrite(parser_, yield_star, avfactory); |
6289 } | 6289 } |
6290 | 6290 |
6291 return yield_star; | 6291 return yield_star; |
6292 } | 6292 } |
6293 | 6293 |
| 6294 // Desugaring of (lhs) instanceof (rhs) |
| 6295 // ==================================== |
| 6296 // |
| 6297 // We desugar instanceof into a load of property @@hasInstance on the rhs. |
| 6298 // We end up with roughly the following code (O, C): |
| 6299 // |
| 6300 // do { |
| 6301 // let O = lhs; |
| 6302 // let C = rhs; |
| 6303 // if (!IS_RECEIVER(C)) throw MakeTypeError(kNonObjectInInstanceOfCheck); |
| 6304 // let handler_result = C[Symbol.hasInstance]; |
| 6305 // if (handler_result === undefined) { |
| 6306 // if (!IS_CALLABLE(C)) { |
| 6307 // throw MakeTypeError(kCalledNonCallableInstanceOf); |
| 6308 // } |
| 6309 // handler_result = %ordinary_has_instance(C, O); |
| 6310 // } else { |
| 6311 // handler_result = !!(%_Call(handler_result, C, O)); |
| 6312 // } |
| 6313 // handler_result; |
| 6314 // } |
| 6315 // |
| 6316 Expression* ParserTraits::RewriteInstanceof(Expression* lhs, Expression* rhs, |
| 6317 int pos) { |
| 6318 const int nopos = RelocInfo::kNoPosition; |
| 6319 |
| 6320 auto factory = parser_->factory(); |
| 6321 auto avfactory = parser_->ast_value_factory(); |
| 6322 auto scope = parser_->scope_; |
| 6323 auto zone = parser_->zone(); |
| 6324 |
| 6325 // let O = lhs; |
| 6326 Variable* var_O = scope->NewTemporary(avfactory->empty_string()); |
| 6327 Statement* get_O; |
| 6328 { |
| 6329 Expression* O_proxy = factory->NewVariableProxy(var_O); |
| 6330 Expression* assignment = |
| 6331 factory->NewAssignment(Token::ASSIGN, O_proxy, lhs, nopos); |
| 6332 get_O = factory->NewExpressionStatement(assignment, nopos); |
| 6333 } |
| 6334 |
| 6335 // let C = lhs; |
| 6336 Variable* var_C = scope->NewTemporary(avfactory->empty_string()); |
| 6337 Statement* get_C; |
| 6338 { |
| 6339 Expression* C_proxy = factory->NewVariableProxy(var_C); |
| 6340 Expression* assignment = |
| 6341 factory->NewAssignment(Token::ASSIGN, C_proxy, rhs, nopos); |
| 6342 get_C = factory->NewExpressionStatement(assignment, nopos); |
| 6343 } |
| 6344 |
| 6345 // if (!IS_RECEIVER(C)) throw MakeTypeError(kNonObjectInInstanceOfCheck); |
| 6346 Statement* validate_C; |
| 6347 { |
| 6348 auto args = new (zone) ZoneList<Expression*>(1, zone); |
| 6349 args->Add(factory->NewVariableProxy(var_C), zone); |
| 6350 Expression* is_receiver_call = |
| 6351 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); |
| 6352 Expression* call = |
| 6353 NewThrowTypeError(MessageTemplate::kNonObjectInInstanceOfCheck, |
| 6354 avfactory->empty_string(), nopos); |
| 6355 Statement* throw_call = factory->NewExpressionStatement(call, nopos); |
| 6356 |
| 6357 validate_C = |
| 6358 factory->NewIfStatement(is_receiver_call, |
| 6359 factory->NewEmptyStatement(nopos), |
| 6360 throw_call, |
| 6361 nopos); |
| 6362 } |
| 6363 |
| 6364 // let handler_result = C[Symbol.hasInstance]; |
| 6365 Variable* var_handler_result = scope->NewTemporary(avfactory->empty_string()); |
| 6366 Statement* initialize_handler; |
| 6367 { |
| 6368 Expression* hasInstance_symbol_literal = |
| 6369 factory->NewSymbolLiteral("hasInstance_symbol", RelocInfo::kNoPosition); |
| 6370 Expression* prop = factory->NewProperty(factory->NewVariableProxy(var_C), |
| 6371 hasInstance_symbol_literal, pos); |
| 6372 Expression* handler_proxy = factory->NewVariableProxy(var_handler_result); |
| 6373 Expression* assignment = |
| 6374 factory->NewAssignment(Token::ASSIGN, handler_proxy, prop, nopos); |
| 6375 initialize_handler = factory->NewExpressionStatement(assignment, nopos); |
| 6376 } |
| 6377 |
| 6378 // if (handler_result === undefined) { |
| 6379 // if (!IS_CALLABLE(C)) { |
| 6380 // throw MakeTypeError(kCalledNonCallableInstanceOf); |
| 6381 // } |
| 6382 // result = %ordinary_has_instance(C, O); |
| 6383 // } else { |
| 6384 // handler_result = !!%_Call(handler_result, C, O); |
| 6385 // } |
| 6386 Statement* call_handler; |
| 6387 { |
| 6388 Expression* condition = factory->NewCompareOperation( |
| 6389 Token::EQ_STRICT, factory->NewVariableProxy(var_handler_result), |
| 6390 factory->NewUndefinedLiteral(nopos), nopos); |
| 6391 |
| 6392 Block* then_side = factory->NewBlock(nullptr, 2, false, nopos); |
| 6393 { |
| 6394 Expression* throw_expr = |
| 6395 NewThrowTypeError(MessageTemplate::kCalledNonCallableInstanceOf, |
| 6396 avfactory->empty_string(), nopos); |
| 6397 Statement* validate_C = CheckCallable(var_C, throw_expr); |
| 6398 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone); |
| 6399 args->Add(factory->NewVariableProxy(var_C), zone); |
| 6400 args->Add(factory->NewVariableProxy(var_O), zone); |
| 6401 CallRuntime* call = factory->NewCallRuntime( |
| 6402 Context::ORDINARY_HAS_INSTANCE_INDEX, args, pos); |
| 6403 Expression* result_proxy = factory->NewVariableProxy(var_handler_result); |
| 6404 Expression* assignment = |
| 6405 factory->NewAssignment(Token::ASSIGN, result_proxy, call, nopos); |
| 6406 Statement* assignment_return = |
| 6407 factory->NewExpressionStatement(assignment, nopos); |
| 6408 |
| 6409 then_side->statements()->Add(validate_C, zone); |
| 6410 then_side->statements()->Add(assignment_return, zone); |
| 6411 } |
| 6412 |
| 6413 Statement* else_side; |
| 6414 { |
| 6415 auto args = new (zone) ZoneList<Expression*>(3, zone); |
| 6416 args->Add(factory->NewVariableProxy(var_handler_result), zone); |
| 6417 args->Add(factory->NewVariableProxy(var_C), zone); |
| 6418 args->Add(factory->NewVariableProxy(var_O), zone); |
| 6419 Expression* call = |
| 6420 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
| 6421 Expression* inner_not = |
| 6422 factory->NewUnaryOperation(Token::NOT, call, nopos); |
| 6423 Expression* outer_not = |
| 6424 factory->NewUnaryOperation(Token::NOT, inner_not, nopos); |
| 6425 Expression* result_proxy = factory->NewVariableProxy(var_handler_result); |
| 6426 Expression* assignment = |
| 6427 factory->NewAssignment(Token::ASSIGN, result_proxy, outer_not, nopos); |
| 6428 |
| 6429 else_side = factory->NewExpressionStatement(assignment, nopos); |
| 6430 } |
| 6431 call_handler = |
| 6432 factory->NewIfStatement(condition, then_side, else_side, nopos); |
| 6433 } |
| 6434 |
| 6435 // do { ... } |
| 6436 DoExpression* instanceof; |
| 6437 { |
| 6438 Block* block = factory->NewBlock(nullptr, 5, true, nopos); |
| 6439 block->statements()->Add(get_O, zone); |
| 6440 block->statements()->Add(get_C, zone); |
| 6441 block->statements()->Add(validate_C, zone); |
| 6442 block->statements()->Add(initialize_handler, zone); |
| 6443 block->statements()->Add(call_handler, zone); |
| 6444 |
| 6445 // Here is the desugared instanceof. |
| 6446 instanceof = factory->NewDoExpression(block, var_handler_result, nopos); |
| 6447 Rewriter::Rewrite(parser_, instanceof, avfactory); |
| 6448 } |
| 6449 |
| 6450 return instanceof; |
| 6451 } |
| 6452 |
| 6453 Statement* ParserTraits::CheckCallable(Variable* var, Expression* error) { |
| 6454 auto factory = parser_->factory(); |
| 6455 auto avfactory = parser_->ast_value_factory(); |
| 6456 const int nopos = RelocInfo::kNoPosition; |
| 6457 Statement* validate_var; |
| 6458 { |
| 6459 Expression* type_of = factory->NewUnaryOperation( |
| 6460 Token::TYPEOF, factory->NewVariableProxy(var), nopos); |
| 6461 Expression* function_literal = |
| 6462 factory->NewStringLiteral(avfactory->function_string(), nopos); |
| 6463 Expression* condition = factory->NewCompareOperation( |
| 6464 Token::EQ_STRICT, type_of, function_literal, nopos); |
| 6465 |
| 6466 Statement* throw_call = factory->NewExpressionStatement(error, nopos); |
| 6467 |
| 6468 validate_var = factory->NewIfStatement( |
| 6469 condition, factory->NewEmptyStatement(nopos), throw_call, nopos); |
| 6470 } |
| 6471 return validate_var; |
| 6472 } |
6294 | 6473 |
6295 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, | 6474 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, |
6296 Variable* iterator, | 6475 Variable* iterator, |
6297 Maybe<Variable*> input, | 6476 Maybe<Variable*> input, |
6298 Maybe<Variable*> output) { | 6477 Maybe<Variable*> output) { |
6299 const int nopos = RelocInfo::kNoPosition; | 6478 const int nopos = RelocInfo::kNoPosition; |
6300 auto factory = parser_->factory(); | 6479 auto factory = parser_->factory(); |
6301 auto avfactory = parser_->ast_value_factory(); | 6480 auto avfactory = parser_->ast_value_factory(); |
6302 auto scope = parser_->scope_; | 6481 auto scope = parser_->scope_; |
6303 auto zone = parser_->zone(); | 6482 auto zone = parser_->zone(); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6382 | 6561 |
6383 statements->Add(get_return, zone); | 6562 statements->Add(get_return, zone); |
6384 statements->Add(check_return, zone); | 6563 statements->Add(check_return, zone); |
6385 statements->Add(call_return, zone); | 6564 statements->Add(call_return, zone); |
6386 statements->Add(validate_output, zone); | 6565 statements->Add(validate_output, zone); |
6387 } | 6566 } |
6388 | 6567 |
6389 | 6568 |
6390 } // namespace internal | 6569 } // namespace internal |
6391 } // namespace v8 | 6570 } // namespace v8 |
OLD | NEW |