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

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

Issue 59683002: Clean up Parser::ParseTryStatement in the VM. (Closed) Base URL: https://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
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 "vm/bigint_operations.h" 8 #include "platform/utils.h"
9 #include "vm/ast.h"
9 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
10 #include "vm/class_finalizer.h" 11 #include "vm/class_finalizer.h"
11 #include "vm/compiler.h" 12 #include "vm/compiler.h"
12 #include "vm/compiler_stats.h" 13 #include "vm/compiler_stats.h"
13 #include "vm/dart_api_impl.h" 14 #include "vm/dart_api_impl.h"
14 #include "vm/dart_entry.h" 15 #include "vm/dart_entry.h"
15 #include "vm/flags.h" 16 #include "vm/flags.h"
16 #include "vm/growable_array.h" 17 #include "vm/growable_array.h"
18 #include "vm/handles.h"
19 #include "vm/heap.h"
20 #include "vm/isolate.h"
17 #include "vm/longjump.h" 21 #include "vm/longjump.h"
22 #include "vm/native_arguments.h"
18 #include "vm/native_entry.h" 23 #include "vm/native_entry.h"
19 #include "vm/object.h" 24 #include "vm/object.h"
20 #include "vm/object_store.h" 25 #include "vm/object_store.h"
26 #include "vm/os.h"
21 #include "vm/resolver.h" 27 #include "vm/resolver.h"
28 #include "vm/scanner.h"
22 #include "vm/scopes.h" 29 #include "vm/scopes.h"
23 #include "vm/stack_frame.h" 30 #include "vm/stack_frame.h"
31 #include "vm/timer.h"
24 #include "vm/symbols.h" 32 #include "vm/symbols.h"
33 #include "vm/zone.h"
25 34
26 namespace dart { 35 namespace dart {
27 36
28 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); 37 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements.");
29 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); 38 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks.");
30 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); 39 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations.");
31 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); 40 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors.");
32 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); 41 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings.");
33 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef"); 42 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef");
34 DECLARE_FLAG(bool, error_on_bad_type); 43 DECLARE_FLAG(bool, error_on_bad_type);
(...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 // Generate code returning the field value. 1042 // Generate code returning the field value.
1034 ReturnNode* return_node = 1043 ReturnNode* return_node =
1035 new ReturnNode(ident_pos, 1044 new ReturnNode(ident_pos,
1036 new LoadStaticFieldNode(ident_pos, field)); 1045 new LoadStaticFieldNode(ident_pos, field));
1037 current_block_->statements->Add(return_node); 1046 current_block_->statements->Add(return_node);
1038 } 1047 }
1039 return CloseBlock(); 1048 return CloseBlock();
1040 } 1049 }
1041 1050
1042 1051
1052 LocalVariable* Parser::EnsureLocalVariable(const String& name) {
1053 LocalVariable* variable = current_block_->scope->LocalLookupVariable(name);
1054 if (variable == NULL) {
1055 variable = new LocalVariable(TokenPos(), name,
1056 Type::ZoneHandle(Type::DynamicType()));
1057 current_block_->scope->AddVariable(variable);
1058 }
1059 return variable;
1060 }
1061
1062
1043 SequenceNode* Parser::ParseStaticInitializer(const Function& func) { 1063 SequenceNode* Parser::ParseStaticInitializer(const Function& func) {
1044 TRACE_PARSER("ParseStaticInitializer"); 1064 TRACE_PARSER("ParseStaticInitializer");
1045 ParamList params; 1065 ParamList params;
1046 ASSERT(func.num_fixed_parameters() == 0); // static. 1066 ASSERT(func.num_fixed_parameters() == 0); // static.
1047 ASSERT(!func.HasOptionalParameters()); 1067 ASSERT(!func.HasOptionalParameters());
1048 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); 1068 ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
1049 1069
1050 // Build local scope for function and populate with the formal parameters. 1070 // Build local scope for function and populate with the formal parameters.
1051 OpenFunctionBlock(func); 1071 OpenFunctionBlock(func);
1052 AddFormalParamsToScope(&params, current_block_->scope); 1072 AddFormalParamsToScope(&params, current_block_->scope);
1053 1073
1054 // Move forward to the start of the initializer expression. 1074 // Move forward to the start of the initializer expression.
1055 ExpectIdentifier("identifier expected"); 1075 ExpectIdentifier("identifier expected");
1056 ExpectToken(Token::kASSIGN); 1076 ExpectToken(Token::kASSIGN);
1057 intptr_t token_pos = TokenPos(); 1077 intptr_t token_pos = TokenPos();
1058 1078
1059 // Synthesize a try-catch block to wrap the initializer expression. 1079 // Synthesize a try-catch block to wrap the initializer expression.
1060 LocalVariable* context_var = 1080 LocalVariable* context_var =
1061 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); 1081 EnsureLocalVariable(Symbols::SavedTryContextVar());
1062 if (context_var == NULL) { 1082 LocalVariable* exception_var = EnsureLocalVariable(Symbols::ExceptionVar());
1063 context_var = new LocalVariable(token_pos, 1083 LocalVariable* stack_trace_var =
1064 Symbols::SavedTryContextVar(), 1084 EnsureLocalVariable(Symbols::StackTraceVar());
1065 Type::ZoneHandle(Type::DynamicType()));
1066 current_block_->scope->AddVariable(context_var);
1067 }
1068 LocalVariable* catch_excp_var =
1069 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar());
1070 if (catch_excp_var == NULL) {
1071 catch_excp_var = new LocalVariable(token_pos,
1072 Symbols::ExceptionVar(),
1073 Type::ZoneHandle(Type::DynamicType()));
1074 current_block_->scope->AddVariable(catch_excp_var);
1075 }
1076 LocalVariable* catch_trace_var =
1077 current_block_->scope->LocalLookupVariable(Symbols::StacktraceVar());
1078 if (catch_trace_var == NULL) {
1079 catch_trace_var = new LocalVariable(token_pos,
1080 Symbols::StacktraceVar(),
1081 Type::ZoneHandle(Type::DynamicType()));
1082 current_block_->scope->AddVariable(catch_trace_var);
1083 }
1084 1085
1085 OpenBlock(); // Start try block. 1086 OpenBlock(); // Start try block.
1086 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); 1087 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
1087 const Field& field = Field::ZoneHandle(func.saved_static_field()); 1088 const Field& field = Field::ZoneHandle(func.saved_static_field());
1088 ASSERT(!field.is_const()); 1089 ASSERT(!field.is_const());
1089 StoreStaticFieldNode* store = new StoreStaticFieldNode(field.token_pos(), 1090 StoreStaticFieldNode* store = new StoreStaticFieldNode(field.token_pos(),
1090 field, 1091 field,
1091 expr); 1092 expr);
1092 current_block_->statements->Add(store); 1093 current_block_->statements->Add(store);
1093 SequenceNode* try_block = CloseBlock(); // End try block. 1094 SequenceNode* try_block = CloseBlock(); // End try block.
(...skipping 14 matching lines...) Expand all
1108 store_null->Add(new StoreStaticFieldNode( 1109 store_null->Add(new StoreStaticFieldNode(
1109 field.token_pos(), 1110 field.token_pos(),
1110 field, 1111 field,
1111 new LiteralNode(token_pos, Instance::ZoneHandle()))); 1112 new LiteralNode(token_pos, Instance::ZoneHandle())));
1112 AstNode* transition_sentinel_check = 1113 AstNode* transition_sentinel_check =
1113 new IfNode(token_pos, compare_transition_sentinel, store_null, NULL); 1114 new IfNode(token_pos, compare_transition_sentinel, store_null, NULL);
1114 current_block_->statements->Add(transition_sentinel_check); 1115 current_block_->statements->Add(transition_sentinel_check);
1115 1116
1116 current_block_->statements->Add( 1117 current_block_->statements->Add(
1117 new ThrowNode(token_pos, 1118 new ThrowNode(token_pos,
1118 new LoadLocalNode(token_pos, catch_excp_var), 1119 new LoadLocalNode(token_pos, exception_var),
1119 new LoadLocalNode(token_pos, catch_trace_var))); 1120 new LoadLocalNode(token_pos, stack_trace_var)));
1120 current_block_->statements->Add( 1121 current_block_->statements->Add(
1121 new JumpNode(token_pos, Token::kCONTINUE, end_catch_label)); 1122 new JumpNode(token_pos, Token::kCONTINUE, end_catch_label));
1122 SequenceNode* catch_clause = CloseBlock(); // End catch clause. 1123 SequenceNode* catch_clause = CloseBlock(); // End catch clause.
1123 1124
1124 current_block_->statements->Add(catch_clause); 1125 current_block_->statements->Add(catch_clause);
1125 SequenceNode* catch_handler_list = CloseBlock(); // End catch handler list. 1126 SequenceNode* catch_handler_list = CloseBlock(); // End catch handler list.
1126 CatchClauseNode* catch_block = 1127 CatchClauseNode* catch_block =
1127 new CatchClauseNode(token_pos, 1128 new CatchClauseNode(token_pos,
1128 catch_handler_list, 1129 catch_handler_list,
1129 Array::ZoneHandle(Object::empty_array().raw()), 1130 Array::ZoneHandle(Object::empty_array().raw()),
1130 context_var, 1131 context_var,
1131 catch_excp_var, 1132 exception_var,
1132 catch_trace_var, 1133 stack_trace_var,
1133 CatchClauseNode::kInvalidTryIndex, 1134 CatchClauseNode::kInvalidTryIndex,
1134 false); // No stack trace needed. 1135 false); // No stack trace needed.
1135 1136
1136 AstNode* try_catch_node = new TryCatchNode(token_pos, 1137 AstNode* try_catch_node = new TryCatchNode(token_pos,
1137 try_block, 1138 try_block,
1138 end_catch_label, 1139 end_catch_label,
1139 context_var, 1140 context_var,
1140 catch_block, 1141 catch_block,
1141 NULL, // No finally block. 1142 NULL, // No finally block.
1142 AllocateTryIndex()); 1143 AllocateTryIndex());
(...skipping 5532 matching lines...) Expand 10 before | Expand all | Expand 10 after
6675 condition = InsertClosureCallNodes(condition); 6676 condition = InsertClosureCallNodes(condition);
6676 condition = new UnaryOpNode(condition_pos, Token::kNOT, condition); 6677 condition = new UnaryOpNode(condition_pos, Token::kNOT, condition);
6677 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); 6678 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end);
6678 return new IfNode(condition_pos, 6679 return new IfNode(condition_pos,
6679 condition, 6680 condition,
6680 NodeAsSequenceNode(condition_pos, assert_throw, NULL), 6681 NodeAsSequenceNode(condition_pos, assert_throw, NULL),
6681 NULL); 6682 NULL);
6682 } 6683 }
6683 6684
6684 6685
6685 struct CatchParamDesc { 6686 struct CatchParameter {
6686 CatchParamDesc() 6687 CatchParameter()
6687 : token_pos(0), type(NULL), var(NULL) { } 6688 : token_pos(0), type(AbstractType::ZoneHandle()), name(NULL), var(NULL) {
6689 }
6688 intptr_t token_pos; 6690 intptr_t token_pos;
6689 const AbstractType* type; 6691 AbstractType& type;
6690 const String* var; 6692 const String* name;
6693 LocalVariable* var;
6691 }; 6694 };
6692 6695
6693 6696
6694 // Populate local scope of the catch block with the catch parameters. 6697 // Populate local scope of the catch block with the catch parameters.
6695 void Parser::AddCatchParamsToScope(const CatchParamDesc& exception_param, 6698 void Parser::AddCatchParametersToScope(CatchParameter* exception_param,
6696 const CatchParamDesc& stack_trace_param, 6699 CatchParameter* stack_trace_param,
6697 LocalScope* scope) { 6700 LocalScope* scope) {
6698 if (exception_param.var != NULL) { 6701 if (exception_param->name != NULL) {
6699 LocalVariable* var = new LocalVariable(exception_param.token_pos, 6702 LocalVariable* var = new LocalVariable(exception_param->token_pos,
6700 *exception_param.var, 6703 *exception_param->name,
6701 *exception_param.type); 6704 exception_param->type);
6702 var->set_is_final(); 6705 var->set_is_final();
6703 bool added_to_scope = scope->AddVariable(var); 6706 bool added_to_scope = scope->AddVariable(var);
6704 ASSERT(added_to_scope); 6707 ASSERT(added_to_scope);
6708 exception_param->var = var;
6705 } 6709 }
6706 if (stack_trace_param.var != NULL) { 6710 if (stack_trace_param->name != NULL) {
6707 LocalVariable* var = new LocalVariable(TokenPos(), 6711 LocalVariable* var = new LocalVariable(stack_trace_param->token_pos,
6708 *stack_trace_param.var, 6712 *stack_trace_param->name,
6709 *stack_trace_param.type); 6713 stack_trace_param->type);
6710 var->set_is_final(); 6714 var->set_is_final();
6711 bool added_to_scope = scope->AddVariable(var); 6715 bool added_to_scope = scope->AddVariable(var);
6712 if (!added_to_scope) { 6716 if (!added_to_scope) {
6713 ErrorMsg(stack_trace_param.token_pos, 6717 ErrorMsg(stack_trace_param->token_pos,
6714 "name '%s' already exists in scope", 6718 "name '%s' already exists in scope",
6715 stack_trace_param.var->ToCString()); 6719 stack_trace_param->name->ToCString());
6716 } 6720 }
6721 stack_trace_param->var = var;
6717 } 6722 }
6718 } 6723 }
6719 6724
6720 6725
6721 SequenceNode* Parser::ParseFinallyBlock() { 6726 SequenceNode* Parser::ParseFinallyBlock() {
6722 TRACE_PARSER("ParseFinallyBlock"); 6727 TRACE_PARSER("ParseFinallyBlock");
6723 OpenBlock(); 6728 OpenBlock();
6724 ExpectToken(Token::kLBRACE); 6729 ExpectToken(Token::kLBRACE);
6725 ParseStatementSequence(); 6730 ParseStatementSequence();
6726 ExpectToken(Token::kRBRACE); 6731 ExpectToken(Token::kRBRACE);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
6778 } else { 6783 } else {
6779 ASSERT(node->IsJumpNode()); 6784 ASSERT(node->IsJumpNode());
6780 node->AsJumpNode()->AddInlinedFinallyNode(finally_node); 6785 node->AsJumpNode()->AddInlinedFinallyNode(finally_node);
6781 } 6786 }
6782 } 6787 }
6783 6788
6784 6789
6785 AstNode* Parser::ParseTryStatement(String* label_name) { 6790 AstNode* Parser::ParseTryStatement(String* label_name) {
6786 TRACE_PARSER("ParseTryStatement"); 6791 TRACE_PARSER("ParseTryStatement");
6787 6792
6788 // We create three stack slots for exceptions here: 6793 // We create three local variables for exceptions here:
6789 // ':saved_try_context_var' - Used to save the context before start of the try 6794 // ':saved_try_context_var' - Used to save the context before start of the
6790 // block. The context register is restored from 6795 // try block. The context register is restored
6791 // this slot before processing the catch block 6796 // from this slot before processing the catch
6792 // handler. 6797 // block handler.
6793 // ':exception_var' - Used to save the current exception object that was 6798 // ':exception_var' - Used to save the current exception object that was
6794 // thrown. 6799 // thrown.
6795 // ':stacktrace_var' - Used to save the current stack trace object into which 6800 // ':stack_trace_var' - Used to save the current stack trace object into
6796 // the stack trace was copied into when an exception was 6801 // which the stack trace was copied into when an
6797 // thrown. 6802 // exception was thrown.
6798 // :exception_var and :stacktrace_var get set with the exception object 6803 // :exception_var and :stack_trace_var get set with the exception object
6799 // and the stacktrace object when an exception is thrown. 6804 // and the stack trace object when an exception is thrown. These three
6800 // These three implicit variables can never be captured variables. 6805 // implicit variables can never be captured variables.
6801 LocalVariable* context_var = 6806 LocalVariable* context_var =
6802 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); 6807 EnsureLocalVariable(Symbols::SavedTryContextVar());
6803 if (context_var == NULL) { 6808 LocalVariable* exception_var = EnsureLocalVariable(Symbols::ExceptionVar());
6804 context_var = new LocalVariable(TokenPos(), 6809 LocalVariable* stack_trace_var =
6805 Symbols::SavedTryContextVar(), 6810 EnsureLocalVariable(Symbols::StackTraceVar());
6806 Type::ZoneHandle(Type::DynamicType()));
6807 current_block_->scope->AddVariable(context_var);
6808 }
6809 LocalVariable* catch_excp_var =
6810 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar());
6811 if (catch_excp_var == NULL) {
6812 catch_excp_var = new LocalVariable(TokenPos(),
6813 Symbols::ExceptionVar(),
6814 Type::ZoneHandle(Type::DynamicType()));
6815 current_block_->scope->AddVariable(catch_excp_var);
6816 }
6817 LocalVariable* catch_trace_var =
6818 current_block_->scope->LocalLookupVariable(Symbols::StacktraceVar());
6819 if (catch_trace_var == NULL) {
6820 catch_trace_var = new LocalVariable(TokenPos(),
6821 Symbols::StacktraceVar(),
6822 Type::ZoneHandle(Type::DynamicType()));
6823 current_block_->scope->AddVariable(catch_trace_var);
6824 }
6825 6811
6826 const intptr_t try_pos = TokenPos(); 6812 const intptr_t try_pos = TokenPos();
6827 ConsumeToken(); // Consume the 'try'. 6813 ConsumeToken(); // Consume the 'try'.
6828 6814
6829 SourceLabel* try_label = NULL; 6815 SourceLabel* try_label = NULL;
6830 if (label_name != NULL) { 6816 if (label_name != NULL) {
6831 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); 6817 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement);
6832 OpenBlock(); 6818 OpenBlock();
6833 current_block_->scope->AddLabel(try_label); 6819 current_block_->scope->AddLabel(try_label);
6834 } 6820 }
(...skipping 10 matching lines...) Expand all
6845 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && 6831 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") &&
6846 (CurrentToken() != Token::kFINALLY)) { 6832 (CurrentToken() != Token::kFINALLY)) {
6847 ErrorMsg("catch or finally clause expected"); 6833 ErrorMsg("catch or finally clause expected");
6848 } 6834 }
6849 6835
6850 // Now create a label for the end of catch block processing so that we can 6836 // Now create a label for the end of catch block processing so that we can
6851 // jump over the catch block code after executing the try block. 6837 // jump over the catch block code after executing the try block.
6852 SourceLabel* end_catch_label = 6838 SourceLabel* end_catch_label =
6853 SourceLabel::New(TokenPos(), NULL, SourceLabel::kCatch); 6839 SourceLabel::New(TokenPos(), NULL, SourceLabel::kCatch);
6854 6840
6855 // Now parse the 'catch' blocks if any and merge all of them into 6841 // Now parse the 'catch' blocks if any and merge all of them into an
6856 // an if-then sequence of the different types specified using the 'is' 6842 // if-then sequence of the different types specified using the 'is'
6857 // operator. 6843 // operator.
6858 bool generic_catch_seen = false; 6844 bool generic_catch_seen = false;
6859 const intptr_t handler_pos = TokenPos(); 6845 const intptr_t handler_pos = TokenPos();
6860 OpenBlock(); // Start the catch block sequence. 6846 OpenBlock(); // Start the catch block sequence.
6861 current_block_->scope->AddLabel(end_catch_label); 6847 current_block_->scope->AddLabel(end_catch_label);
6862 const GrowableObjectArray& handler_types = 6848 const GrowableObjectArray& handler_types =
6863 GrowableObjectArray::Handle(GrowableObjectArray::New()); 6849 GrowableObjectArray::Handle(GrowableObjectArray::New());
6864 bool needs_stacktrace = false; 6850 bool needs_stack_trace = false;
6865 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { 6851 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) {
6866 const intptr_t catch_pos = TokenPos(); 6852 const intptr_t catch_pos = TokenPos();
6867 CatchParamDesc exception_param; 6853 CatchParameter exception_param;
6868 CatchParamDesc stack_trace_param; 6854 CatchParameter stack_trace_param;
6869 if (IsLiteral("on")) { 6855 if (IsLiteral("on")) {
6870 ConsumeToken(); 6856 ConsumeToken();
6871 exception_param.type = &AbstractType::ZoneHandle( 6857 exception_param.type = ParseType(ClassFinalizer::kCanonicalize);
6872 ParseType(ClassFinalizer::kCanonicalize));
6873 } else { 6858 } else {
6874 exception_param.type = 6859 exception_param.type = Type::DynamicType();
6875 &AbstractType::ZoneHandle(Type::DynamicType());
6876 } 6860 }
6877 if (CurrentToken() == Token::kCATCH) { 6861 if (CurrentToken() == Token::kCATCH) {
6878 ConsumeToken(); // Consume the 'catch'. 6862 ConsumeToken(); // Consume the 'catch'.
6879 ExpectToken(Token::kLPAREN); 6863 ExpectToken(Token::kLPAREN);
6880 exception_param.token_pos = TokenPos(); 6864 exception_param.token_pos = TokenPos();
6881 exception_param.var = ExpectIdentifier("identifier expected"); 6865 exception_param.name = ExpectIdentifier("identifier expected");
6882 if (CurrentToken() == Token::kCOMMA) { 6866 if (CurrentToken() == Token::kCOMMA) {
6883 ConsumeToken(); 6867 ConsumeToken();
6884 // TODO(hausner): Make implicit type be StackTrace, not dynamic. 6868 // TODO(hausner): Make implicit type be StackTrace, not dynamic.
6885 stack_trace_param.type = 6869 stack_trace_param.type = Type::DynamicType();
6886 &AbstractType::ZoneHandle(Type::DynamicType());
6887 stack_trace_param.token_pos = TokenPos(); 6870 stack_trace_param.token_pos = TokenPos();
6888 stack_trace_param.var = ExpectIdentifier("identifier expected"); 6871 stack_trace_param.name = ExpectIdentifier("identifier expected");
6889 } 6872 }
6890 ExpectToken(Token::kRPAREN); 6873 ExpectToken(Token::kRPAREN);
6891 } 6874 }
6892 6875
6893 // Parse the individual catch handler code and add an unconditional 6876 // Parse the individual catch handler code and add an unconditional JUMP
6894 // JUMP to the end of the try block. 6877 // to the end of the try block.
6895 ExpectToken(Token::kLBRACE); 6878 ExpectToken(Token::kLBRACE);
6896 OpenBlock(); 6879 OpenBlock();
6897 AddCatchParamsToScope(exception_param, 6880 AddCatchParametersToScope(&exception_param, &stack_trace_param,
6898 stack_trace_param, 6881 current_block_->scope);
6899 current_block_->scope);
6900 6882
6901 if (exception_param.var != NULL) { 6883 if (exception_param.var != NULL) {
6902 // Generate code to load the exception object (:exception_var) into 6884 // Generate code to load the exception object (:exception_var) into
6903 // the exception variable specified in this block. 6885 // the exception variable specified in this block.
6904 LocalVariable* var = LookupLocalScope(*exception_param.var); 6886 ASSERT(exception_var != NULL);
6905 ASSERT(var != NULL);
6906 ASSERT(catch_excp_var != NULL);
6907 current_block_->statements->Add( 6887 current_block_->statements->Add(
6908 new StoreLocalNode(catch_pos, var, 6888 new StoreLocalNode(catch_pos, exception_param.var,
6909 new LoadLocalNode(catch_pos, catch_excp_var))); 6889 new LoadLocalNode(catch_pos, exception_var)));
6910 } 6890 }
6911 if (stack_trace_param.var != NULL) { 6891 if (stack_trace_param.var != NULL) {
6912 // 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
6913 // to load the stack trace object (:stacktrace_var) into the stack trace 6893 // to load the stack trace object (:stack_trace_var) into the stack
6914 // variable specified in this block. 6894 // trace variable specified in this block.
6915 needs_stacktrace = true; 6895 needs_stack_trace = true;
6916 ArgumentListNode* no_args = new ArgumentListNode(catch_pos); 6896 ArgumentListNode* no_args = new ArgumentListNode(catch_pos);
6917 LocalVariable* trace = LookupLocalScope(*stack_trace_param.var); 6897 ASSERT(stack_trace_var != NULL);
6918 ASSERT(catch_trace_var != NULL);
6919 current_block_->statements->Add( 6898 current_block_->statements->Add(
6920 new StoreLocalNode(catch_pos, trace, 6899 new StoreLocalNode(catch_pos, stack_trace_param.var,
6921 new LoadLocalNode(catch_pos, catch_trace_var))); 6900 new LoadLocalNode(catch_pos, stack_trace_var)));
6922 current_block_->statements->Add( 6901 current_block_->statements->Add(
6923 new InstanceCallNode( 6902 new InstanceCallNode(
6924 catch_pos, 6903 catch_pos,
6925 new LoadLocalNode(catch_pos, trace), 6904 new LoadLocalNode(catch_pos, stack_trace_param.var),
6926 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), 6905 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()),
6927 no_args)); 6906 no_args));
6928 } 6907 }
6929 6908
6930 ParseStatementSequence(); // Parse the catch handler code. 6909 ParseStatementSequence(); // Parse the catch handler code.
6931 current_block_->statements->Add( 6910 current_block_->statements->Add(
6932 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label)); 6911 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label));
6933 SequenceNode* catch_handler = CloseBlock(); 6912 SequenceNode* catch_handler = CloseBlock();
6934 ExpectToken(Token::kRBRACE); 6913 ExpectToken(Token::kRBRACE);
6935 6914
6936 if (!exception_param.type->IsDynamicType()) { // Has a type specification. 6915 if (!exception_param.type.IsDynamicType()) { // Has a type specification.
6937 // Now form an 'if type check' as an exception type exists in 6916 // Now form an 'if type check' as an exception type exists in the
6938 // the catch specifier. 6917 // catch specifier.
6939 if (!exception_param.type->IsInstantiated() && 6918 if (!exception_param.type.IsInstantiated() &&
6940 (current_block_->scope->function_level() > 0)) { 6919 (current_block_->scope->function_level() > 0)) {
6941 // Make sure that the instantiator is captured. 6920 // Make sure that the instantiator is captured.
6942 CaptureInstantiator(); 6921 CaptureInstantiator();
6943 } 6922 }
6944 TypeNode* exception_type = new TypeNode(catch_pos, *exception_param.type); 6923 TypeNode* exception_type = new TypeNode(catch_pos, exception_param.type);
6945 AstNode* exception_var = new LoadLocalNode(catch_pos, catch_excp_var); 6924 AstNode* exception_value = new LoadLocalNode(catch_pos, exception_var);
6946 if (!exception_type->type().IsInstantiated()) { 6925 if (!exception_type->type().IsInstantiated()) {
6947 EnsureExpressionTemp(); 6926 EnsureExpressionTemp();
6948 } 6927 }
6949 AstNode* type_cond_expr = new ComparisonNode( 6928 AstNode* type_cond_expr = new ComparisonNode(
6950 catch_pos, Token::kIS, exception_var, exception_type); 6929 catch_pos, Token::kIS, exception_value, exception_type);
6951 current_block_->statements->Add( 6930 current_block_->statements->Add(
6952 new IfNode(catch_pos, type_cond_expr, catch_handler, NULL)); 6931 new IfNode(catch_pos, type_cond_expr, catch_handler, NULL));
6953 6932
6954 // Do not add uninstantiated types (e.g. type parameter T or 6933 // Do not add uninstantiated types (e.g. type parameter T or generic
6955 // generic type List<T>), since the debugger won't be able to 6934 // type List<T>), since the debugger won't be able to instantiate it
6956 // instantiate it when walking the stack. 6935 // when walking the stack. This means that the debugger is not able
6957 // This means that the debugger is not able to determine whether 6936 // to determine whether an exception is caught if the catch clause
6958 // an exception is caught if the catch clause uses generic types. 6937 // uses generic types. It will report the exception as uncaught when
6959 // It will report the exception as uncaught when in fact it might 6938 // in fact it might be caught and handled when we unwind the stack.
6960 // be caught and handled when we unwind the stack. 6939 if (exception_param.type.IsInstantiated()) {
6961 if (exception_param.type->IsInstantiated()) { 6940 handler_types.Add(exception_param.type);
6962 handler_types.Add(*exception_param.type);
6963 } 6941 }
6964 } else { 6942 } else {
6965 // No exception type exists in the catch specifier so execute the 6943 // No exception type exists in the catch specifier so execute the
6966 // catch handler code unconditionally. 6944 // catch handler code unconditionally.
6967 current_block_->statements->Add(catch_handler); 6945 current_block_->statements->Add(catch_handler);
6968 generic_catch_seen = true; 6946 generic_catch_seen = true;
6969 // This catch clause will handle all exceptions. We can safely forget 6947 // This catch clause will handle all exceptions. We can safely forget
6970 // all previous catch clause types. 6948 // all previous catch clause types.
6971 handler_types.SetLength(0); 6949 handler_types.SetLength(0);
6972 handler_types.Add(*exception_param.type); 6950 handler_types.Add(exception_param.type);
6973 } 6951 }
6974 } 6952 }
6975 SequenceNode* catch_handler_list = CloseBlock(); 6953 SequenceNode* catch_handler_list = CloseBlock();
6976 TryBlocks* inner_try_block = PopTryBlock(); 6954 TryBlocks* inner_try_block = PopTryBlock();
6977 const intptr_t try_index = inner_try_block->try_index(); 6955 const intptr_t try_index = inner_try_block->try_index();
6978 TryBlocks* outer_try_block = try_blocks_list_; 6956 TryBlocks* outer_try_block = try_blocks_list_;
6979 const intptr_t outer_try_index = (outer_try_block != NULL) 6957 const intptr_t outer_try_index = (outer_try_block != NULL)
6980 ? outer_try_block->try_index() 6958 ? outer_try_block->try_index()
6981 : CatchClauseNode::kInvalidTryIndex; 6959 : CatchClauseNode::kInvalidTryIndex;
6982 6960
(...skipping 15 matching lines...) Expand all
6998 outer_try_index); 6976 outer_try_index);
6999 AddFinallyBlockToNode(node_to_inline, node); 6977 AddFinallyBlockToNode(node_to_inline, node);
7000 node_index += 1; 6978 node_index += 1;
7001 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index); 6979 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index);
7002 tokens_iterator_.SetCurrentPosition(finally_pos); 6980 tokens_iterator_.SetCurrentPosition(finally_pos);
7003 } 6981 }
7004 finally_block = ParseFinallyBlock(); 6982 finally_block = ParseFinallyBlock();
7005 } 6983 }
7006 6984
7007 if (!generic_catch_seen) { 6985 if (!generic_catch_seen) {
7008 // No generic catch handler exists so rethrow the exception so that 6986 // No generic catch handler exists so rethrow the exception so that the
7009 // the next catch handler can deal with it. 6987 // next catch handler can deal with it.
7010 catch_handler_list->Add( 6988 catch_handler_list->Add(
7011 new ThrowNode(handler_pos, 6989 new ThrowNode(handler_pos,
7012 new LoadLocalNode(handler_pos, catch_excp_var), 6990 new LoadLocalNode(handler_pos, exception_var),
7013 new LoadLocalNode(handler_pos, catch_trace_var))); 6991 new LoadLocalNode(handler_pos, stack_trace_var)));
7014 } 6992 }
7015 CatchClauseNode* catch_block = 6993 CatchClauseNode* catch_block =
7016 new CatchClauseNode(handler_pos, 6994 new CatchClauseNode(handler_pos,
7017 catch_handler_list, 6995 catch_handler_list,
7018 Array::ZoneHandle(Array::MakeArray(handler_types)), 6996 Array::ZoneHandle(Array::MakeArray(handler_types)),
7019 context_var, 6997 context_var,
7020 catch_excp_var, 6998 exception_var,
7021 catch_trace_var, 6999 stack_trace_var,
7022 (finally_block != NULL) 7000 (finally_block != NULL)
7023 ? AllocateTryIndex() 7001 ? AllocateTryIndex()
7024 : CatchClauseNode::kInvalidTryIndex, 7002 : CatchClauseNode::kInvalidTryIndex,
7025 needs_stacktrace); 7003 needs_stack_trace);
7026 7004
7027 // Now create the try/catch ast node and return it. If there is a label 7005 // Now create the try/catch ast node and return it. If there is a label on
7028 // on the try/catch, close the block that's embedding the try statement 7006 // the try/catch, close the block that's embedding the try statement and
7029 // and attach the label to it. 7007 // attach the label to it.
7030 AstNode* try_catch_node = 7008 AstNode* try_catch_node =
7031 new TryCatchNode(try_pos, try_block, end_catch_label, 7009 new TryCatchNode(try_pos, try_block, end_catch_label,
7032 context_var, catch_block, finally_block, try_index); 7010 context_var, catch_block, finally_block, try_index);
7033 7011
7034 if (try_label != NULL) { 7012 if (try_label != NULL) {
7035 current_block_->statements->Add(try_catch_node); 7013 current_block_->statements->Add(try_catch_node);
7036 SequenceNode* sequence = CloseBlock(); 7014 SequenceNode* sequence = CloseBlock();
7037 sequence->set_label(try_label); 7015 sequence->set_label(try_label);
7038 try_catch_node = sequence; 7016 try_catch_node = sequence;
7039 } 7017 }
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
7187 ExpectSemicolon(); 7165 ExpectSemicolon();
7188 // Check if it is ok to do a rethrow. 7166 // Check if it is ok to do a rethrow.
7189 SourceLabel* label = current_block_->scope->LookupInnermostCatchLabel(); 7167 SourceLabel* label = current_block_->scope->LookupInnermostCatchLabel();
7190 if (label == NULL || 7168 if (label == NULL ||
7191 label->FunctionLevel() != current_block_->scope->function_level()) { 7169 label->FunctionLevel() != current_block_->scope->function_level()) {
7192 ErrorMsg(statement_pos, "rethrow of an exception is not valid here"); 7170 ErrorMsg(statement_pos, "rethrow of an exception is not valid here");
7193 } 7171 }
7194 ASSERT(label->owner() != NULL); 7172 ASSERT(label->owner() != NULL);
7195 LocalScope* scope = label->owner()->parent(); 7173 LocalScope* scope = label->owner()->parent();
7196 ASSERT(scope != NULL); 7174 ASSERT(scope != NULL);
7197 LocalVariable* excp_var = 7175 LocalVariable* exception_var =
7198 scope->LocalLookupVariable(Symbols::ExceptionVar()); 7176 scope->LocalLookupVariable(Symbols::ExceptionVar());
7199 ASSERT(excp_var != NULL); 7177 ASSERT(exception_var != NULL);
7200 LocalVariable* trace_var = 7178 LocalVariable* stack_trace_var =
7201 scope->LocalLookupVariable(Symbols::StacktraceVar()); 7179 scope->LocalLookupVariable(Symbols::StackTraceVar());
7202 ASSERT(trace_var != NULL); 7180 ASSERT(stack_trace_var != NULL);
7203 statement = new ThrowNode(statement_pos, 7181 statement =
7204 new LoadLocalNode(statement_pos, excp_var), 7182 new ThrowNode(statement_pos,
7205 new LoadLocalNode(statement_pos, trace_var)); 7183 new LoadLocalNode(statement_pos, exception_var),
7184 new LoadLocalNode(statement_pos, stack_trace_var));
7206 } else { 7185 } else {
7207 statement = ParseExpr(kAllowConst, kConsumeCascades); 7186 statement = ParseExpr(kAllowConst, kConsumeCascades);
7208 ExpectSemicolon(); 7187 ExpectSemicolon();
7209 } 7188 }
7210 return statement; 7189 return statement;
7211 } 7190 }
7212 7191
7213 7192
7214 RawError* Parser::FormatErrorWithAppend(const Error& prev_error, 7193 RawError* Parser::FormatErrorWithAppend(const Error& prev_error,
7215 const Script& script, 7194 const Script& script,
(...skipping 3556 matching lines...) Expand 10 before | Expand all | Expand 10 after
10772 void Parser::SkipQualIdent() { 10751 void Parser::SkipQualIdent() {
10773 ASSERT(IsIdentifier()); 10752 ASSERT(IsIdentifier());
10774 ConsumeToken(); 10753 ConsumeToken();
10775 if (CurrentToken() == Token::kPERIOD) { 10754 if (CurrentToken() == Token::kPERIOD) {
10776 ConsumeToken(); // Consume the kPERIOD token. 10755 ConsumeToken(); // Consume the kPERIOD token.
10777 ExpectIdentifier("identifier expected after '.'"); 10756 ExpectIdentifier("identifier expected after '.'");
10778 } 10757 }
10779 } 10758 }
10780 10759
10781 } // namespace dart 10760 } // namespace dart
OLDNEW
« runtime/vm/parser.h ('K') | « runtime/vm/parser.h ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698