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

Side by Side Diff: runtime/vm/kernel_to_il.cc

Issue 2487183002: VM: [Kernel] Ensure we have the correct try-index when translating finally blocks (Closed)
Patch Set: Rebased & remove print in test Created 4 years, 1 month 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
« no previous file with comments | « no previous file | tests/kernel/unsorted/try_finally_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include <map> 5 #include <map>
6 #include <set> 6 #include <set>
7 #include <string> 7 #include <string>
8 8
9 #include "vm/kernel_to_il.h" 9 #include "vm/kernel_to_il.h"
10 10
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 class TryFinallyBlock { 833 class TryFinallyBlock {
834 public: 834 public:
835 TryFinallyBlock(FlowGraphBuilder* builder, Statement* finalizer) 835 TryFinallyBlock(FlowGraphBuilder* builder, Statement* finalizer)
836 : builder_(builder), 836 : builder_(builder),
837 outer_(builder->try_finally_block_), 837 outer_(builder->try_finally_block_),
838 finalizer_(finalizer), 838 finalizer_(finalizer),
839 context_depth_(builder->context_depth_), 839 context_depth_(builder->context_depth_),
840 // Finalizers are executed outside of the try block hence 840 // Finalizers are executed outside of the try block hence
841 // try depth of finalizers are one less than current try 841 // try depth of finalizers are one less than current try
842 // depth. 842 // depth.
843 try_depth_(builder->try_depth_ - 1) { 843 try_depth_(builder->try_depth_ - 1),
844 try_index_(builder_->CurrentTryIndex()) {
844 builder_->try_finally_block_ = this; 845 builder_->try_finally_block_ = this;
845 } 846 }
846 ~TryFinallyBlock() { builder_->try_finally_block_ = outer_; } 847 ~TryFinallyBlock() { builder_->try_finally_block_ = outer_; }
847 848
848 Statement* finalizer() const { return finalizer_; } 849 Statement* finalizer() const { return finalizer_; }
849 intptr_t context_depth() const { return context_depth_; } 850 intptr_t context_depth() const { return context_depth_; }
850 intptr_t try_depth() const { return try_depth_; } 851 intptr_t try_depth() const { return try_depth_; }
852 intptr_t try_index() const { return try_index_; }
851 TryFinallyBlock* outer() const { return outer_; } 853 TryFinallyBlock* outer() const { return outer_; }
852 854
853 private: 855 private:
854 FlowGraphBuilder* const builder_; 856 FlowGraphBuilder* const builder_;
855 TryFinallyBlock* const outer_; 857 TryFinallyBlock* const outer_;
856 Statement* const finalizer_; 858 Statement* const finalizer_;
857 const intptr_t context_depth_; 859 const intptr_t context_depth_;
858 const intptr_t try_depth_; 860 const intptr_t try_depth_;
861 const intptr_t try_index_;
859 }; 862 };
860 863
861 864
862 class TryCatchBlock { 865 class TryCatchBlock {
863 public: 866 public:
864 explicit TryCatchBlock(FlowGraphBuilder* builder, 867 explicit TryCatchBlock(FlowGraphBuilder* builder,
865 intptr_t try_handler_index = -1) 868 intptr_t try_handler_index = -1)
866 : builder_(builder), 869 : builder_(builder),
867 outer_(builder->try_catch_block_), 870 outer_(builder->try_catch_block_),
868 try_index_(try_handler_index) { 871 try_index_(try_handler_index) {
869 if (try_index_ == -1) try_index_ = builder->AllocateTryIndex(); 872 if (try_index_ == -1) try_index_ = builder->AllocateTryIndex();
870 builder->try_catch_block_ = this; 873 builder->try_catch_block_ = this;
871 } 874 }
872 ~TryCatchBlock() { builder_->try_catch_block_ = outer_; } 875 ~TryCatchBlock() { builder_->try_catch_block_ = outer_; }
873 876
874 intptr_t TryIndex() { return try_index_; } 877 intptr_t try_index() { return try_index_; }
878 TryCatchBlock* outer() const { return outer_; }
875 879
876 private: 880 private:
877 FlowGraphBuilder* builder_; 881 FlowGraphBuilder* builder_;
878 TryCatchBlock* outer_; 882 TryCatchBlock* outer_;
879 intptr_t try_index_; 883 intptr_t try_index_;
880 }; 884 };
881 885
882 886
883 class CatchBlock { 887 class CatchBlock {
884 public: 888 public:
(...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after
1846 &type_translator_) {} 1850 &type_translator_) {}
1847 1851
1848 1852
1849 FlowGraphBuilder::~FlowGraphBuilder() {} 1853 FlowGraphBuilder::~FlowGraphBuilder() {}
1850 1854
1851 1855
1852 Fragment FlowGraphBuilder::TranslateFinallyFinalizers( 1856 Fragment FlowGraphBuilder::TranslateFinallyFinalizers(
1853 TryFinallyBlock* outer_finally, 1857 TryFinallyBlock* outer_finally,
1854 intptr_t target_context_depth) { 1858 intptr_t target_context_depth) {
1855 TryFinallyBlock* const saved_block = try_finally_block_; 1859 TryFinallyBlock* const saved_block = try_finally_block_;
1860 TryCatchBlock* const saved_try_catch_block = try_catch_block_;
1856 const intptr_t saved_depth = context_depth_; 1861 const intptr_t saved_depth = context_depth_;
1857 const intptr_t saved_try_depth = try_depth_; 1862 const intptr_t saved_try_depth = try_depth_;
1858 1863
1859 Fragment instructions; 1864 Fragment instructions;
1860 1865
1861 // While translating the body of a finalizer we need to set the try-finally 1866 // While translating the body of a finalizer we need to set the try-finally
1862 // block which is active when translating the body. 1867 // block which is active when translating the body.
1863 while (try_finally_block_ != outer_finally) { 1868 while (try_finally_block_ != outer_finally) {
1864 // Set correct try depth (in case there are nested try statements). 1869 // Set correct try depth (in case there are nested try statements).
1865 try_depth_ = try_finally_block_->try_depth(); 1870 try_depth_ = try_finally_block_->try_depth();
1866 1871
1867 // Potentially restore the context to what is expected for the finally 1872 // Potentially restore the context to what is expected for the finally
1868 // block. 1873 // block.
1869 instructions += AdjustContextTo(try_finally_block_->context_depth()); 1874 instructions += AdjustContextTo(try_finally_block_->context_depth());
1870 1875
1876 // The to-be-translated finalizer has to have the correct try-index (namely
1877 // the one outside the try-finally block).
1878 bool changed_try_index = false;
1879 intptr_t target_try_index = try_finally_block_->try_index();
1880 while (CurrentTryIndex() != target_try_index) {
1881 try_catch_block_ = try_catch_block_->outer();
1882 changed_try_index = true;
1883 }
1884 if (changed_try_index) {
1885 JoinEntryInstr* entry = BuildJoinEntry();
1886 instructions += Goto(entry);
1887 instructions = Fragment(instructions.entry, entry);
1888 }
1889
1871 Statement* finalizer = try_finally_block_->finalizer(); 1890 Statement* finalizer = try_finally_block_->finalizer();
1872 try_finally_block_ = try_finally_block_->outer(); 1891 try_finally_block_ = try_finally_block_->outer();
1873 1892
1874 // This will potentially have exceptional cases as described in 1893 // This will potentially have exceptional cases as described in
1875 // [VisitTryFinally] and will handle them. 1894 // [VisitTryFinally] and will handle them.
1876 instructions += TranslateStatement(finalizer); 1895 instructions += TranslateStatement(finalizer);
1877 1896
1878 // We only need to make sure that if the finalizer ended normally, we 1897 // We only need to make sure that if the finalizer ended normally, we
1879 // continue towards the next outer try-finally. 1898 // continue towards the next outer try-finally.
1880 if (!instructions.is_open()) break; 1899 if (!instructions.is_open()) break;
1881 } 1900 }
1882 1901
1883 if (instructions.is_open() && target_context_depth != -1) { 1902 if (instructions.is_open() && target_context_depth != -1) {
1884 // A target context depth of -1 indicates that we the code after this 1903 // A target context depth of -1 indicates that the code after this
1885 // will not care about the context chain so we can leave it any way we 1904 // will not care about the context chain so we can leave it any way we
1886 // want after the last finalizer. That is used when returning. 1905 // want after the last finalizer. That is used when returning.
1887 instructions += AdjustContextTo(target_context_depth); 1906 instructions += AdjustContextTo(target_context_depth);
1888 } 1907 }
1889 1908
1890 try_finally_block_ = saved_block; 1909 try_finally_block_ = saved_block;
1910 try_catch_block_ = saved_try_catch_block;
1891 context_depth_ = saved_depth; 1911 context_depth_ = saved_depth;
1892 try_depth_ = saved_try_depth; 1912 try_depth_ = saved_try_depth;
1893 1913
1894 return instructions; 1914 return instructions;
1895 } 1915 }
1896 1916
1897 1917
1898 Fragment FlowGraphBuilder::EnterScope(TreeNode* node, bool* new_context) { 1918 Fragment FlowGraphBuilder::EnterScope(TreeNode* node, bool* new_context) {
1899 Fragment instructions; 1919 Fragment instructions;
1900 const intptr_t context_size = 1920 const intptr_t context_size =
(...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after
2661 stack_->definition()->set_ssa_temp_index(0); 2681 stack_->definition()->set_ssa_temp_index(0);
2662 2682
2663 return variable; 2683 return variable;
2664 } 2684 }
2665 2685
2666 2686
2667 intptr_t FlowGraphBuilder::CurrentTryIndex() { 2687 intptr_t FlowGraphBuilder::CurrentTryIndex() {
2668 if (try_catch_block_ == NULL) { 2688 if (try_catch_block_ == NULL) {
2669 return CatchClauseNode::kInvalidTryIndex; 2689 return CatchClauseNode::kInvalidTryIndex;
2670 } else { 2690 } else {
2671 return try_catch_block_->TryIndex(); 2691 return try_catch_block_->try_index();
2672 } 2692 }
2673 } 2693 }
2674 2694
2675 2695
2676 dart::LocalVariable* FlowGraphBuilder::LookupVariable( 2696 dart::LocalVariable* FlowGraphBuilder::LookupVariable(
2677 VariableDeclaration* var) { 2697 VariableDeclaration* var) {
2678 LocalVariable* local = scopes_->locals.Lookup(var); 2698 LocalVariable* local = scopes_->locals.Lookup(var);
2679 ASSERT(local != NULL); 2699 ASSERT(local != NULL);
2680 return local; 2700 return local;
2681 } 2701 }
(...skipping 2743 matching lines...) Expand 10 before | Expand all | Expand 10 after
5425 // 5445 //
5426 // => We are responsible for catching it, executing the finally block and 5446 // => We are responsible for catching it, executing the finally block and
5427 // rethrowing the exception. 5447 // rethrowing the exception.
5428 intptr_t try_handler_index = AllocateTryIndex(); 5448 intptr_t try_handler_index = AllocateTryIndex();
5429 Fragment try_body = TryCatch(try_handler_index); 5449 Fragment try_body = TryCatch(try_handler_index);
5430 JoinEntryInstr* after_try = BuildJoinEntry(); 5450 JoinEntryInstr* after_try = BuildJoinEntry();
5431 5451
5432 // Fill in the body of the try. 5452 // Fill in the body of the try.
5433 ++try_depth_; 5453 ++try_depth_;
5434 { 5454 {
5455 TryFinallyBlock tfb(this, node->finalizer());
5435 TryCatchBlock tcb(this, try_handler_index); 5456 TryCatchBlock tcb(this, try_handler_index);
5436 TryFinallyBlock tfb(this, node->finalizer());
5437 try_body += TranslateStatement(node->body()); 5457 try_body += TranslateStatement(node->body());
5438 } 5458 }
5439 --try_depth_; 5459 --try_depth_;
5440 5460
5441 if (try_body.is_open()) { 5461 if (try_body.is_open()) {
5442 // Please note: The try index will be on level out of this block, 5462 // Please note: The try index will be on level out of this block,
5443 // thereby ensuring if there's an exception in the finally block we 5463 // thereby ensuring if there's an exception in the finally block we
5444 // won't run it twice. 5464 // won't run it twice.
5445 JoinEntryInstr* finally_entry = BuildJoinEntry(); 5465 JoinEntryInstr* finally_entry = BuildJoinEntry();
5446 5466
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
5718 instructions += LoadLocal(closure); 5738 instructions += LoadLocal(closure);
5719 instructions += LoadLocal(parsed_function_->current_context_var()); 5739 instructions += LoadLocal(parsed_function_->current_context_var());
5720 instructions += StoreInstanceField(Closure::context_offset()); 5740 instructions += StoreInstanceField(Closure::context_offset());
5721 5741
5722 return instructions; 5742 return instructions;
5723 } 5743 }
5724 5744
5725 5745
5726 } // namespace kernel 5746 } // namespace kernel
5727 } // namespace dart 5747 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | tests/kernel/unsorted/try_finally_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698