| 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 "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 SequenceNode* initialize_field = new SequenceNode(ident_pos, NULL); | 975 SequenceNode* initialize_field = new SequenceNode(ident_pos, NULL); |
| 976 initialize_field->Add( | 976 initialize_field->Add( |
| 977 new StoreStaticFieldNode( | 977 new StoreStaticFieldNode( |
| 978 ident_pos, | 978 ident_pos, |
| 979 field, | 979 field, |
| 980 new LiteralNode(ident_pos, Object::transition_sentinel()))); | 980 new LiteralNode(ident_pos, Object::transition_sentinel()))); |
| 981 // TODO(hausner): If evaluation of the field value throws an exception, | 981 // TODO(hausner): If evaluation of the field value throws an exception, |
| 982 // we leave the field value as 'transition_sentinel', which is wrong. | 982 // we leave the field value as 'transition_sentinel', which is wrong. |
| 983 // A second reference to the field later throws a circular dependency | 983 // A second reference to the field later throws a circular dependency |
| 984 // exception. The field should instead be set to null after an exception. | 984 // exception. The field should instead be set to null after an exception. |
| 985 const String& init_name = | 985 const String& init_name = String::Handle( |
| 986 String::Handle(Symbols::New(String::Handle( | 986 Symbols::New(String::Handle(String::Concat( |
| 987 String::Concat(Symbols::InitPrefix(), String::Handle(field.name()))))); | 987 Symbols::InitPrefix(), String::Handle(field.name()))))); |
| 988 const Function& init_function = Function::ZoneHandle( | 988 const Function& init_function = Function::ZoneHandle( |
| 989 field_class.LookupStaticFunction(init_name)); | 989 field_class.LookupStaticFunction(init_name)); |
| 990 ASSERT(!init_function.IsNull()); | 990 ASSERT(!init_function.IsNull()); |
| 991 ArgumentListNode* arguments = new ArgumentListNode(expr_pos); | 991 ArgumentListNode* arguments = new ArgumentListNode(expr_pos); |
| 992 StaticCallNode* init_call = | 992 StaticCallNode* init_call = |
| 993 new StaticCallNode(expr_pos, init_function, arguments); | 993 new StaticCallNode(expr_pos, init_function, arguments); |
| 994 initialize_field->Add(init_call); |
| 994 | 995 |
| 995 initialize_field->Add(new StoreStaticFieldNode(ident_pos, | |
| 996 field, | |
| 997 init_call)); | |
| 998 AstNode* uninitialized_check = | 996 AstNode* uninitialized_check = |
| 999 new IfNode(ident_pos, compare_uninitialized, initialize_field, NULL); | 997 new IfNode(ident_pos, compare_uninitialized, initialize_field, NULL); |
| 1000 current_block_->statements->Add(uninitialized_check); | 998 current_block_->statements->Add(uninitialized_check); |
| 1001 | 999 |
| 1002 // Generate code returning the field value. | 1000 // Generate code returning the field value. |
| 1003 ReturnNode* return_node = | 1001 ReturnNode* return_node = |
| 1004 new ReturnNode(ident_pos, | 1002 new ReturnNode(ident_pos, |
| 1005 new LoadStaticFieldNode(ident_pos, field)); | 1003 new LoadStaticFieldNode(ident_pos, field)); |
| 1006 current_block_->statements->Add(return_node); | 1004 current_block_->statements->Add(return_node); |
| 1007 } | 1005 } |
| 1008 return CloseBlock(); | 1006 return CloseBlock(); |
| 1009 } | 1007 } |
| 1010 | 1008 |
| 1011 | 1009 |
| 1012 SequenceNode* Parser::ParseStaticInitializer(const Function& func) { | 1010 SequenceNode* Parser::ParseStaticInitializer(const Function& func) { |
| 1013 TRACE_PARSER("ParseStaticInitializer"); | 1011 TRACE_PARSER("ParseStaticInitializer"); |
| 1014 ParamList params; | 1012 ParamList params; |
| 1015 ASSERT(func.num_fixed_parameters() == 0); // static. | 1013 ASSERT(func.num_fixed_parameters() == 0); // static. |
| 1016 ASSERT(!func.HasOptionalParameters()); | 1014 ASSERT(!func.HasOptionalParameters()); |
| 1017 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 1015 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 1018 | 1016 |
| 1019 // Build local scope for function and populate with the formal parameters. | 1017 // Build local scope for function and populate with the formal parameters. |
| 1020 OpenFunctionBlock(func); | 1018 OpenFunctionBlock(func); |
| 1021 AddFormalParamsToScope(¶ms, current_block_->scope); | 1019 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1022 | 1020 |
| 1023 intptr_t expr_pos = func.token_pos(); | 1021 // Move forward to the start of the initializer expression. |
| 1022 ExpectIdentifier("identifier expected"); |
| 1023 ExpectToken(Token::kASSIGN); |
| 1024 intptr_t token_pos = TokenPos(); |
| 1025 |
| 1026 // Synthesize a try-catch block to wrap the initializer expression. |
| 1027 LocalVariable* context_var = |
| 1028 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); |
| 1029 if (context_var == NULL) { |
| 1030 context_var = new LocalVariable(token_pos, |
| 1031 Symbols::SavedTryContextVar(), |
| 1032 Type::ZoneHandle(Type::DynamicType())); |
| 1033 current_block_->scope->AddVariable(context_var); |
| 1034 } |
| 1035 LocalVariable* catch_excp_var = |
| 1036 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar()); |
| 1037 if (catch_excp_var == NULL) { |
| 1038 catch_excp_var = new LocalVariable(token_pos, |
| 1039 Symbols::ExceptionVar(), |
| 1040 Type::ZoneHandle(Type::DynamicType())); |
| 1041 current_block_->scope->AddVariable(catch_excp_var); |
| 1042 } |
| 1043 LocalVariable* catch_trace_var = |
| 1044 current_block_->scope->LocalLookupVariable(Symbols::StacktraceVar()); |
| 1045 if (catch_trace_var == NULL) { |
| 1046 catch_trace_var = new LocalVariable(token_pos, |
| 1047 Symbols::StacktraceVar(), |
| 1048 Type::ZoneHandle(Type::DynamicType())); |
| 1049 current_block_->scope->AddVariable(catch_trace_var); |
| 1050 } |
| 1051 |
| 1052 OpenBlock(); // Start try block. |
| 1024 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 1053 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 1025 ReturnNode* return_node = new ReturnNode(expr_pos, expr); | 1054 const Field& field = Field::ZoneHandle(func.saved_static_field()); |
| 1026 current_block_->statements->Add(return_node); | 1055 ASSERT(!field.is_const()); |
| 1056 StoreStaticFieldNode* store = new StoreStaticFieldNode(field.token_pos(), |
| 1057 field, |
| 1058 expr); |
| 1059 current_block_->statements->Add(store); |
| 1060 SequenceNode* try_block = CloseBlock(); // End try block. |
| 1061 |
| 1062 OpenBlock(); // Start catch handler list. |
| 1063 SourceLabel* end_catch_label = |
| 1064 SourceLabel::New(token_pos, NULL, SourceLabel::kCatch); |
| 1065 current_block_->scope->AddLabel(end_catch_label); |
| 1066 |
| 1067 OpenBlock(); // Start catch clause. |
| 1068 AstNode* compare_transition_sentinel = new ComparisonNode( |
| 1069 token_pos, |
| 1070 Token::kEQ_STRICT, |
| 1071 new LoadStaticFieldNode(token_pos, field), |
| 1072 new LiteralNode(field.token_pos(), Object::transition_sentinel())); |
| 1073 |
| 1074 SequenceNode* store_null = new SequenceNode(token_pos, NULL); |
| 1075 store_null->Add(new StoreStaticFieldNode( |
| 1076 field.token_pos(), |
| 1077 field, |
| 1078 new LiteralNode(token_pos, Instance::ZoneHandle()))); |
| 1079 AstNode* transition_sentinel_check = |
| 1080 new IfNode(token_pos, compare_transition_sentinel, store_null, NULL); |
| 1081 current_block_->statements->Add(transition_sentinel_check); |
| 1082 |
| 1083 current_block_->statements->Add( |
| 1084 new ThrowNode(token_pos, |
| 1085 new LoadLocalNode(token_pos, catch_excp_var), |
| 1086 new LoadLocalNode(token_pos, catch_trace_var))); |
| 1087 current_block_->statements->Add( |
| 1088 new JumpNode(token_pos, Token::kCONTINUE, end_catch_label)); |
| 1089 SequenceNode* catch_clause = CloseBlock(); // End catch clause. |
| 1090 |
| 1091 current_block_->statements->Add(catch_clause); |
| 1092 SequenceNode* catch_handler_list = CloseBlock(); // End catch handler list. |
| 1093 CatchClauseNode* catch_block = |
| 1094 new CatchClauseNode(token_pos, |
| 1095 catch_handler_list, |
| 1096 Array::ZoneHandle(Object::empty_array().raw()), |
| 1097 context_var, |
| 1098 catch_excp_var, |
| 1099 catch_trace_var, |
| 1100 CatchClauseNode::kInvalidTryIndex, |
| 1101 false); // No stack trace needed. |
| 1102 |
| 1103 AstNode* try_catch_node = new TryCatchNode(token_pos, |
| 1104 try_block, |
| 1105 end_catch_label, |
| 1106 context_var, |
| 1107 catch_block, |
| 1108 NULL, // No finally block. |
| 1109 AllocateTryIndex()); |
| 1110 current_block_->statements->Add(try_catch_node); |
| 1027 return CloseBlock(); | 1111 return CloseBlock(); |
| 1028 } | 1112 } |
| 1029 | 1113 |
| 1030 | 1114 |
| 1031 // Create AstNodes for an implicit instance getter method: | 1115 // Create AstNodes for an implicit instance getter method: |
| 1032 // LoadLocalNode 0 ('this'); | 1116 // LoadLocalNode 0 ('this'); |
| 1033 // LoadInstanceFieldNode (field_name); | 1117 // LoadInstanceFieldNode (field_name); |
| 1034 // ReturnNode (field's value); | 1118 // ReturnNode (field's value); |
| 1035 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { | 1119 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { |
| 1036 TRACE_PARSER("ParseInstanceGetter"); | 1120 TRACE_PARSER("ParseInstanceGetter"); |
| (...skipping 2227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3264 if (field->has_factory) { | 3348 if (field->has_factory) { |
| 3265 ErrorMsg("keyword 'factory' not allowed in field declaration"); | 3349 ErrorMsg("keyword 'factory' not allowed in field declaration"); |
| 3266 } | 3350 } |
| 3267 if (!field->has_static && field->has_const) { | 3351 if (!field->has_static && field->has_const) { |
| 3268 ErrorMsg(field->name_pos, "instance field may not be 'const'"); | 3352 ErrorMsg(field->name_pos, "instance field may not be 'const'"); |
| 3269 } | 3353 } |
| 3270 Function& getter = Function::Handle(); | 3354 Function& getter = Function::Handle(); |
| 3271 Function& setter = Function::Handle(); | 3355 Function& setter = Function::Handle(); |
| 3272 Field& class_field = Field::ZoneHandle(); | 3356 Field& class_field = Field::ZoneHandle(); |
| 3273 Instance& init_value = Instance::Handle(); | 3357 Instance& init_value = Instance::Handle(); |
| 3274 intptr_t expr_pos = -1; | |
| 3275 while (true) { | 3358 while (true) { |
| 3276 bool has_initializer = CurrentToken() == Token::kASSIGN; | 3359 bool has_initializer = CurrentToken() == Token::kASSIGN; |
| 3277 bool has_simple_literal = false; | 3360 bool has_simple_literal = false; |
| 3278 if (has_initializer) { | 3361 if (has_initializer) { |
| 3279 ConsumeToken(); | 3362 ConsumeToken(); |
| 3280 init_value = Object::sentinel().raw(); | 3363 init_value = Object::sentinel().raw(); |
| 3281 // For static const fields and static final non-const fields, the | 3364 // For static const fields and static final non-const fields, the |
| 3282 // initialization expression will be parsed through the | 3365 // initialization expression will be parsed through the |
| 3283 // kImplicitStaticFinalGetter method invocation/compilation. | 3366 // kImplicitStaticFinalGetter method invocation/compilation. |
| 3284 // For instance fields, the expression is parsed when a constructor | 3367 // For instance fields, the expression is parsed when a constructor |
| 3285 // is compiled. | 3368 // is compiled. |
| 3286 // For static const fields and static final non-const fields with very | 3369 // For static const fields and static final non-const fields with very |
| 3287 // simple initializer expressions (e.g. a literal number or string), we | 3370 // simple initializer expressions (e.g. a literal number or string), we |
| 3288 // optimize away the kImplicitStaticFinalGetter and initialize the field | 3371 // optimize away the kImplicitStaticFinalGetter and initialize the field |
| 3289 // here. However, the class finalizer will check the value type for | 3372 // here. However, the class finalizer will check the value type for |
| 3290 // assignability once the declared field type can be resolved. If the | 3373 // assignability once the declared field type can be resolved. If the |
| 3291 // value is not assignable (assuming checked mode and disregarding actual | 3374 // value is not assignable (assuming checked mode and disregarding actual |
| 3292 // mode), the field value is reset and a kImplicitStaticFinalGetter is | 3375 // mode), the field value is reset and a kImplicitStaticFinalGetter is |
| 3293 // created at finalization time. | 3376 // created at finalization time. |
| 3294 | 3377 |
| 3295 if (field->has_static && (field->has_const || field->has_final) && | 3378 if (field->has_static && (field->has_const || field->has_final) && |
| 3296 (LookaheadToken(1) == Token::kSEMICOLON)) { | 3379 (LookaheadToken(1) == Token::kSEMICOLON)) { |
| 3297 has_simple_literal = IsSimpleLiteral(*field->type, &init_value); | 3380 has_simple_literal = IsSimpleLiteral(*field->type, &init_value); |
| 3298 } | 3381 } |
| 3299 expr_pos = TokenPos(); | |
| 3300 SkipExpr(); | 3382 SkipExpr(); |
| 3301 } else { | 3383 } else { |
| 3302 // Static const and static final fields must have an initializer. | 3384 // Static const and static final fields must have an initializer. |
| 3303 // Static const fields are implicitly final. | 3385 // Static const fields are implicitly final. |
| 3304 if (field->has_static && field->has_final) { | 3386 if (field->has_static && field->has_final) { |
| 3305 ErrorMsg(field->name_pos, | 3387 ErrorMsg(field->name_pos, |
| 3306 "static %s field '%s' must have an initializer expression", | 3388 "static %s field '%s' must have an initializer expression", |
| 3307 field->has_const ? "const" : "final", | 3389 field->has_const ? "const" : "final", |
| 3308 field->name->ToCString()); | 3390 field->name->ToCString()); |
| 3309 } | 3391 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3334 RawFunction::kImplicitStaticFinalGetter, | 3416 RawFunction::kImplicitStaticFinalGetter, |
| 3335 field->has_static, | 3417 field->has_static, |
| 3336 field->has_const, | 3418 field->has_const, |
| 3337 /* is_abstract = */ false, | 3419 /* is_abstract = */ false, |
| 3338 /* is_external = */ false, | 3420 /* is_external = */ false, |
| 3339 current_class(), | 3421 current_class(), |
| 3340 field->name_pos); | 3422 field->name_pos); |
| 3341 getter.set_result_type(*field->type); | 3423 getter.set_result_type(*field->type); |
| 3342 members->AddFunction(getter); | 3424 members->AddFunction(getter); |
| 3343 | 3425 |
| 3344 // Create initializer function. | 3426 // Create initializer function for non-const fields. |
| 3345 const Function& init_function = Function::ZoneHandle( | 3427 if (!class_field.is_const()) { |
| 3346 Function::NewStaticInitializer(*field->name, | 3428 const Function& init_function = Function::ZoneHandle( |
| 3347 *field->type, | 3429 Function::NewStaticInitializer(class_field)); |
| 3348 current_class(), | 3430 members->AddFunction(init_function); |
| 3349 expr_pos)); | 3431 } |
| 3350 members->AddFunction(init_function); | |
| 3351 } | 3432 } |
| 3352 } | 3433 } |
| 3353 | 3434 |
| 3354 // For instance fields, we create implicit getter and setter methods. | 3435 // For instance fields, we create implicit getter and setter methods. |
| 3355 if (!field->has_static) { | 3436 if (!field->has_static) { |
| 3356 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); | 3437 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); |
| 3357 getter = Function::New(getter_name, RawFunction::kImplicitGetter, | 3438 getter = Function::New(getter_name, RawFunction::kImplicitGetter, |
| 3358 field->has_static, | 3439 field->has_static, |
| 3359 field->has_final, | 3440 field->has_final, |
| 3360 /* is_abstract = */ false, | 3441 /* is_abstract = */ false, |
| (...skipping 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4450 if (metadata_pos >= 0) { | 4531 if (metadata_pos >= 0) { |
| 4451 library_.AddFieldMetadata(field, metadata_pos); | 4532 library_.AddFieldMetadata(field, metadata_pos); |
| 4452 } | 4533 } |
| 4453 if (CurrentToken() == Token::kASSIGN) { | 4534 if (CurrentToken() == Token::kASSIGN) { |
| 4454 ConsumeToken(); | 4535 ConsumeToken(); |
| 4455 Instance& field_value = Instance::Handle(Object::sentinel().raw()); | 4536 Instance& field_value = Instance::Handle(Object::sentinel().raw()); |
| 4456 bool has_simple_literal = false; | 4537 bool has_simple_literal = false; |
| 4457 if ((is_const || is_final) && (LookaheadToken(1) == Token::kSEMICOLON)) { | 4538 if ((is_const || is_final) && (LookaheadToken(1) == Token::kSEMICOLON)) { |
| 4458 has_simple_literal = IsSimpleLiteral(type, &field_value); | 4539 has_simple_literal = IsSimpleLiteral(type, &field_value); |
| 4459 } | 4540 } |
| 4460 const intptr_t expr_pos = TokenPos(); | |
| 4461 SkipExpr(); | 4541 SkipExpr(); |
| 4462 field.set_value(field_value); | 4542 field.set_value(field_value); |
| 4463 if (!has_simple_literal) { | 4543 if (!has_simple_literal) { |
| 4464 // Create a static final getter. | 4544 // Create a static final getter. |
| 4465 String& getter_name = String::Handle(Field::GetterSymbol(var_name)); | 4545 String& getter_name = String::Handle(Field::GetterSymbol(var_name)); |
| 4466 getter = Function::New(getter_name, | 4546 getter = Function::New(getter_name, |
| 4467 RawFunction::kImplicitStaticFinalGetter, | 4547 RawFunction::kImplicitStaticFinalGetter, |
| 4468 is_static, | 4548 is_static, |
| 4469 is_const, | 4549 is_const, |
| 4470 /* is_abstract = */ false, | 4550 /* is_abstract = */ false, |
| 4471 /* is_external = */ false, | 4551 /* is_external = */ false, |
| 4472 current_class(), | 4552 current_class(), |
| 4473 name_pos); | 4553 name_pos); |
| 4474 getter.set_result_type(type); | 4554 getter.set_result_type(type); |
| 4475 top_level->functions.Add(getter); | 4555 top_level->functions.Add(getter); |
| 4476 | 4556 |
| 4477 // Create initializer function. | 4557 // Create initializer function. |
| 4478 const Function& init_function = Function::ZoneHandle( | 4558 if (!field.is_const()) { |
| 4479 Function::NewStaticInitializer(var_name, | 4559 const Function& init_function = Function::ZoneHandle( |
| 4480 type, | 4560 Function::NewStaticInitializer(field)); |
| 4481 current_class(), | 4561 top_level->functions.Add(init_function); |
| 4482 expr_pos)); | 4562 } |
| 4483 top_level->functions.Add(init_function); | |
| 4484 } | 4563 } |
| 4485 } else if (is_final) { | 4564 } else if (is_final) { |
| 4486 ErrorMsg(name_pos, "missing initializer for final or const variable"); | 4565 ErrorMsg(name_pos, "missing initializer for final or const variable"); |
| 4487 } | 4566 } |
| 4488 | 4567 |
| 4489 if (CurrentToken() == Token::kCOMMA) { | 4568 if (CurrentToken() == Token::kCOMMA) { |
| 4490 ConsumeToken(); | 4569 ConsumeToken(); |
| 4491 } else if (CurrentToken() == Token::kSEMICOLON) { | 4570 } else if (CurrentToken() == Token::kSEMICOLON) { |
| 4492 ConsumeToken(); | 4571 ConsumeToken(); |
| 4493 break; | 4572 break; |
| (...skipping 2206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6700 // Now create a label for the end of catch block processing so that we can | 6779 // Now create a label for the end of catch block processing so that we can |
| 6701 // jump over the catch block code after executing the try block. | 6780 // jump over the catch block code after executing the try block. |
| 6702 SourceLabel* end_catch_label = | 6781 SourceLabel* end_catch_label = |
| 6703 SourceLabel::New(TokenPos(), NULL, SourceLabel::kCatch); | 6782 SourceLabel::New(TokenPos(), NULL, SourceLabel::kCatch); |
| 6704 | 6783 |
| 6705 // Now parse the 'catch' blocks if any and merge all of them into | 6784 // Now parse the 'catch' blocks if any and merge all of them into |
| 6706 // an if-then sequence of the different types specified using the 'is' | 6785 // an if-then sequence of the different types specified using the 'is' |
| 6707 // operator. | 6786 // operator. |
| 6708 bool catch_seen = false; | 6787 bool catch_seen = false; |
| 6709 bool generic_catch_seen = false; | 6788 bool generic_catch_seen = false; |
| 6710 SequenceNode* catch_handler_list = NULL; | |
| 6711 const intptr_t handler_pos = TokenPos(); | 6789 const intptr_t handler_pos = TokenPos(); |
| 6712 OpenBlock(); // Start the catch block sequence. | 6790 OpenBlock(); // Start the catch block sequence. |
| 6713 current_block_->scope->AddLabel(end_catch_label); | 6791 current_block_->scope->AddLabel(end_catch_label); |
| 6714 const GrowableObjectArray& handler_types = | 6792 const GrowableObjectArray& handler_types = |
| 6715 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 6793 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 6716 bool needs_stacktrace = false; | 6794 bool needs_stacktrace = false; |
| 6717 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { | 6795 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { |
| 6718 const intptr_t catch_pos = TokenPos(); | 6796 const intptr_t catch_pos = TokenPos(); |
| 6719 CatchParamDesc exception_param; | 6797 CatchParamDesc exception_param; |
| 6720 CatchParamDesc stack_trace_param; | 6798 CatchParamDesc stack_trace_param; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6824 // This catch clause will handle all exceptions. We can safely forget | 6902 // This catch clause will handle all exceptions. We can safely forget |
| 6825 // all previous catch clause types. | 6903 // all previous catch clause types. |
| 6826 handler_types.SetLength(0); | 6904 handler_types.SetLength(0); |
| 6827 handler_types.Add(*exception_param.type); | 6905 handler_types.Add(*exception_param.type); |
| 6828 } | 6906 } |
| 6829 SequenceNode* catch_clause = CloseBlock(); | 6907 SequenceNode* catch_clause = CloseBlock(); |
| 6830 | 6908 |
| 6831 // Add this individual catch handler to the catch handlers list. | 6909 // Add this individual catch handler to the catch handlers list. |
| 6832 current_block_->statements->Add(catch_clause); | 6910 current_block_->statements->Add(catch_clause); |
| 6833 } | 6911 } |
| 6834 catch_handler_list = CloseBlock(); | 6912 SequenceNode* catch_handler_list = CloseBlock(); |
| 6835 TryBlocks* inner_try_block = PopTryBlock(); | 6913 TryBlocks* inner_try_block = PopTryBlock(); |
| 6836 const intptr_t try_index = inner_try_block->try_index(); | 6914 const intptr_t try_index = inner_try_block->try_index(); |
| 6837 TryBlocks* outer_try_block = try_blocks_list_; | 6915 TryBlocks* outer_try_block = try_blocks_list_; |
| 6838 const intptr_t outer_try_index = (outer_try_block != NULL) | 6916 const intptr_t outer_try_index = (outer_try_block != NULL) |
| 6839 ? outer_try_block->try_index() | 6917 ? outer_try_block->try_index() |
| 6840 : CatchClauseNode::kInvalidTryIndex; | 6918 : CatchClauseNode::kInvalidTryIndex; |
| 6841 | 6919 |
| 6842 // Finally parse the 'finally' block. | 6920 // Finally parse the 'finally' block. |
| 6843 SequenceNode* finally_block = NULL; | 6921 SequenceNode* finally_block = NULL; |
| 6844 if (CurrentToken() == Token::kFINALLY) { | 6922 if (CurrentToken() == Token::kFINALLY) { |
| (...skipping 3786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10631 void Parser::SkipQualIdent() { | 10709 void Parser::SkipQualIdent() { |
| 10632 ASSERT(IsIdentifier()); | 10710 ASSERT(IsIdentifier()); |
| 10633 ConsumeToken(); | 10711 ConsumeToken(); |
| 10634 if (CurrentToken() == Token::kPERIOD) { | 10712 if (CurrentToken() == Token::kPERIOD) { |
| 10635 ConsumeToken(); // Consume the kPERIOD token. | 10713 ConsumeToken(); // Consume the kPERIOD token. |
| 10636 ExpectIdentifier("identifier expected after '.'"); | 10714 ExpectIdentifier("identifier expected after '.'"); |
| 10637 } | 10715 } |
| 10638 } | 10716 } |
| 10639 | 10717 |
| 10640 } // namespace dart | 10718 } // namespace dart |
| OLD | NEW |