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 |