Chromium Code Reviews| 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 1139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1150 | 1150 |
| 1151 | 1151 |
| 1152 // Create AstNodes for an implicit instance getter method: | 1152 // Create AstNodes for an implicit instance getter method: |
| 1153 // LoadLocalNode 0 ('this'); | 1153 // LoadLocalNode 0 ('this'); |
| 1154 // LoadInstanceFieldNode (field_name); | 1154 // LoadInstanceFieldNode (field_name); |
| 1155 // ReturnNode (field's value); | 1155 // ReturnNode (field's value); |
| 1156 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { | 1156 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { |
| 1157 TRACE_PARSER("ParseInstanceGetter"); | 1157 TRACE_PARSER("ParseInstanceGetter"); |
| 1158 ParamList params; | 1158 ParamList params; |
| 1159 // func.token_pos() points to the name of the field. | 1159 // func.token_pos() points to the name of the field. |
| 1160 intptr_t ident_pos = func.token_pos(); | 1160 const intptr_t ident_pos = func.token_pos(); |
| 1161 ASSERT(current_class().raw() == func.Owner()); | 1161 ASSERT(current_class().raw() == func.Owner()); |
| 1162 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1162 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
| 1163 ASSERT(func.num_fixed_parameters() == 1); // receiver. | 1163 ASSERT(func.num_fixed_parameters() == 1); // receiver. |
| 1164 ASSERT(!func.HasOptionalParameters()); | 1164 ASSERT(!func.HasOptionalParameters()); |
| 1165 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 1165 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 1166 | 1166 |
| 1167 // Build local scope for function and populate with the formal parameters. | 1167 // Build local scope for function and populate with the formal parameters. |
| 1168 OpenFunctionBlock(func); | 1168 OpenFunctionBlock(func); |
| 1169 AddFormalParamsToScope(¶ms, current_block_->scope); | 1169 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1170 | 1170 |
| 1171 // Receiver is local 0. | 1171 // Receiver is local 0. |
| 1172 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1172 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| 1173 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); | 1173 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); |
| 1174 ASSERT(IsIdentifier()); | 1174 ASSERT(IsIdentifier()); |
| 1175 const String& field_name = *CurrentLiteral(); | 1175 const String& field_name = *CurrentLiteral(); |
| 1176 const Class& field_class = Class::Handle(func.Owner()); | 1176 const Class& field_class = Class::Handle(func.Owner()); |
| 1177 const Field& field = | 1177 const Field& field = |
| 1178 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); | 1178 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); |
| 1179 | 1179 |
| 1180 LoadInstanceFieldNode* load_field = | 1180 LoadInstanceFieldNode* load_field = |
| 1181 new LoadInstanceFieldNode(ident_pos, load_receiver, field); | 1181 new LoadInstanceFieldNode(ident_pos, load_receiver, field); |
| 1182 | 1182 |
| 1183 ReturnNode* return_node = new ReturnNode(ident_pos, load_field); | 1183 ReturnNode* return_node = |
| 1184 new ReturnNode(Scanner::kDummyTokenIndex, load_field); | |
|
regis
2014/01/21 20:11:40
A comment indicating why it is important to pass a
| |
| 1184 current_block_->statements->Add(return_node); | 1185 current_block_->statements->Add(return_node); |
| 1185 return CloseBlock(); | 1186 return CloseBlock(); |
| 1186 } | 1187 } |
| 1187 | 1188 |
| 1188 | 1189 |
| 1189 // Create AstNodes for an implicit instance setter method: | 1190 // Create AstNodes for an implicit instance setter method: |
| 1190 // LoadLocalNode 0 ('this') | 1191 // LoadLocalNode 0 ('this') |
| 1191 // LoadLocalNode 1 ('value') | 1192 // LoadLocalNode 1 ('value') |
| 1192 // SetInstanceField (field_name); | 1193 // SetInstanceField (field_name); |
| 1193 // ReturnNode (void); | 1194 // ReturnNode (void); |
| 1194 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { | 1195 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { |
| 1195 TRACE_PARSER("ParseInstanceSetter"); | 1196 TRACE_PARSER("ParseInstanceSetter"); |
| 1196 // func.token_pos() points to the name of the field. | 1197 // func.token_pos() points to the name of the field. |
| 1197 intptr_t ident_pos = func.token_pos(); | 1198 const intptr_t ident_pos = func.token_pos(); |
| 1198 const String& field_name = *CurrentLiteral(); | 1199 const String& field_name = *CurrentLiteral(); |
| 1199 const Class& field_class = Class::ZoneHandle(func.Owner()); | 1200 const Class& field_class = Class::ZoneHandle(func.Owner()); |
| 1200 const Field& field = | 1201 const Field& field = |
| 1201 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); | 1202 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); |
| 1202 const AbstractType& field_type = AbstractType::ZoneHandle(field.type()); | 1203 const AbstractType& field_type = AbstractType::ZoneHandle(field.type()); |
| 1203 | 1204 |
| 1204 ParamList params; | 1205 ParamList params; |
| 1205 ASSERT(current_class().raw() == func.Owner()); | 1206 ASSERT(current_class().raw() == func.Owner()); |
| 1206 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1207 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
| 1207 params.AddFinalParameter(ident_pos, | 1208 params.AddFinalParameter(ident_pos, |
| 1208 &Symbols::Value(), | 1209 &Symbols::Value(), |
| 1209 &field_type); | 1210 &field_type); |
| 1210 ASSERT(func.num_fixed_parameters() == 2); // receiver, value. | 1211 ASSERT(func.num_fixed_parameters() == 2); // receiver, value. |
| 1211 ASSERT(!func.HasOptionalParameters()); | 1212 ASSERT(!func.HasOptionalParameters()); |
| 1212 ASSERT(AbstractType::Handle(func.result_type()).IsVoidType()); | 1213 ASSERT(AbstractType::Handle(func.result_type()).IsVoidType()); |
| 1213 | 1214 |
| 1214 // Build local scope for function and populate with the formal parameters. | 1215 // Build local scope for function and populate with the formal parameters. |
| 1215 OpenFunctionBlock(func); | 1216 OpenFunctionBlock(func); |
| 1216 AddFormalParamsToScope(¶ms, current_block_->scope); | 1217 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1217 | 1218 |
| 1218 LoadLocalNode* receiver = | 1219 LoadLocalNode* receiver = |
| 1219 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(0)); | 1220 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(0)); |
| 1220 LoadLocalNode* value = | 1221 LoadLocalNode* value = |
| 1221 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(1)); | 1222 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(1)); |
| 1222 | 1223 |
| 1223 EnsureExpressionTemp(); | 1224 EnsureExpressionTemp(); |
| 1224 StoreInstanceFieldNode* store_field = | 1225 StoreInstanceFieldNode* store_field = |
| 1225 new StoreInstanceFieldNode(ident_pos, receiver, field, value); | 1226 new StoreInstanceFieldNode(ident_pos, receiver, field, value); |
| 1226 current_block_->statements->Add(store_field); | 1227 current_block_->statements->Add(store_field); |
| 1227 current_block_->statements->Add(new ReturnNode(ident_pos)); | 1228 current_block_->statements->Add(new ReturnNode(Scanner::kDummyTokenIndex)); |
|
regis
2014/01/21 20:11:40
ditto
| |
| 1228 return CloseBlock(); | 1229 return CloseBlock(); |
| 1229 } | 1230 } |
| 1230 | 1231 |
| 1231 | 1232 |
| 1232 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { | 1233 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { |
| 1233 TRACE_PARSER("ParseMethodExtractor"); | 1234 TRACE_PARSER("ParseMethodExtractor"); |
| 1234 ParamList params; | 1235 ParamList params; |
| 1235 | 1236 |
| 1236 const intptr_t ident_pos = func.token_pos(); | 1237 const intptr_t ident_pos = func.token_pos(); |
| 1238 const intptr_t invisible_pos = Scanner::kDummyTokenIndex; | |
|
regis
2014/01/21 20:11:40
Would be unnecessary if you declare an alias of Sc
| |
| 1237 ASSERT(func.token_pos() == 0); | 1239 ASSERT(func.token_pos() == 0); |
| 1238 ASSERT(current_class().raw() == func.Owner()); | 1240 ASSERT(current_class().raw() == func.Owner()); |
| 1239 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1241 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
| 1240 ASSERT(func.num_fixed_parameters() == 1); // Receiver. | 1242 ASSERT(func.num_fixed_parameters() == 1); // Receiver. |
| 1241 ASSERT(!func.HasOptionalParameters()); | 1243 ASSERT(!func.HasOptionalParameters()); |
| 1242 | 1244 |
| 1243 // Build local scope for function and populate with the formal parameters. | 1245 // Build local scope for function and populate with the formal parameters. |
| 1244 OpenFunctionBlock(func); | 1246 OpenFunctionBlock(func); |
| 1245 AddFormalParamsToScope(¶ms, current_block_->scope); | 1247 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1246 | 1248 |
| 1247 // Receiver is local 0. | 1249 // Receiver is local 0. |
| 1248 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1250 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| 1249 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); | 1251 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); |
| 1250 | 1252 |
| 1251 ClosureNode* closure = new ClosureNode( | 1253 ClosureNode* closure = new ClosureNode( |
| 1252 ident_pos, | 1254 ident_pos, |
| 1253 Function::ZoneHandle(func.extracted_method_closure()), | 1255 Function::ZoneHandle(func.extracted_method_closure()), |
| 1254 load_receiver, | 1256 load_receiver, |
| 1255 NULL); | 1257 NULL); |
| 1256 | 1258 |
| 1257 ReturnNode* return_node = new ReturnNode(ident_pos, closure); | 1259 ReturnNode* return_node = new ReturnNode(invisible_pos, closure); |
| 1258 current_block_->statements->Add(return_node); | 1260 current_block_->statements->Add(return_node); |
| 1259 return CloseBlock(); | 1261 return CloseBlock(); |
| 1260 } | 1262 } |
| 1261 | 1263 |
| 1262 | 1264 |
| 1263 void Parser::BuildDispatcherScope(const Function& func, | 1265 void Parser::BuildDispatcherScope(const Function& func, |
| 1264 const ArgumentsDescriptor& desc, | 1266 const ArgumentsDescriptor& desc, |
| 1265 Array& default_values) { | 1267 Array& default_values) { |
| 1266 ParamList params; | 1268 ParamList params; |
| 1267 // Receiver first. | 1269 // Receiver first. |
| (...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2032 // No function or field exists of the specified field_name. | 2034 // No function or field exists of the specified field_name. |
| 2033 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called. | 2035 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called. |
| 2034 } | 2036 } |
| 2035 } | 2037 } |
| 2036 return new StaticGetterNode( | 2038 return new StaticGetterNode( |
| 2037 field_pos, implicit_argument, true, super_class, field_name); | 2039 field_pos, implicit_argument, true, super_class, field_name); |
| 2038 } | 2040 } |
| 2039 | 2041 |
| 2040 | 2042 |
| 2041 void Parser::GenerateSuperConstructorCall(const Class& cls, | 2043 void Parser::GenerateSuperConstructorCall(const Class& cls, |
| 2044 intptr_t supercall_pos, | |
| 2042 LocalVariable* receiver, | 2045 LocalVariable* receiver, |
| 2043 ArgumentListNode* forwarding_args) { | 2046 ArgumentListNode* forwarding_args) { |
| 2044 const intptr_t supercall_pos = TokenPos(); | |
| 2045 const Class& super_class = Class::Handle(cls.SuperClass()); | 2047 const Class& super_class = Class::Handle(cls.SuperClass()); |
| 2046 // Omit the implicit super() if there is no super class (i.e. | 2048 // Omit the implicit super() if there is no super class (i.e. |
| 2047 // we're not compiling class Object), or if the super class is an | 2049 // we're not compiling class Object), or if the super class is an |
| 2048 // artificially generated "wrapper class" that has no constructor. | 2050 // artificially generated "wrapper class" that has no constructor. |
| 2049 if (super_class.IsNull() || | 2051 if (super_class.IsNull() || |
| 2050 (super_class.num_native_fields() > 0 && | 2052 (super_class.num_native_fields() > 0 && |
| 2051 Class::Handle(super_class.SuperClass()).IsObjectClass())) { | 2053 Class::Handle(super_class.SuperClass()).IsObjectClass())) { |
| 2052 return; | 2054 return; |
| 2053 } | 2055 } |
| 2054 String& super_ctor_name = String::Handle(super_class.Name()); | 2056 String& super_ctor_name = String::Handle(super_class.Name()); |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2353 super_init_seen = true; | 2355 super_init_seen = true; |
| 2354 } else { | 2356 } else { |
| 2355 init_statement = ParseInitializer(cls, receiver, initialized_fields); | 2357 init_statement = ParseInitializer(cls, receiver, initialized_fields); |
| 2356 } | 2358 } |
| 2357 current_block_->statements->Add(init_statement); | 2359 current_block_->statements->Add(init_statement); |
| 2358 } while (CurrentToken() == Token::kCOMMA); | 2360 } while (CurrentToken() == Token::kCOMMA); |
| 2359 } | 2361 } |
| 2360 if (!super_init_seen) { | 2362 if (!super_init_seen) { |
| 2361 // Generate implicit super() if we haven't seen an explicit super call | 2363 // Generate implicit super() if we haven't seen an explicit super call |
| 2362 // or constructor redirection. | 2364 // or constructor redirection. |
| 2363 GenerateSuperConstructorCall(cls, receiver, NULL); | 2365 GenerateSuperConstructorCall(cls, TokenPos(), receiver, NULL); |
| 2364 } | 2366 } |
| 2365 CheckFieldsInitialized(cls); | 2367 CheckFieldsInitialized(cls); |
| 2366 } | 2368 } |
| 2367 | 2369 |
| 2368 | 2370 |
| 2369 void Parser::ParseConstructorRedirection(const Class& cls, | 2371 void Parser::ParseConstructorRedirection(const Class& cls, |
| 2370 LocalVariable* receiver) { | 2372 LocalVariable* receiver) { |
| 2371 TRACE_PARSER("ParseConstructorRedirection"); | 2373 TRACE_PARSER("ParseConstructorRedirection"); |
| 2372 ExpectToken(Token::kCOLON); | 2374 ExpectToken(Token::kCOLON); |
| 2373 ASSERT(CurrentToken() == Token::kTHIS); | 2375 ASSERT(CurrentToken() == Token::kTHIS); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2412 } | 2414 } |
| 2413 current_block_->statements->Add( | 2415 current_block_->statements->Add( |
| 2414 new StaticCallNode(call_pos, redirect_ctor, arguments)); | 2416 new StaticCallNode(call_pos, redirect_ctor, arguments)); |
| 2415 } | 2417 } |
| 2416 | 2418 |
| 2417 | 2419 |
| 2418 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { | 2420 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { |
| 2419 ASSERT(func.IsConstructor()); | 2421 ASSERT(func.IsConstructor()); |
| 2420 ASSERT(func.Owner() == current_class().raw()); | 2422 ASSERT(func.Owner() == current_class().raw()); |
| 2421 const intptr_t ctor_pos = TokenPos(); | 2423 const intptr_t ctor_pos = TokenPos(); |
| 2424 const intptr_t dummy_pos = Scanner::kDummyTokenIndex; | |
|
regis
2014/01/21 20:11:40
ditto
| |
| 2422 OpenFunctionBlock(func); | 2425 OpenFunctionBlock(func); |
| 2423 | 2426 |
| 2424 LocalVariable* receiver = new LocalVariable( | 2427 LocalVariable* receiver = new LocalVariable( |
| 2425 ctor_pos, Symbols::This(), *ReceiverType(current_class())); | 2428 dummy_pos, Symbols::This(), *ReceiverType(current_class())); |
| 2426 current_block_->scope->AddVariable(receiver); | 2429 current_block_->scope->AddVariable(receiver); |
| 2427 | 2430 |
| 2428 LocalVariable* phase_parameter = new LocalVariable( | 2431 LocalVariable* phase_parameter = new LocalVariable( |
| 2429 ctor_pos, Symbols::PhaseParameter(), Type::ZoneHandle(Type::SmiType())); | 2432 dummy_pos, Symbols::PhaseParameter(), Type::ZoneHandle(Type::SmiType())); |
| 2430 current_block_->scope->AddVariable(phase_parameter); | 2433 current_block_->scope->AddVariable(phase_parameter); |
| 2431 | 2434 |
| 2432 // Parse expressions of instance fields that have an explicit | 2435 // Parse expressions of instance fields that have an explicit |
| 2433 // initializer expression. | 2436 // initializer expression. |
| 2434 // The receiver must not be visible to field initializer expressions. | 2437 // The receiver must not be visible to field initializer expressions. |
| 2435 receiver->set_invisible(true); | 2438 receiver->set_invisible(true); |
| 2436 GrowableArray<Field*> initialized_fields; | 2439 GrowableArray<Field*> initialized_fields; |
| 2437 ParseInitializedInstanceFields( | 2440 ParseInitializedInstanceFields( |
| 2438 current_class(), receiver, &initialized_fields); | 2441 current_class(), receiver, &initialized_fields); |
| 2439 receiver->set_invisible(false); | 2442 receiver->set_invisible(false); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2455 // whether optional parameters are even allowed in this situation. | 2458 // whether optional parameters are even allowed in this situation. |
| 2456 // TODO(hausner): Remove this limitation if the language spec indeed | 2459 // TODO(hausner): Remove this limitation if the language spec indeed |
| 2457 // allows optional parameters. | 2460 // allows optional parameters. |
| 2458 if (func.HasOptionalParameters()) { | 2461 if (func.HasOptionalParameters()) { |
| 2459 ErrorMsg(ctor_pos, | 2462 ErrorMsg(ctor_pos, |
| 2460 "forwarding constructors must not have optional parameters"); | 2463 "forwarding constructors must not have optional parameters"); |
| 2461 } | 2464 } |
| 2462 | 2465 |
| 2463 // Prepare user-defined arguments to be forwarded to super call. | 2466 // Prepare user-defined arguments to be forwarded to super call. |
| 2464 // The first user-defined argument is at position 2. | 2467 // The first user-defined argument is at position 2. |
| 2465 forwarding_args = new ArgumentListNode(ctor_pos); | 2468 forwarding_args = new ArgumentListNode(dummy_pos); |
| 2466 for (int i = 2; i < func.NumParameters(); i++) { | 2469 for (int i = 2; i < func.NumParameters(); i++) { |
| 2467 LocalVariable* param = new LocalVariable( | 2470 LocalVariable* param = new LocalVariable( |
| 2468 ctor_pos, | 2471 dummy_pos, |
| 2469 String::ZoneHandle(func.ParameterNameAt(i)), | 2472 String::ZoneHandle(func.ParameterNameAt(i)), |
| 2470 Type::ZoneHandle(Type::DynamicType())); | 2473 Type::ZoneHandle(Type::DynamicType())); |
| 2471 current_block_->scope->AddVariable(param); | 2474 current_block_->scope->AddVariable(param); |
| 2472 forwarding_args->Add(new LoadLocalNode(ctor_pos, param)); | 2475 forwarding_args->Add(new LoadLocalNode(dummy_pos, param)); |
| 2473 } | 2476 } |
| 2474 } | 2477 } |
| 2475 | 2478 |
| 2476 GenerateSuperConstructorCall(current_class(), receiver, forwarding_args); | 2479 GenerateSuperConstructorCall(current_class(), |
| 2480 dummy_pos, | |
| 2481 receiver, | |
| 2482 forwarding_args); | |
| 2477 CheckFieldsInitialized(current_class()); | 2483 CheckFieldsInitialized(current_class()); |
| 2478 | 2484 |
| 2479 // Empty constructor body. | 2485 // Empty constructor body. |
| 2486 current_block_->statements->Add(new ReturnNode(dummy_pos)); | |
| 2480 SequenceNode* statements = CloseBlock(); | 2487 SequenceNode* statements = CloseBlock(); |
| 2481 return statements; | 2488 return statements; |
| 2482 } | 2489 } |
| 2483 | 2490 |
| 2484 | 2491 |
| 2485 void Parser::CheckRecursiveInvocation() { | 2492 void Parser::CheckRecursiveInvocation() { |
| 2486 const GrowableObjectArray& pending_functions = | 2493 const GrowableObjectArray& pending_functions = |
| 2487 GrowableObjectArray::Handle( | 2494 GrowableObjectArray::Handle( |
| 2488 isolate()->object_store()->pending_functions()); | 2495 isolate()->object_store()->pending_functions()); |
| 2489 for (int i = 0; i < pending_functions.Length(); i++) { | 2496 for (int i = 0; i < pending_functions.Length(); i++) { |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2629 } | 2636 } |
| 2630 | 2637 |
| 2631 SequenceNode* init_statements = CloseBlock(); | 2638 SequenceNode* init_statements = CloseBlock(); |
| 2632 if (is_redirecting_constructor) { | 2639 if (is_redirecting_constructor) { |
| 2633 // A redirecting super constructor simply passes the phase parameter on to | 2640 // A redirecting super constructor simply passes the phase parameter on to |
| 2634 // the target which executes the corresponding phase. | 2641 // the target which executes the corresponding phase. |
| 2635 current_block_->statements->Add(init_statements); | 2642 current_block_->statements->Add(init_statements); |
| 2636 } else if (init_statements->length() > 0) { | 2643 } else if (init_statements->length() > 0) { |
| 2637 // Generate guard around the initializer code. | 2644 // Generate guard around the initializer code. |
| 2638 LocalVariable* phase_param = LookupPhaseParameter(); | 2645 LocalVariable* phase_param = LookupPhaseParameter(); |
| 2639 AstNode* phase_value = new LoadLocalNode(TokenPos(), phase_param); | 2646 AstNode* phase_value = new |
| 2647 LoadLocalNode(Scanner::kDummyTokenIndex, phase_param); | |
| 2640 AstNode* phase_check = new BinaryOpNode( | 2648 AstNode* phase_check = new BinaryOpNode( |
| 2641 TokenPos(), Token::kBIT_AND, phase_value, | 2649 Scanner::kDummyTokenIndex, Token::kBIT_AND, phase_value, |
| 2642 new LiteralNode(TokenPos(), | 2650 new LiteralNode(Scanner::kDummyTokenIndex, |
| 2643 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); | 2651 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); |
| 2644 AstNode* comparison = | 2652 AstNode* comparison = |
| 2645 new ComparisonNode(TokenPos(), Token::kNE_STRICT, | 2653 new ComparisonNode(Scanner::kDummyTokenIndex, |
| 2654 Token::kNE_STRICT, | |
| 2646 phase_check, | 2655 phase_check, |
| 2647 new LiteralNode(TokenPos(), | 2656 new LiteralNode(TokenPos(), |
| 2648 Smi::ZoneHandle(Smi::New(0)))); | 2657 Smi::ZoneHandle(Smi::New(0)))); |
| 2649 AstNode* guarded_init_statements = | 2658 AstNode* guarded_init_statements = |
| 2650 new IfNode(TokenPos(), comparison, init_statements, NULL); | 2659 new IfNode(Scanner::kDummyTokenIndex, |
| 2660 comparison, | |
| 2661 init_statements, | |
| 2662 NULL); | |
| 2651 current_block_->statements->Add(guarded_init_statements); | 2663 current_block_->statements->Add(guarded_init_statements); |
| 2652 } | 2664 } |
| 2653 | 2665 |
| 2654 // Parsing of initializers done. Now we parse the constructor body | 2666 // Parsing of initializers done. Now we parse the constructor body |
| 2655 // and add the implicit super call to the super constructor's body | 2667 // and add the implicit super call to the super constructor's body |
| 2656 // if necessary. | 2668 // if necessary. |
| 2657 StaticCallNode* super_call = NULL; | 2669 StaticCallNode* super_call = NULL; |
| 2658 // Look for the super initializer call in the sequence of initializer | 2670 // Look for the super initializer call in the sequence of initializer |
| 2659 // statements. If it exists and is not the last initializer statement, | 2671 // statements. If it exists and is not the last initializer statement, |
| 2660 // we need to create an implicit super call to the super constructor's | 2672 // we need to create an implicit super call to the super constructor's |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2755 // Some constructors have no function body. | 2767 // Some constructors have no function body. |
| 2756 ConsumeToken(); | 2768 ConsumeToken(); |
| 2757 } else { | 2769 } else { |
| 2758 UnexpectedToken(); | 2770 UnexpectedToken(); |
| 2759 } | 2771 } |
| 2760 | 2772 |
| 2761 SequenceNode* ctor_block = CloseBlock(); | 2773 SequenceNode* ctor_block = CloseBlock(); |
| 2762 if (ctor_block->length() > 0) { | 2774 if (ctor_block->length() > 0) { |
| 2763 // Generate guard around the constructor body code. | 2775 // Generate guard around the constructor body code. |
| 2764 LocalVariable* phase_param = LookupPhaseParameter(); | 2776 LocalVariable* phase_param = LookupPhaseParameter(); |
| 2765 AstNode* phase_value = new LoadLocalNode(body_pos, phase_param); | 2777 AstNode* phase_value = |
| 2778 new LoadLocalNode(Scanner::kDummyTokenIndex, phase_param); | |
| 2766 AstNode* phase_check = | 2779 AstNode* phase_check = |
| 2767 new BinaryOpNode(body_pos, Token::kBIT_AND, | 2780 new BinaryOpNode(Scanner::kDummyTokenIndex, Token::kBIT_AND, |
| 2768 phase_value, | 2781 phase_value, |
| 2769 new LiteralNode(body_pos, | 2782 new LiteralNode(Scanner::kDummyTokenIndex, |
| 2770 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody)))); | 2783 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody)))); |
| 2771 AstNode* comparison = | 2784 AstNode* comparison = |
| 2772 new ComparisonNode(body_pos, Token::kNE_STRICT, | 2785 new ComparisonNode(Scanner::kDummyTokenIndex, |
| 2773 phase_check, | 2786 Token::kNE_STRICT, |
| 2774 new LiteralNode(body_pos, | 2787 phase_check, |
| 2775 Smi::ZoneHandle(Smi::New(0)))); | 2788 new LiteralNode(body_pos, |
| 2789 Smi::ZoneHandle(Smi::New(0)))); | |
| 2776 AstNode* guarded_block_statements = | 2790 AstNode* guarded_block_statements = |
| 2777 new IfNode(body_pos, comparison, ctor_block, NULL); | 2791 new IfNode(Scanner::kDummyTokenIndex, comparison, ctor_block, NULL); |
| 2778 current_block_->statements->Add(guarded_block_statements); | 2792 current_block_->statements->Add(guarded_block_statements); |
| 2779 } | 2793 } |
| 2780 | 2794 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); |
| 2781 SequenceNode* statements = CloseBlock(); | 2795 SequenceNode* statements = CloseBlock(); |
| 2782 return statements; | 2796 return statements; |
| 2783 } | 2797 } |
| 2784 | 2798 |
| 2785 | 2799 |
| 2786 // Parser is at the opening parenthesis of the formal parameter | 2800 // Parser is at the opening parenthesis of the formal parameter |
| 2787 // declaration of the function or constructor. | 2801 // declaration of the function or constructor. |
| 2788 // Parse the formal parameters and code. | 2802 // Parse the formal parameters and code. |
| 2789 SequenceNode* Parser::ParseFunc(const Function& func, | 2803 SequenceNode* Parser::ParseFunc(const Function& func, |
| 2790 Array& default_parameter_values) { | 2804 Array& default_parameter_values) { |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2938 func.set_end_token_pos(end_token_pos); | 2952 func.set_end_token_pos(end_token_pos); |
| 2939 SequenceNode* body = CloseBlock(); | 2953 SequenceNode* body = CloseBlock(); |
| 2940 current_block_->statements->Add(body); | 2954 current_block_->statements->Add(body); |
| 2941 innermost_function_ = saved_innermost_function.raw(); | 2955 innermost_function_ = saved_innermost_function.raw(); |
| 2942 last_used_try_index_ = saved_try_index; | 2956 last_used_try_index_ = saved_try_index; |
| 2943 return CloseBlock(); | 2957 return CloseBlock(); |
| 2944 } | 2958 } |
| 2945 | 2959 |
| 2946 | 2960 |
| 2947 void Parser::AddEqualityNullCheck() { | 2961 void Parser::AddEqualityNullCheck() { |
| 2948 const intptr_t token_pos = TokenPos(); | 2962 const intptr_t dummy_pos = Scanner::kDummyTokenIndex; |
| 2949 AstNode* argument = | 2963 AstNode* argument = |
| 2950 new LoadLocalNode(token_pos, | 2964 new LoadLocalNode(dummy_pos, |
| 2951 current_block_->scope->parent()->VariableAt(1)); | 2965 current_block_->scope->parent()->VariableAt(1)); |
| 2952 LiteralNode* null_operand = | 2966 LiteralNode* null_operand = |
| 2953 new LiteralNode(token_pos, Instance::ZoneHandle()); | 2967 new LiteralNode(dummy_pos, Instance::ZoneHandle()); |
| 2954 ComparisonNode* check_arg = new ComparisonNode(token_pos, | 2968 ComparisonNode* check_arg = new ComparisonNode(dummy_pos, |
| 2955 Token::kEQ_STRICT, | 2969 Token::kEQ_STRICT, |
| 2956 argument, | 2970 argument, |
| 2957 null_operand); | 2971 null_operand); |
| 2958 ComparisonNode* result = new ComparisonNode(token_pos, | 2972 ComparisonNode* result = new ComparisonNode(dummy_pos, |
| 2959 Token::kEQ_STRICT, | 2973 Token::kEQ_STRICT, |
| 2960 LoadReceiver(token_pos), | 2974 LoadReceiver(dummy_pos), |
| 2961 null_operand); | 2975 null_operand); |
| 2962 SequenceNode* arg_is_null = new SequenceNode(token_pos, NULL); | 2976 SequenceNode* arg_is_null = new SequenceNode(dummy_pos, NULL); |
| 2963 arg_is_null->Add(new ReturnNode(token_pos, result)); | 2977 arg_is_null->Add(new ReturnNode(dummy_pos, result)); |
| 2964 IfNode* if_arg_null = new IfNode(token_pos, | 2978 IfNode* if_arg_null = new IfNode(dummy_pos, |
| 2965 check_arg, | 2979 check_arg, |
| 2966 arg_is_null, | 2980 arg_is_null, |
| 2967 NULL); | 2981 NULL); |
| 2968 current_block_->statements->Add(if_arg_null); | 2982 current_block_->statements->Add(if_arg_null); |
| 2969 } | 2983 } |
| 2970 | 2984 |
| 2971 | 2985 |
| 2972 void Parser::SkipIf(Token::Kind token) { | 2986 void Parser::SkipIf(Token::Kind token) { |
| 2973 if (CurrentToken() == token) { | 2987 if (CurrentToken() == token) { |
| 2974 ConsumeToken(); | 2988 ConsumeToken(); |
| (...skipping 7801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10776 void Parser::SkipQualIdent() { | 10790 void Parser::SkipQualIdent() { |
| 10777 ASSERT(IsIdentifier()); | 10791 ASSERT(IsIdentifier()); |
| 10778 ConsumeToken(); | 10792 ConsumeToken(); |
| 10779 if (CurrentToken() == Token::kPERIOD) { | 10793 if (CurrentToken() == Token::kPERIOD) { |
| 10780 ConsumeToken(); // Consume the kPERIOD token. | 10794 ConsumeToken(); // Consume the kPERIOD token. |
| 10781 ExpectIdentifier("identifier expected after '.'"); | 10795 ExpectIdentifier("identifier expected after '.'"); |
| 10782 } | 10796 } |
| 10783 } | 10797 } |
| 10784 | 10798 |
| 10785 } // namespace dart | 10799 } // namespace dart |
| OLD | NEW |