| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 820 node_sequence = parser.ParseInstanceGetter(func); | 820 node_sequence = parser.ParseInstanceGetter(func); |
| 821 break; | 821 break; |
| 822 case RawFunction::kImplicitSetter: | 822 case RawFunction::kImplicitSetter: |
| 823 ASSERT(!func.is_static()); | 823 ASSERT(!func.is_static()); |
| 824 node_sequence = parser.ParseInstanceSetter(func); | 824 node_sequence = parser.ParseInstanceSetter(func); |
| 825 break; | 825 break; |
| 826 case RawFunction::kImplicitStaticFinalGetter: | 826 case RawFunction::kImplicitStaticFinalGetter: |
| 827 node_sequence = parser.ParseStaticFinalGetter(func); | 827 node_sequence = parser.ParseStaticFinalGetter(func); |
| 828 CompilerStats::num_implicit_final_getters++; | 828 CompilerStats::num_implicit_final_getters++; |
| 829 break; | 829 break; |
| 830 case RawFunction::kStaticInitializer: | |
| 831 node_sequence = parser.ParseStaticInitializer(func); | |
| 832 CompilerStats::num_static_initializer_funcs++; | |
| 833 break; | |
| 834 case RawFunction::kMethodExtractor: | 830 case RawFunction::kMethodExtractor: |
| 835 node_sequence = parser.ParseMethodExtractor(func); | 831 node_sequence = parser.ParseMethodExtractor(func); |
| 836 break; | 832 break; |
| 837 case RawFunction::kNoSuchMethodDispatcher: | 833 case RawFunction::kNoSuchMethodDispatcher: |
| 838 node_sequence = | 834 node_sequence = |
| 839 parser.ParseNoSuchMethodDispatcher(func, &default_parameter_values); | 835 parser.ParseNoSuchMethodDispatcher(func, &default_parameter_values); |
| 840 break; | 836 break; |
| 841 case RawFunction::kInvokeFieldDispatcher: | 837 case RawFunction::kInvokeFieldDispatcher: |
| 842 node_sequence = | 838 node_sequence = |
| 843 parser.ParseInvokeFieldDispatcher(func, &default_parameter_values); | 839 parser.ParseInvokeFieldDispatcher(func, &default_parameter_values); |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 995 if (expr->EvalConstExpr() == NULL) { | 991 if (expr->EvalConstExpr() == NULL) { |
| 996 ReportError(expr_pos, "expression must be a compile-time constant"); | 992 ReportError(expr_pos, "expression must be a compile-time constant"); |
| 997 } | 993 } |
| 998 const Instance& val = EvaluateConstExpr(expr_pos, expr); | 994 const Instance& val = EvaluateConstExpr(expr_pos, expr); |
| 999 meta_values.Add(val); | 995 meta_values.Add(val); |
| 1000 } | 996 } |
| 1001 return Array::MakeArray(meta_values); | 997 return Array::MakeArray(meta_values); |
| 1002 } | 998 } |
| 1003 | 999 |
| 1004 | 1000 |
| 1001 SequenceNode* Parser::ParseStaticInitializer() { |
| 1002 ExpectIdentifier("field name expected"); |
| 1003 CheckToken(Token::kASSIGN, "field initialier expected"); |
| 1004 ConsumeToken(); |
| 1005 OpenFunctionBlock(parsed_function()->function()); |
| 1006 intptr_t expr_pos = TokenPos(); |
| 1007 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 1008 ReturnNode* ret = new(I) ReturnNode(expr_pos, expr); |
| 1009 current_block_->statements->Add(ret); |
| 1010 return CloseBlock(); |
| 1011 } |
| 1012 |
| 1013 |
| 1014 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { |
| 1015 ASSERT(field.is_static()); |
| 1016 ASSERT(field.value() == Object::transition_sentinel().raw()); |
| 1017 Isolate* isolate = Isolate::Current(); |
| 1018 |
| 1019 const Class& script_cls = Class::Handle(isolate, field.origin()); |
| 1020 const Script& script = Script::Handle(isolate, script_cls.script()); |
| 1021 |
| 1022 const String& field_name = String::Handle(isolate, field.name()); |
| 1023 String& init_name = String::Handle(isolate, |
| 1024 String::Concat(Symbols::InitPrefix(), field_name)); |
| 1025 init_name = Symbols::New(init_name); |
| 1026 |
| 1027 const Function& initializer = Function::ZoneHandle(isolate, |
| 1028 Function::New(init_name, |
| 1029 RawFunction::kRegularFunction, |
| 1030 true, // static |
| 1031 false, // !const |
| 1032 false, // !abstract |
| 1033 false, // !external |
| 1034 false, // !native |
| 1035 Class::Handle(field.owner()), |
| 1036 field.token_pos())); |
| 1037 initializer.set_result_type(AbstractType::Handle(isolate, field.type())); |
| 1038 // Static initializer functions are hidden from the user. |
| 1039 // Since they are only executed once, we avoid optimizing |
| 1040 // and inlining them. After the field is initialized, the |
| 1041 // compiler can eliminate the call to the static initializer. |
| 1042 initializer.set_is_visible(false); |
| 1043 initializer.SetIsOptimizable(false); |
| 1044 initializer.set_is_inlinable(false); |
| 1045 |
| 1046 ParsedFunction* parsed_function = new ParsedFunction(isolate, initializer); |
| 1047 Parser parser(script, parsed_function, field.token_pos()); |
| 1048 |
| 1049 SequenceNode* body = parser.ParseStaticInitializer(); |
| 1050 parsed_function->SetNodeSequence(body); |
| 1051 parsed_function->set_default_parameter_values(Object::null_array()); |
| 1052 |
| 1053 if (parsed_function->has_expression_temp_var()) { |
| 1054 body->scope()->AddVariable(parsed_function->expression_temp_var()); |
| 1055 } |
| 1056 if (parsed_function->has_saved_current_context_var()) { |
| 1057 body->scope()->AddVariable(parsed_function->saved_current_context_var()); |
| 1058 } |
| 1059 if (parsed_function->has_finally_return_temp_var()) { |
| 1060 body->scope()->AddVariable(parsed_function->finally_return_temp_var()); |
| 1061 } |
| 1062 // The instantiator is not required in a static expression. |
| 1063 ASSERT(!parser.IsInstantiatorRequired()); |
| 1064 |
| 1065 return parsed_function; |
| 1066 } |
| 1067 |
| 1068 |
| 1005 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { | 1069 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { |
| 1006 TRACE_PARSER("ParseStaticFinalGetter"); | 1070 TRACE_PARSER("ParseStaticFinalGetter"); |
| 1007 ParamList params; | 1071 ParamList params; |
| 1008 ASSERT(func.num_fixed_parameters() == 0); // static. | 1072 ASSERT(func.num_fixed_parameters() == 0); // static. |
| 1009 ASSERT(!func.HasOptionalParameters()); | 1073 ASSERT(!func.HasOptionalParameters()); |
| 1010 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | 1074 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); |
| 1011 | 1075 |
| 1012 // Build local scope for function and populate with the formal parameters. | 1076 // Build local scope for function and populate with the formal parameters. |
| 1013 OpenFunctionBlock(func); | 1077 OpenFunctionBlock(func); |
| 1014 AddFormalParamsToScope(¶ms, current_block_->scope); | 1078 AddFormalParamsToScope(¶ms, current_block_->scope); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1031 // leave the evaluation to the getter function. | 1095 // leave the evaluation to the getter function. |
| 1032 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 1096 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 1033 // This getter will only be called once at compile time. | 1097 // This getter will only be called once at compile time. |
| 1034 if (expr->EvalConstExpr() == NULL) { | 1098 if (expr->EvalConstExpr() == NULL) { |
| 1035 ReportError(expr_pos, "initializer is not a valid compile-time constant"); | 1099 ReportError(expr_pos, "initializer is not a valid compile-time constant"); |
| 1036 } | 1100 } |
| 1037 ReturnNode* return_node = new ReturnNode(ident_pos, expr); | 1101 ReturnNode* return_node = new ReturnNode(ident_pos, expr); |
| 1038 current_block_->statements->Add(return_node); | 1102 current_block_->statements->Add(return_node); |
| 1039 } else { | 1103 } else { |
| 1040 // This getter may be called each time the static field is accessed. | 1104 // This getter may be called each time the static field is accessed. |
| 1041 // The following generated code lazily initializes the field: | 1105 // Call runtime support to parse and evaluate the initializer expression. |
| 1042 // if (field.value === transition_sentinel) { | 1106 // The runtime function will detect circular dependencies in expressions |
| 1043 // field.value = null; | 1107 // and handle errors while evaluating the expression. |
| 1044 // throw("circular dependency in field initialization"); | 1108 current_block_->statements->Add( |
| 1045 // } | 1109 new (I) InitStaticFieldNode(ident_pos, field)); |
| 1046 // if (field.value === sentinel) { | |
| 1047 // field.value = transition_sentinel; | |
| 1048 // field.value = expr; | |
| 1049 // } | |
| 1050 // return field.value; // Type check is executed here in checked mode. | |
| 1051 | |
| 1052 // Generate code checking for circular dependency in field initialization. | |
| 1053 AstNode* compare_circular = new ComparisonNode( | |
| 1054 ident_pos, | |
| 1055 Token::kEQ_STRICT, | |
| 1056 new LoadStaticFieldNode(ident_pos, field), | |
| 1057 new LiteralNode(ident_pos, Object::transition_sentinel())); | |
| 1058 // Set field to null prior to throwing exception, so that subsequent | |
| 1059 // accesses to the field do not throw again, since initializers should only | |
| 1060 // be executed once. | |
| 1061 SequenceNode* report_circular = new SequenceNode(ident_pos, NULL); | |
| 1062 report_circular->Add( | |
| 1063 new StoreStaticFieldNode( | |
| 1064 ident_pos, | |
| 1065 field, | |
| 1066 new LiteralNode(ident_pos, Instance::ZoneHandle(I)))); | |
| 1067 // Call CyclicInitializationError._throwNew(field_name). | |
| 1068 ArgumentListNode* error_arguments = new ArgumentListNode(ident_pos); | |
| 1069 error_arguments->Add(new LiteralNode(ident_pos, field_name)); | |
| 1070 report_circular->Add( | |
| 1071 MakeStaticCall(Symbols::CyclicInitializationError(), | |
| 1072 Library::PrivateCoreLibName(Symbols::ThrowNew()), | |
| 1073 error_arguments)); | |
| 1074 AstNode* circular_check = | |
| 1075 new IfNode(ident_pos, compare_circular, report_circular, NULL); | |
| 1076 current_block_->statements->Add(circular_check); | |
| 1077 | |
| 1078 // Generate code checking for uninitialized field. | |
| 1079 AstNode* compare_uninitialized = new ComparisonNode( | |
| 1080 ident_pos, | |
| 1081 Token::kEQ_STRICT, | |
| 1082 new LoadStaticFieldNode(ident_pos, field), | |
| 1083 new LiteralNode(ident_pos, Object::sentinel())); | |
| 1084 SequenceNode* initialize_field = new SequenceNode(ident_pos, NULL); | |
| 1085 initialize_field->Add( | |
| 1086 new StoreStaticFieldNode( | |
| 1087 ident_pos, | |
| 1088 field, | |
| 1089 new LiteralNode(ident_pos, Object::transition_sentinel()))); | |
| 1090 const String& init_name = String::Handle(I, Symbols::New( | |
| 1091 String::Handle(I, String::Concat( | |
| 1092 Symbols::InitPrefix(), String::Handle(I, field.name()))))); | |
| 1093 const Function& init_function = Function::ZoneHandle(I, | |
| 1094 field_class.LookupStaticFunction(init_name)); | |
| 1095 ASSERT(!init_function.IsNull()); | |
| 1096 ArgumentListNode* arguments = new ArgumentListNode(expr_pos); | |
| 1097 StaticCallNode* init_call = | |
| 1098 new StaticCallNode(expr_pos, init_function, arguments); | |
| 1099 initialize_field->Add(init_call); | |
| 1100 | |
| 1101 AstNode* uninitialized_check = | |
| 1102 new IfNode(ident_pos, compare_uninitialized, initialize_field, NULL); | |
| 1103 current_block_->statements->Add(uninitialized_check); | |
| 1104 | |
| 1105 // Generate code returning the field value. | |
| 1106 ReturnNode* return_node = | 1110 ReturnNode* return_node = |
| 1107 new ReturnNode(ident_pos, new LoadStaticFieldNode(ident_pos, field)); | 1111 new ReturnNode(ident_pos, |
| 1112 new LoadStaticFieldNode(ident_pos, field)); |
| 1108 current_block_->statements->Add(return_node); | 1113 current_block_->statements->Add(return_node); |
| 1109 } | 1114 } |
| 1110 return CloseBlock(); | 1115 return CloseBlock(); |
| 1111 } | 1116 } |
| 1112 | 1117 |
| 1113 | 1118 |
| 1114 SequenceNode* Parser::ParseStaticInitializer(const Function& func) { | |
| 1115 TRACE_PARSER("ParseStaticInitializer"); | |
| 1116 ParamList params; | |
| 1117 ASSERT(func.num_fixed_parameters() == 0); // static. | |
| 1118 ASSERT(!func.HasOptionalParameters()); | |
| 1119 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | |
| 1120 | |
| 1121 // Build local scope for function and populate with the formal parameters. | |
| 1122 OpenFunctionBlock(func); | |
| 1123 AddFormalParamsToScope(¶ms, current_block_->scope); | |
| 1124 | |
| 1125 // Move forward to the start of the initializer expression. | |
| 1126 intptr_t ident_pos = TokenPos(); | |
| 1127 ExpectIdentifier("identifier expected"); | |
| 1128 ExpectToken(Token::kASSIGN); | |
| 1129 intptr_t token_pos = TokenPos(); | |
| 1130 | |
| 1131 // Synthesize a try-catch block to wrap the initializer expression. | |
| 1132 LocalVariable* context_var = | |
| 1133 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); | |
| 1134 if (context_var == NULL) { | |
| 1135 context_var = new(I) LocalVariable( | |
| 1136 token_pos, | |
| 1137 Symbols::SavedTryContextVar(), | |
| 1138 Type::ZoneHandle(I, Type::DynamicType())); | |
| 1139 current_block_->scope->AddVariable(context_var); | |
| 1140 } | |
| 1141 LocalVariable* catch_excp_var = | |
| 1142 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar()); | |
| 1143 if (catch_excp_var == NULL) { | |
| 1144 catch_excp_var = new (I) LocalVariable( | |
| 1145 token_pos, | |
| 1146 Symbols::ExceptionVar(), | |
| 1147 Type::ZoneHandle(I, Type::DynamicType())); | |
| 1148 current_block_->scope->AddVariable(catch_excp_var); | |
| 1149 } | |
| 1150 LocalVariable* catch_trace_var = | |
| 1151 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar()); | |
| 1152 if (catch_trace_var == NULL) { | |
| 1153 catch_trace_var = new (I) LocalVariable( | |
| 1154 token_pos, | |
| 1155 Symbols::StackTraceVar(), | |
| 1156 Type::ZoneHandle(I, Type::DynamicType())); | |
| 1157 current_block_->scope->AddVariable(catch_trace_var); | |
| 1158 } | |
| 1159 | |
| 1160 OpenBlock(); // Start try block. | |
| 1161 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | |
| 1162 const Field& field = Field::ZoneHandle(I, func.saved_static_field()); | |
| 1163 ASSERT(!field.is_const()); | |
| 1164 if (FLAG_enable_type_checks) { | |
| 1165 expr = new AssignableNode( | |
| 1166 field.token_pos(), | |
| 1167 expr, | |
| 1168 AbstractType::ZoneHandle(I, field.type()), | |
| 1169 String::ZoneHandle(I, field.name())); | |
| 1170 } | |
| 1171 StoreStaticFieldNode* store = new StoreStaticFieldNode(field.token_pos(), | |
| 1172 field, | |
| 1173 expr); | |
| 1174 current_block_->statements->Add(store); | |
| 1175 SequenceNode* try_block = CloseBlock(); // End try block. | |
| 1176 | |
| 1177 OpenBlock(); // Start catch handler list. | |
| 1178 OpenBlock(); // Start catch clause. | |
| 1179 AstNode* compare_transition_sentinel = new ComparisonNode( | |
| 1180 token_pos, | |
| 1181 Token::kEQ_STRICT, | |
| 1182 new LoadStaticFieldNode(ident_pos, field), | |
| 1183 new LiteralNode(field.token_pos(), Object::transition_sentinel())); | |
| 1184 | |
| 1185 SequenceNode* store_null = new SequenceNode(token_pos, NULL); | |
| 1186 store_null->Add(new StoreStaticFieldNode( | |
| 1187 field.token_pos(), | |
| 1188 field, | |
| 1189 new LiteralNode(token_pos, Instance::ZoneHandle(I)))); | |
| 1190 AstNode* transition_sentinel_check = | |
| 1191 new IfNode(token_pos, compare_transition_sentinel, store_null, NULL); | |
| 1192 current_block_->statements->Add(transition_sentinel_check); | |
| 1193 | |
| 1194 current_block_->statements->Add( | |
| 1195 new ThrowNode(token_pos, | |
| 1196 new LoadLocalNode(token_pos, catch_excp_var), | |
| 1197 new LoadLocalNode(token_pos, catch_trace_var))); | |
| 1198 SequenceNode* catch_clause = CloseBlock(); // End catch clause. | |
| 1199 | |
| 1200 current_block_->statements->Add(catch_clause); | |
| 1201 SequenceNode* catch_handler_list = CloseBlock(); // End catch handler list. | |
| 1202 CatchClauseNode* catch_block = | |
| 1203 new CatchClauseNode(token_pos, | |
| 1204 catch_handler_list, | |
| 1205 Array::ZoneHandle(I, Object::empty_array().raw()), | |
| 1206 context_var, | |
| 1207 catch_excp_var, | |
| 1208 catch_trace_var, | |
| 1209 CatchClauseNode::kInvalidTryIndex, | |
| 1210 false); // No stack trace needed. | |
| 1211 | |
| 1212 AstNode* try_catch_node = new TryCatchNode(token_pos, | |
| 1213 try_block, | |
| 1214 context_var, | |
| 1215 catch_block, | |
| 1216 NULL, // No finally block. | |
| 1217 AllocateTryIndex()); | |
| 1218 current_block_->statements->Add(try_catch_node); | |
| 1219 return CloseBlock(); | |
| 1220 } | |
| 1221 | |
| 1222 | |
| 1223 // Create AstNodes for an implicit instance getter method: | 1119 // Create AstNodes for an implicit instance getter method: |
| 1224 // LoadLocalNode 0 ('this'); | 1120 // LoadLocalNode 0 ('this'); |
| 1225 // LoadInstanceFieldNode (field_name); | 1121 // LoadInstanceFieldNode (field_name); |
| 1226 // ReturnNode (field's value); | 1122 // ReturnNode (field's value); |
| 1227 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { | 1123 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { |
| 1228 TRACE_PARSER("ParseInstanceGetter"); | 1124 TRACE_PARSER("ParseInstanceGetter"); |
| 1229 ParamList params; | 1125 ParamList params; |
| 1230 // func.token_pos() points to the name of the field. | 1126 // func.token_pos() points to the name of the field. |
| 1231 const intptr_t ident_pos = func.token_pos(); | 1127 const intptr_t ident_pos = func.token_pos(); |
| 1232 ASSERT(current_class().raw() == func.Owner()); | 1128 ASSERT(current_class().raw() == func.Owner()); |
| (...skipping 2440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3673 RawFunction::kImplicitStaticFinalGetter, | 3569 RawFunction::kImplicitStaticFinalGetter, |
| 3674 field->has_static, | 3570 field->has_static, |
| 3675 field->has_const, | 3571 field->has_const, |
| 3676 /* is_abstract = */ false, | 3572 /* is_abstract = */ false, |
| 3677 /* is_external = */ false, | 3573 /* is_external = */ false, |
| 3678 /* is_native = */ false, | 3574 /* is_native = */ false, |
| 3679 current_class(), | 3575 current_class(), |
| 3680 field->name_pos); | 3576 field->name_pos); |
| 3681 getter.set_result_type(*field->type); | 3577 getter.set_result_type(*field->type); |
| 3682 members->AddFunction(getter); | 3578 members->AddFunction(getter); |
| 3683 | |
| 3684 // Create initializer function for non-const fields. | |
| 3685 if (!class_field.is_const()) { | |
| 3686 const Function& init_function = Function::ZoneHandle(I, | |
| 3687 Function::NewStaticInitializer(class_field)); | |
| 3688 members->AddFunction(init_function); | |
| 3689 } | |
| 3690 } | 3579 } |
| 3691 } | 3580 } |
| 3692 | 3581 |
| 3693 // For instance fields, we create implicit getter and setter methods. | 3582 // For instance fields, we create implicit getter and setter methods. |
| 3694 if (!field->has_static) { | 3583 if (!field->has_static) { |
| 3695 String& getter_name = String::Handle(I, | 3584 String& getter_name = String::Handle(I, |
| 3696 Field::GetterSymbol(*field->name)); | 3585 Field::GetterSymbol(*field->name)); |
| 3697 getter = Function::New(getter_name, RawFunction::kImplicitGetter, | 3586 getter = Function::New(getter_name, RawFunction::kImplicitGetter, |
| 3698 field->has_static, | 3587 field->has_static, |
| 3699 field->has_final, | 3588 field->has_final, |
| (...skipping 1138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4838 RawFunction::kImplicitStaticFinalGetter, | 4727 RawFunction::kImplicitStaticFinalGetter, |
| 4839 is_static, | 4728 is_static, |
| 4840 is_const, | 4729 is_const, |
| 4841 /* is_abstract = */ false, | 4730 /* is_abstract = */ false, |
| 4842 /* is_external = */ false, | 4731 /* is_external = */ false, |
| 4843 /* is_native = */ false, | 4732 /* is_native = */ false, |
| 4844 current_class(), | 4733 current_class(), |
| 4845 name_pos); | 4734 name_pos); |
| 4846 getter.set_result_type(type); | 4735 getter.set_result_type(type); |
| 4847 top_level->functions.Add(getter); | 4736 top_level->functions.Add(getter); |
| 4848 | |
| 4849 // Create initializer function. | |
| 4850 if (!field.is_const()) { | |
| 4851 const Function& init_function = Function::ZoneHandle(I, | |
| 4852 Function::NewStaticInitializer(field)); | |
| 4853 top_level->functions.Add(init_function); | |
| 4854 } | |
| 4855 } | 4737 } |
| 4856 } else if (is_final) { | 4738 } else if (is_final) { |
| 4857 ReportError(name_pos, "missing initializer for final or const variable"); | 4739 ReportError(name_pos, "missing initializer for final or const variable"); |
| 4858 } | 4740 } |
| 4859 | 4741 |
| 4860 if (CurrentToken() == Token::kCOMMA) { | 4742 if (CurrentToken() == Token::kCOMMA) { |
| 4861 ConsumeToken(); | 4743 ConsumeToken(); |
| 4862 } else if (CurrentToken() == Token::kSEMICOLON) { | 4744 } else if (CurrentToken() == Token::kSEMICOLON) { |
| 4863 ConsumeToken(); | 4745 ConsumeToken(); |
| 4864 break; | 4746 break; |
| (...skipping 6089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10954 ASSERT(field.is_const()); | 10836 ASSERT(field.is_const()); |
| 10955 ASSERT(field.value() != Object::sentinel().raw()); | 10837 ASSERT(field.value() != Object::sentinel().raw()); |
| 10956 ASSERT(field.value() != Object::transition_sentinel().raw()); | 10838 ASSERT(field.value() != Object::transition_sentinel().raw()); |
| 10957 return Instance::ZoneHandle(I, field.value()); | 10839 return Instance::ZoneHandle(I, field.value()); |
| 10958 } else { | 10840 } else { |
| 10959 ASSERT(expr->EvalConstExpr() != NULL); | 10841 ASSERT(expr->EvalConstExpr() != NULL); |
| 10960 ReturnNode* ret = new(I) ReturnNode(expr->token_pos(), expr); | 10842 ReturnNode* ret = new(I) ReturnNode(expr->token_pos(), expr); |
| 10961 // Compile time constant expressions cannot reference anything from a | 10843 // Compile time constant expressions cannot reference anything from a |
| 10962 // local scope. | 10844 // local scope. |
| 10963 LocalScope* empty_scope = new(I) LocalScope(NULL, 0, 0); | 10845 LocalScope* empty_scope = new(I) LocalScope(NULL, 0, 0); |
| 10964 SequenceNode* seq = new(I) SequenceNode(expr->token_pos(), | 10846 SequenceNode* seq = new(I) SequenceNode(expr->token_pos(), empty_scope); |
| 10965 empty_scope); | |
| 10966 seq->Add(ret); | 10847 seq->Add(ret); |
| 10967 | 10848 |
| 10968 Object& result = Object::Handle(I, Compiler::ExecuteOnce(seq)); | 10849 Object& result = Object::Handle(I, Compiler::ExecuteOnce(seq)); |
| 10969 if (result.IsError()) { | 10850 if (result.IsError()) { |
| 10970 ReportErrors(Error::Cast(result), | 10851 ReportErrors(Error::Cast(result), |
| 10971 script_, expr_pos, | 10852 script_, expr_pos, |
| 10972 "error evaluating constant expression"); | 10853 "error evaluating constant expression"); |
| 10973 } | 10854 } |
| 10974 ASSERT(result.IsInstance()); | 10855 ASSERT(result.IsInstance()); |
| 10975 Instance& value = Instance::ZoneHandle(I); | 10856 Instance& value = Instance::ZoneHandle(I); |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11308 void Parser::SkipQualIdent() { | 11189 void Parser::SkipQualIdent() { |
| 11309 ASSERT(IsIdentifier()); | 11190 ASSERT(IsIdentifier()); |
| 11310 ConsumeToken(); | 11191 ConsumeToken(); |
| 11311 if (CurrentToken() == Token::kPERIOD) { | 11192 if (CurrentToken() == Token::kPERIOD) { |
| 11312 ConsumeToken(); // Consume the kPERIOD token. | 11193 ConsumeToken(); // Consume the kPERIOD token. |
| 11313 ExpectIdentifier("identifier expected after '.'"); | 11194 ExpectIdentifier("identifier expected after '.'"); |
| 11314 } | 11195 } |
| 11315 } | 11196 } |
| 11316 | 11197 |
| 11317 } // namespace dart | 11198 } // namespace dart |
| OLD | NEW |