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

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

Issue 60943003: Fix scoping of catch clause variables (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/language/try_catch_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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 "vm/parser.h" 5 #include "vm/parser.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "platform/utils.h" 8 #include "platform/utils.h"
9 #include "vm/ast.h" 9 #include "vm/ast.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 6857 matching lines...) Expand 10 before | Expand all | Expand 10 after
6868 // TODO(hausner): Make implicit type be StackTrace, not dynamic. 6868 // TODO(hausner): Make implicit type be StackTrace, not dynamic.
6869 stack_trace_param.type = Type::DynamicType(); 6869 stack_trace_param.type = Type::DynamicType();
6870 stack_trace_param.token_pos = TokenPos(); 6870 stack_trace_param.token_pos = TokenPos();
6871 stack_trace_param.name = ExpectIdentifier("identifier expected"); 6871 stack_trace_param.name = ExpectIdentifier("identifier expected");
6872 } 6872 }
6873 ExpectToken(Token::kRPAREN); 6873 ExpectToken(Token::kRPAREN);
6874 } 6874 }
6875 6875
6876 // Parse the individual catch handler code and add an unconditional JUMP 6876 // Parse the individual catch handler code and add an unconditional JUMP
6877 // to the end of the try block. 6877 // to the end of the try block.
6878 ExpectToken(Token::kLBRACE); 6878 OpenBlock(); // Block for the exception and stack trace variables.
6879 OpenBlock();
6880 AddCatchParametersToScope(&exception_param, &stack_trace_param, 6879 AddCatchParametersToScope(&exception_param, &stack_trace_param,
6881 current_block_->scope); 6880 current_block_->scope);
6882 6881
6883 if (exception_param.var != NULL) { 6882 if (exception_param.var != NULL) {
6884 // Generate code to load the exception object (:exception_var) into 6883 // Generate code to load the exception object (:exception_var) into
6885 // the exception variable specified in this block. 6884 // the exception variable specified in this block.
6886 ASSERT(exception_var != NULL); 6885 ASSERT(exception_var != NULL);
6887 current_block_->statements->Add( 6886 current_block_->statements->Add(
6888 new StoreLocalNode(catch_pos, exception_param.var, 6887 new StoreLocalNode(catch_pos, exception_param.var,
6889 new LoadLocalNode(catch_pos, exception_var))); 6888 new LoadLocalNode(catch_pos, exception_var)));
6890 } 6889 }
6891 if (stack_trace_param.var != NULL) { 6890 if (stack_trace_param.var != NULL) {
6892 // A stack trace variable is specified in this block, so generate code 6891 // A stack trace variable is specified in this block, so generate code
6893 // to load the stack trace object (:stack_trace_var) into the stack 6892 // to load the stack trace object (:stack_trace_var) into the stack
6894 // trace variable specified in this block. 6893 // trace variable specified in this block.
6895 needs_stack_trace = true; 6894 needs_stack_trace = true;
6896 ArgumentListNode* no_args = new ArgumentListNode(catch_pos); 6895 ArgumentListNode* no_args = new ArgumentListNode(catch_pos);
6897 ASSERT(stack_trace_var != NULL); 6896 ASSERT(stack_trace_var != NULL);
6898 current_block_->statements->Add( 6897 current_block_->statements->Add(
6899 new StoreLocalNode(catch_pos, stack_trace_param.var, 6898 new StoreLocalNode(catch_pos, stack_trace_param.var,
6900 new LoadLocalNode(catch_pos, stack_trace_var))); 6899 new LoadLocalNode(catch_pos, stack_trace_var)));
6901 current_block_->statements->Add( 6900 current_block_->statements->Add(
6902 new InstanceCallNode( 6901 new InstanceCallNode(
6903 catch_pos, 6902 catch_pos,
6904 new LoadLocalNode(catch_pos, stack_trace_param.var), 6903 new LoadLocalNode(catch_pos, stack_trace_param.var),
6905 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), 6904 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()),
6906 no_args)); 6905 no_args));
6907 } 6906 }
6908 6907
6909 ParseStatementSequence(); // Parse the catch handler code. 6908 // Parse the catch handler code.
6910 current_block_->statements->Add( 6909 if (CurrentToken() != Token::kLBRACE) {
6910 ErrorMsg("'{' expected");
6911 }
6912 SequenceNode* catch_block = ParseNestedStatement(false, NULL);
6913 catch_block->Add(
6911 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label)); 6914 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label));
6912 SequenceNode* catch_handler = CloseBlock();
6913 ExpectToken(Token::kRBRACE);
6914 6915
6915 const bool is_bad_type = exception_param.type.IsMalformed() || 6916 const bool is_bad_type = exception_param.type.IsMalformed() ||
6916 exception_param.type.IsMalbounded(); 6917 exception_param.type.IsMalbounded();
6917 if (!is_bad_type && !exception_param.type.IsDynamicType()) { 6918 if (!is_bad_type && !exception_param.type.IsDynamicType()) {
6918 // Has a type specification that is not malformed or malbounded. 6919 // Has a type specification that is not malformed or malbounded.
6919 // Now form an 'if type check' as an exception type exists in the 6920 // Now form an 'if type check' as an exception type exists in the
6920 // catch specifier. 6921 // catch specifier.
6921 if (!exception_param.type.IsInstantiated() && 6922 if (!exception_param.type.IsInstantiated() &&
6922 (current_block_->scope->function_level() > 0)) { 6923 (current_block_->scope->function_level() > 0)) {
6923 // Make sure that the instantiator is captured. 6924 // Make sure that the instantiator is captured.
6924 CaptureInstantiator(); 6925 CaptureInstantiator();
6925 } 6926 }
6926 TypeNode* exception_type = new TypeNode(catch_pos, exception_param.type); 6927 TypeNode* exception_type = new TypeNode(catch_pos, exception_param.type);
6927 AstNode* exception_value = new LoadLocalNode(catch_pos, exception_var); 6928 AstNode* exception_value = new LoadLocalNode(catch_pos, exception_var);
6928 if (!exception_type->type().IsInstantiated()) { 6929 if (!exception_type->type().IsInstantiated()) {
6929 EnsureExpressionTemp(); 6930 EnsureExpressionTemp();
6930 } 6931 }
6931 AstNode* type_cond_expr = new ComparisonNode( 6932 AstNode* type_cond_expr = new ComparisonNode(
6932 catch_pos, Token::kIS, exception_value, exception_type); 6933 catch_pos, Token::kIS, exception_value, exception_type);
6933 current_block_->statements->Add( 6934 current_block_->statements->Add(
6934 new IfNode(catch_pos, type_cond_expr, catch_handler, NULL)); 6935 new IfNode(catch_pos, type_cond_expr, catch_block, NULL));
6935 6936
6936 // Do not add uninstantiated types (e.g. type parameter T or generic 6937 // Do not add uninstantiated types (e.g. type parameter T or generic
6937 // type List<T>), since the debugger won't be able to instantiate it 6938 // type List<T>), since the debugger won't be able to instantiate it
6938 // when walking the stack. This means that the debugger is not able 6939 // when walking the stack. This means that the debugger is not able
6939 // to determine whether an exception is caught if the catch clause 6940 // to determine whether an exception is caught if the catch clause
6940 // uses generic types. It will report the exception as uncaught when 6941 // uses generic types. It will report the exception as uncaught when
6941 // in fact it might be caught and handled when we unwind the stack. 6942 // in fact it might be caught and handled when we unwind the stack.
6942 if (exception_param.type.IsInstantiated()) { 6943 if (exception_param.type.IsInstantiated()) {
6943 handler_types.Add(exception_param.type); 6944 handler_types.Add(exception_param.type);
6944 } 6945 }
6945 } else { 6946 } else {
6946 if (is_bad_type) { 6947 if (is_bad_type) {
6947 current_block_->statements->Add(ThrowTypeError(catch_pos, 6948 current_block_->statements->Add(ThrowTypeError(catch_pos,
6948 exception_param.type)); 6949 exception_param.type));
6949 // We still add the dead code below to satisfy the code generator. 6950 // We still add the dead code below to satisfy the code generator.
6950 } 6951 }
6951 // No exception type exists in the catch specifier so execute the 6952 // No exception type exists in the catch specifier so execute the
6952 // catch handler code unconditionally. 6953 // catch handler code unconditionally.
6953 current_block_->statements->Add(catch_handler); 6954 current_block_->statements->Add(catch_block);
6954 generic_catch_seen = true; 6955 generic_catch_seen = true;
6955 // This catch clause will handle all exceptions. We can safely forget 6956 // This catch clause will handle all exceptions. We can safely forget
6956 // all previous catch clause types. 6957 // all previous catch clause types.
6957 handler_types.SetLength(0); 6958 handler_types.SetLength(0);
6958 handler_types.Add(exception_param.type); 6959 handler_types.Add(exception_param.type);
6959 } 6960 }
6961 // Add this individual catch handler to the catch handlers list.
6962 SequenceNode* catch_clause = CloseBlock();
6963 current_block_->statements->Add(catch_clause);
6960 } 6964 }
6961 SequenceNode* catch_handler_list = CloseBlock(); 6965 SequenceNode* catch_handler_list = CloseBlock();
6962 TryBlocks* inner_try_block = PopTryBlock(); 6966 TryBlocks* inner_try_block = PopTryBlock();
6963 const intptr_t try_index = inner_try_block->try_index(); 6967 const intptr_t try_index = inner_try_block->try_index();
6964 TryBlocks* outer_try_block = try_blocks_list_; 6968 TryBlocks* outer_try_block = try_blocks_list_;
6965 const intptr_t outer_try_index = (outer_try_block != NULL) 6969 const intptr_t outer_try_index = (outer_try_block != NULL)
6966 ? outer_try_block->try_index() 6970 ? outer_try_block->try_index()
6967 : CatchClauseNode::kInvalidTryIndex; 6971 : CatchClauseNode::kInvalidTryIndex;
6968 6972
6969 // Finally parse the 'finally' block. 6973 // Finally parse the 'finally' block.
(...skipping 3768 matching lines...) Expand 10 before | Expand all | Expand 10 after
10738 void Parser::SkipQualIdent() { 10742 void Parser::SkipQualIdent() {
10739 ASSERT(IsIdentifier()); 10743 ASSERT(IsIdentifier());
10740 ConsumeToken(); 10744 ConsumeToken();
10741 if (CurrentToken() == Token::kPERIOD) { 10745 if (CurrentToken() == Token::kPERIOD) {
10742 ConsumeToken(); // Consume the kPERIOD token. 10746 ConsumeToken(); // Consume the kPERIOD token.
10743 ExpectIdentifier("identifier expected after '.'"); 10747 ExpectIdentifier("identifier expected after '.'");
10744 } 10748 }
10745 } 10749 }
10746 10750
10747 } // namespace dart 10751 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | tests/language/try_catch_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698