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

Side by Side Diff: src/fast-codegen.cc

Issue 501076: Fast-codegen: Adding support for try/catch and throw. (Closed)
Patch Set: Created 11 years 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
OLDNEW
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
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
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
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
OLDNEW
« src/compiler.cc ('K') | « src/fast-codegen.h ('k') | src/ia32/fast-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698