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

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

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

Powered by Google App Engine
This is Rietveld 408576698