Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 450 UNREACHABLE(); | 450 UNREACHABLE(); |
| 451 } | 451 } |
| 452 | 452 |
| 453 | 453 |
| 454 void FastCodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 454 void FastCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
| 455 UNREACHABLE(); | 455 UNREACHABLE(); |
| 456 } | 456 } |
| 457 | 457 |
| 458 | 458 |
| 459 void FastCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { | 459 void FastCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { |
| 460 UNREACHABLE(); | 460 Comment cmnt(masm_, "[ TryCatchStatement"); |
| 461 SetStatementPosition(stmt); | |
| 462 | |
| 463 Label setup_try_handler, catch_entry, done; | |
|
Kevin Millikin (Chromium)
2009/12/17 14:36:16
This isn't as complicated as TryFinally, but I mis
| |
| 464 | |
| 465 __ Call(&setup_try_handler); | |
|
Kevin Millikin (Chromium)
2009/12/17 14:36:16
You called this 'try_handler_setup' in TryFinally
| |
| 466 // Try handler code, exception in result register. | |
| 467 | |
| 468 // Store exception in local .catch variable before executing catch block. | |
| 469 { | |
| 470 // The catch variable is *always* a variable proxy for a local variable. | |
| 471 Variable* catch_var = stmt->catch_var()->AsVariableProxy()->AsVariable(); | |
| 472 ASSERT_NOT_NULL(catch_var); | |
| 473 ASSERT_EQ(Variable::TEMPORARY, catch_var->mode()); | |
|
Kevin Millikin (Chromium)
2009/12/17 14:36:16
I think this is true, but the code doesn't depend
| |
| 474 Slot* variable_slot = catch_var->rewrite()->AsSlot(); | |
|
Kevin Millikin (Chromium)
2009/12/17 14:36:16
No need for catch_var->rewrite()->AsSlot(), catch_
| |
| 475 ASSERT_NOT_NULL(variable_slot); | |
| 476 ASSERT_EQ(Slot::LOCAL, variable_slot->type()); | |
| 477 StoreToFrameField(SlotOffset(variable_slot), result_register()); | |
| 478 } | |
| 479 | |
| 480 Visit(stmt->catch_block()); | |
| 481 __ jmp(&done); | |
| 482 | |
| 483 // Try block code. Sets up the exception handler chain. | |
| 484 __ bind(&setup_try_handler); | |
| 485 { | |
| 486 TryCatch try_block(this, &catch_entry); | |
| 487 __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER); | |
| 488 Visit(stmt->try_block()); | |
| 489 __ PopTryHandler(); | |
| 490 } | |
| 491 __ bind(&done); | |
| 461 } | 492 } |
| 462 | 493 |
| 463 | 494 |
| 464 void FastCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { | 495 void FastCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { |
| 496 Comment cmnt(masm_, "[ TryFinallyStatement"); | |
| 497 SetStatementPosition(stmt); | |
| 465 // Try finally is compiled by setting up a try-handler on the stack while | 498 // Try finally is compiled by setting up a try-handler on the stack while |
| 466 // executing the try body, and removing it again afterwards. | 499 // executing the try body, and removing it again afterwards. |
| 467 // | 500 // |
| 468 // The try-finally construct can enter the finally block in three ways: | 501 // The try-finally construct can enter the finally block in three ways: |
| 469 // 1. By exiting the try-block normally. This removes the try-handler and | 502 // 1. By exiting the try-block normally. This removes the try-handler and |
| 470 // calls the finally block code before continuing. | 503 // calls the finally block code before continuing. |
| 471 // 2. By exiting the try-block with a function-local control flow transfer | 504 // 2. By exiting the try-block with a function-local control flow transfer |
| 472 // (break/continue/return). The site of the, e.g., break removes the | 505 // (break/continue/return). The site of the, e.g., break removes the |
| 473 // try handler and calls the finally block code before continuing | 506 // try handler and calls the finally block code before continuing |
| 474 // its outward control transfer. | 507 // its outward control transfer. |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 490 // Jump to try-handler setup and try-block code. Use call to put try-handler | 523 // Jump to try-handler setup and try-block code. Use call to put try-handler |
| 491 // address on stack. | 524 // address on stack. |
| 492 __ Call(&try_handler_setup); | 525 __ Call(&try_handler_setup); |
| 493 // Try handler code. Return address of call is pushed on handler stack. | 526 // Try handler code. Return address of call is pushed on handler stack. |
| 494 { | 527 { |
| 495 // This code is only executed during stack-handler traversal when an | 528 // This code is only executed during stack-handler traversal when an |
| 496 // exception is thrown. The execption is in the result register, which | 529 // exception is thrown. The execption is in the result register, which |
| 497 // is retained by the finally block. | 530 // is retained by the finally block. |
| 498 // Call the finally block and then rethrow the exception. | 531 // Call the finally block and then rethrow the exception. |
| 499 __ Call(&finally_entry); | 532 __ Call(&finally_entry); |
| 500 ThrowException(); | 533 __ push(result_register()); |
| 534 __ CallRuntime(Runtime::kReThrow, 1); | |
| 501 } | 535 } |
| 502 | 536 |
| 503 __ bind(&finally_entry); | 537 __ bind(&finally_entry); |
| 504 { | 538 { |
| 505 // Finally block implementation. | 539 // Finally block implementation. |
| 540 Finally finally_block(this); | |
| 506 EnterFinallyBlock(); | 541 EnterFinallyBlock(); |
| 507 Finally finally_block(this); | |
| 508 Visit(stmt->finally_block()); | 542 Visit(stmt->finally_block()); |
| 509 ExitFinallyBlock(); // Return to the calling code. | 543 ExitFinallyBlock(); // Return to the calling code. |
| 510 } | 544 } |
| 511 | 545 |
| 512 __ bind(&try_handler_setup); | 546 __ bind(&try_handler_setup); |
| 513 { | 547 { |
| 514 // Setup try handler (stack pointer registers). | 548 // Setup try handler (stack pointer registers). |
| 549 TryFinally try_block(this, &finally_entry); | |
| 515 __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); | 550 __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); |
| 516 TryFinally try_block(this, &finally_entry); | 551 Visit(stmt->try_block()); |
| 517 VisitStatements(stmt->try_block()->statements()); | |
| 518 __ PopTryHandler(); | 552 __ PopTryHandler(); |
| 519 } | 553 } |
| 520 // Execute the finally block on the way out. | 554 // Execute the finally block on the way out. |
| 521 __ Call(&finally_entry); | 555 __ Call(&finally_entry); |
| 522 } | 556 } |
| 523 | 557 |
| 524 | 558 |
| 525 void FastCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { | 559 void FastCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { |
| 526 #ifdef ENABLE_DEBUGGER_SUPPORT | 560 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 527 Comment cmnt(masm_, "[ DebuggerStatement"); | 561 Comment cmnt(masm_, "[ DebuggerStatement"); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 658 EmitNamedPropertyAssignment(expr); | 692 EmitNamedPropertyAssignment(expr); |
| 659 break; | 693 break; |
| 660 case KEYED_PROPERTY: | 694 case KEYED_PROPERTY: |
| 661 EmitKeyedPropertyAssignment(expr); | 695 EmitKeyedPropertyAssignment(expr); |
| 662 break; | 696 break; |
| 663 } | 697 } |
| 664 } | 698 } |
| 665 | 699 |
| 666 | 700 |
| 667 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { | 701 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { |
| 668 UNREACHABLE(); | 702 // Call runtime routine to allocate the catch extension object and |
| 703 // assign the exception value to the catch variable. | |
| 704 Comment cmnt(masm_, "[ CatchExtensionObject"); | |
| 705 | |
| 706 // Push key string. | |
| 707 Move(Expression::kValue, expr->key()); | |
|
Kevin Millikin (Chromium)
2009/12/17 14:36:16
Seems just as simple to compile the key and variab
| |
| 708 | |
| 709 // Push .catch variable content. | |
| 710 Variable* exception_variable = expr->value()->AsVariable(); | |
| 711 // The variable is always a temporary local. | |
| 712 ASSERT_NOT_NULL(exception_variable); | |
| 713 ASSERT_EQ(Variable::TEMPORARY, exception_variable->mode()); | |
| 714 Slot* variable_slot = exception_variable->rewrite()->AsSlot(); | |
| 715 ASSERT_NOT_NULL(variable_slot); | |
| 716 ASSERT_EQ(Slot::LOCAL, variable_slot->type()); | |
| 717 // Use result register as scratch register (if necessary). | |
| 718 Move(Expression::kValue, variable_slot, result_register()); | |
| 719 | |
| 720 // Create catch extension object. | |
| 721 __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2); | |
| 722 | |
| 723 __ push(result_register()); | |
| 669 } | 724 } |
| 670 | 725 |
| 671 | 726 |
| 672 void FastCodeGenerator::VisitThrow(Throw* expr) { | 727 void FastCodeGenerator::VisitThrow(Throw* expr) { |
| 673 UNREACHABLE(); | 728 Comment cmnt(masm_, "[ Throw"); |
| 729 Visit(expr->exception()); | |
|
Kevin Millikin (Chromium)
2009/12/17 14:36:16
Might assert the expression context is value.
| |
| 730 // Exception is on stack. | |
| 731 __ CallRuntime(Runtime::kThrow, 1); | |
| 732 // Never returns here. | |
| 674 } | 733 } |
| 675 | 734 |
| 676 | 735 |
| 677 int FastCodeGenerator::TryFinally::Exit(int stack_depth) { | 736 int FastCodeGenerator::TryFinally::Exit(int stack_depth) { |
| 678 // The macros used here must preserve the result register. | 737 // The macros used here must preserve the result register. |
| 679 __ Drop(stack_depth); | 738 __ Drop(stack_depth); |
| 680 __ PopTryHandler(); | 739 __ PopTryHandler(); |
| 681 __ Call(finally_entry_); | 740 __ Call(finally_entry_); |
| 682 return 0; | 741 return 0; |
| 683 } | 742 } |
| 684 | 743 |
| 685 | 744 |
| 686 int FastCodeGenerator::TryCatch::Exit(int stack_depth) { | 745 int FastCodeGenerator::TryCatch::Exit(int stack_depth) { |
| 687 // The macros used here must preserve the result register. | 746 // The macros used here must preserve the result register. |
| 688 __ Drop(stack_depth); | 747 __ Drop(stack_depth); |
| 689 __ PopTryHandler(); | 748 __ PopTryHandler(); |
| 690 return 0; | 749 return 0; |
| 691 } | 750 } |
| 692 | 751 |
| 693 | 752 |
| 694 #undef __ | 753 #undef __ |
| 695 | 754 |
| 696 | 755 |
| 697 } } // namespace v8::internal | 756 } } // namespace v8::internal |
| OLD | NEW |