| OLD | NEW |
| 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 Loading... |
| 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 OpenBlock(); // Block for the exception and stack trace variables. | 6878 ExpectToken(Token::kLBRACE); |
| 6879 OpenBlock(); |
| 6879 AddCatchParametersToScope(&exception_param, &stack_trace_param, | 6880 AddCatchParametersToScope(&exception_param, &stack_trace_param, |
| 6880 current_block_->scope); | 6881 current_block_->scope); |
| 6881 | 6882 |
| 6882 if (exception_param.var != NULL) { | 6883 if (exception_param.var != NULL) { |
| 6883 // Generate code to load the exception object (:exception_var) into | 6884 // Generate code to load the exception object (:exception_var) into |
| 6884 // the exception variable specified in this block. | 6885 // the exception variable specified in this block. |
| 6885 ASSERT(exception_var != NULL); | 6886 ASSERT(exception_var != NULL); |
| 6886 current_block_->statements->Add( | 6887 current_block_->statements->Add( |
| 6887 new StoreLocalNode(catch_pos, exception_param.var, | 6888 new StoreLocalNode(catch_pos, exception_param.var, |
| 6888 new LoadLocalNode(catch_pos, exception_var))); | 6889 new LoadLocalNode(catch_pos, exception_var))); |
| 6889 } | 6890 } |
| 6890 if (stack_trace_param.var != NULL) { | 6891 if (stack_trace_param.var != NULL) { |
| 6891 // A stack trace variable is specified in this block, so generate code | 6892 // A stack trace variable is specified in this block, so generate code |
| 6892 // to load the stack trace object (:stack_trace_var) into the stack | 6893 // to load the stack trace object (:stack_trace_var) into the stack |
| 6893 // trace variable specified in this block. | 6894 // trace variable specified in this block. |
| 6894 needs_stack_trace = true; | 6895 needs_stack_trace = true; |
| 6895 ArgumentListNode* no_args = new ArgumentListNode(catch_pos); | 6896 ArgumentListNode* no_args = new ArgumentListNode(catch_pos); |
| 6896 ASSERT(stack_trace_var != NULL); | 6897 ASSERT(stack_trace_var != NULL); |
| 6897 current_block_->statements->Add( | 6898 current_block_->statements->Add( |
| 6898 new StoreLocalNode(catch_pos, stack_trace_param.var, | 6899 new StoreLocalNode(catch_pos, stack_trace_param.var, |
| 6899 new LoadLocalNode(catch_pos, stack_trace_var))); | 6900 new LoadLocalNode(catch_pos, stack_trace_var))); |
| 6900 current_block_->statements->Add( | 6901 current_block_->statements->Add( |
| 6901 new InstanceCallNode( | 6902 new InstanceCallNode( |
| 6902 catch_pos, | 6903 catch_pos, |
| 6903 new LoadLocalNode(catch_pos, stack_trace_param.var), | 6904 new LoadLocalNode(catch_pos, stack_trace_param.var), |
| 6904 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), | 6905 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), |
| 6905 no_args)); | 6906 no_args)); |
| 6906 } | 6907 } |
| 6907 | 6908 |
| 6908 // Parse the catch handler code. | 6909 ParseStatementSequence(); // Parse the catch handler code. |
| 6909 if (CurrentToken() != Token::kLBRACE) { | 6910 current_block_->statements->Add( |
| 6910 ErrorMsg("'{' expected"); | |
| 6911 } | |
| 6912 SequenceNode* catch_block = ParseNestedStatement(false, NULL); | |
| 6913 catch_block->Add( | |
| 6914 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label)); | 6911 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label)); |
| 6912 SequenceNode* catch_handler = CloseBlock(); |
| 6913 ExpectToken(Token::kRBRACE); |
| 6915 | 6914 |
| 6916 const bool is_bad_type = exception_param.type.IsMalformed() || | 6915 const bool is_bad_type = exception_param.type.IsMalformed() || |
| 6917 exception_param.type.IsMalbounded(); | 6916 exception_param.type.IsMalbounded(); |
| 6918 if (!is_bad_type && !exception_param.type.IsDynamicType()) { | 6917 if (!is_bad_type && !exception_param.type.IsDynamicType()) { |
| 6919 // Has a type specification that is not malformed or malbounded. | 6918 // Has a type specification that is not malformed or malbounded. |
| 6920 // Now form an 'if type check' as an exception type exists in the | 6919 // Now form an 'if type check' as an exception type exists in the |
| 6921 // catch specifier. | 6920 // catch specifier. |
| 6922 if (!exception_param.type.IsInstantiated() && | 6921 if (!exception_param.type.IsInstantiated() && |
| 6923 (current_block_->scope->function_level() > 0)) { | 6922 (current_block_->scope->function_level() > 0)) { |
| 6924 // Make sure that the instantiator is captured. | 6923 // Make sure that the instantiator is captured. |
| 6925 CaptureInstantiator(); | 6924 CaptureInstantiator(); |
| 6926 } | 6925 } |
| 6927 TypeNode* exception_type = new TypeNode(catch_pos, exception_param.type); | 6926 TypeNode* exception_type = new TypeNode(catch_pos, exception_param.type); |
| 6928 AstNode* exception_value = new LoadLocalNode(catch_pos, exception_var); | 6927 AstNode* exception_value = new LoadLocalNode(catch_pos, exception_var); |
| 6929 if (!exception_type->type().IsInstantiated()) { | 6928 if (!exception_type->type().IsInstantiated()) { |
| 6930 EnsureExpressionTemp(); | 6929 EnsureExpressionTemp(); |
| 6931 } | 6930 } |
| 6932 AstNode* type_cond_expr = new ComparisonNode( | 6931 AstNode* type_cond_expr = new ComparisonNode( |
| 6933 catch_pos, Token::kIS, exception_value, exception_type); | 6932 catch_pos, Token::kIS, exception_value, exception_type); |
| 6934 current_block_->statements->Add( | 6933 current_block_->statements->Add( |
| 6935 new IfNode(catch_pos, type_cond_expr, catch_block, NULL)); | 6934 new IfNode(catch_pos, type_cond_expr, catch_handler, NULL)); |
| 6936 | 6935 |
| 6937 // Do not add uninstantiated types (e.g. type parameter T or generic | 6936 // Do not add uninstantiated types (e.g. type parameter T or generic |
| 6938 // type List<T>), since the debugger won't be able to instantiate it | 6937 // type List<T>), since the debugger won't be able to instantiate it |
| 6939 // when walking the stack. This means that the debugger is not able | 6938 // when walking the stack. This means that the debugger is not able |
| 6940 // to determine whether an exception is caught if the catch clause | 6939 // to determine whether an exception is caught if the catch clause |
| 6941 // uses generic types. It will report the exception as uncaught when | 6940 // uses generic types. It will report the exception as uncaught when |
| 6942 // in fact it might be caught and handled when we unwind the stack. | 6941 // in fact it might be caught and handled when we unwind the stack. |
| 6943 if (exception_param.type.IsInstantiated()) { | 6942 if (exception_param.type.IsInstantiated()) { |
| 6944 handler_types.Add(exception_param.type); | 6943 handler_types.Add(exception_param.type); |
| 6945 } | 6944 } |
| 6946 } else { | 6945 } else { |
| 6947 if (is_bad_type) { | 6946 if (is_bad_type) { |
| 6948 current_block_->statements->Add(ThrowTypeError(catch_pos, | 6947 current_block_->statements->Add(ThrowTypeError(catch_pos, |
| 6949 exception_param.type)); | 6948 exception_param.type)); |
| 6950 // We still add the dead code below to satisfy the code generator. | 6949 // We still add the dead code below to satisfy the code generator. |
| 6951 } | 6950 } |
| 6952 // No exception type exists in the catch specifier so execute the | 6951 // No exception type exists in the catch specifier so execute the |
| 6953 // catch handler code unconditionally. | 6952 // catch handler code unconditionally. |
| 6954 current_block_->statements->Add(catch_block); | 6953 current_block_->statements->Add(catch_handler); |
| 6955 generic_catch_seen = true; | 6954 generic_catch_seen = true; |
| 6956 // This catch clause will handle all exceptions. We can safely forget | 6955 // This catch clause will handle all exceptions. We can safely forget |
| 6957 // all previous catch clause types. | 6956 // all previous catch clause types. |
| 6958 handler_types.SetLength(0); | 6957 handler_types.SetLength(0); |
| 6959 handler_types.Add(exception_param.type); | 6958 handler_types.Add(exception_param.type); |
| 6960 } | 6959 } |
| 6961 // Add this individual catch handler to the catch handlers list. | |
| 6962 SequenceNode* catch_clause = CloseBlock(); | |
| 6963 current_block_->statements->Add(catch_clause); | |
| 6964 } | 6960 } |
| 6965 SequenceNode* catch_handler_list = CloseBlock(); | 6961 SequenceNode* catch_handler_list = CloseBlock(); |
| 6966 TryBlocks* inner_try_block = PopTryBlock(); | 6962 TryBlocks* inner_try_block = PopTryBlock(); |
| 6967 const intptr_t try_index = inner_try_block->try_index(); | 6963 const intptr_t try_index = inner_try_block->try_index(); |
| 6968 TryBlocks* outer_try_block = try_blocks_list_; | 6964 TryBlocks* outer_try_block = try_blocks_list_; |
| 6969 const intptr_t outer_try_index = (outer_try_block != NULL) | 6965 const intptr_t outer_try_index = (outer_try_block != NULL) |
| 6970 ? outer_try_block->try_index() | 6966 ? outer_try_block->try_index() |
| 6971 : CatchClauseNode::kInvalidTryIndex; | 6967 : CatchClauseNode::kInvalidTryIndex; |
| 6972 | 6968 |
| 6973 // Finally parse the 'finally' block. | 6969 // Finally parse the 'finally' block. |
| (...skipping 3768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10742 void Parser::SkipQualIdent() { | 10738 void Parser::SkipQualIdent() { |
| 10743 ASSERT(IsIdentifier()); | 10739 ASSERT(IsIdentifier()); |
| 10744 ConsumeToken(); | 10740 ConsumeToken(); |
| 10745 if (CurrentToken() == Token::kPERIOD) { | 10741 if (CurrentToken() == Token::kPERIOD) { |
| 10746 ConsumeToken(); // Consume the kPERIOD token. | 10742 ConsumeToken(); // Consume the kPERIOD token. |
| 10747 ExpectIdentifier("identifier expected after '.'"); | 10743 ExpectIdentifier("identifier expected after '.'"); |
| 10748 } | 10744 } |
| 10749 } | 10745 } |
| 10750 | 10746 |
| 10751 } // namespace dart | 10747 } // namespace dart |
| OLD | NEW |