| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 static const char* kGrowableObjectArrayFromArrayName = | 34 static const char* kGrowableObjectArrayFromArrayName = |
| 35 "GrowableObjectArray._usingArray"; | 35 "GrowableObjectArray._usingArray"; |
| 36 static const char* kGrowableObjectArrayName = "GrowableObjectArray"; | 36 static const char* kGrowableObjectArrayName = "GrowableObjectArray"; |
| 37 static const char* kMutableMapName = "MutableMap"; | 37 static const char* kMutableMapName = "MutableMap"; |
| 38 static const char* kMutableMapFromLiteralName = "fromLiteral"; | 38 static const char* kMutableMapFromLiteralName = "fromLiteral"; |
| 39 static const char* kImmutableMapName = "ImmutableMap"; | 39 static const char* kImmutableMapName = "ImmutableMap"; |
| 40 static const char* kImmutableMapConstructorName = "ImmutableMap."; | 40 static const char* kImmutableMapConstructorName = "ImmutableMap."; |
| 41 static const char* kStringClassName = "StringBase"; | 41 static const char* kStringClassName = "StringBase"; |
| 42 static const char* kInterpolateName = "_interpolate"; | 42 static const char* kInterpolateName = "_interpolate"; |
| 43 static const char* kThisName = "this"; | 43 static const char* kThisName = "this"; |
| 44 static const char* kPhaseParameterName = ":phase"; |
| 44 static const char* kGetIteratorName = "iterator"; | 45 static const char* kGetIteratorName = "iterator"; |
| 45 | 46 |
| 46 #if defined(DEBUG) | 47 #if defined(DEBUG) |
| 47 | 48 |
| 48 class TraceParser : public ValueObject { | 49 class TraceParser : public ValueObject { |
| 49 public: | 50 public: |
| 50 TraceParser(intptr_t token_index, const Script& script, const char* msg) { | 51 TraceParser(intptr_t token_index, const Script& script, const char* msg) { |
| 51 if (FLAG_trace_parser) { | 52 if (FLAG_trace_parser) { |
| 52 intptr_t line, column; | 53 intptr_t line, column; |
| 53 script.GetTokenLocation(token_index, &line, &column); | 54 script.GetTokenLocation(token_index, &line, &column); |
| (...skipping 976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1030 | 1031 |
| 1031 | 1032 |
| 1032 AstNode* Parser::ParseSuperCall(const String& function_name) { | 1033 AstNode* Parser::ParseSuperCall(const String& function_name) { |
| 1033 TRACE_PARSER("ParseSuperCall"); | 1034 TRACE_PARSER("ParseSuperCall"); |
| 1034 ASSERT(CurrentToken() == Token::kLPAREN); | 1035 ASSERT(CurrentToken() == Token::kLPAREN); |
| 1035 const intptr_t supercall_pos = token_index_; | 1036 const intptr_t supercall_pos = token_index_; |
| 1036 | 1037 |
| 1037 const Function& super_function = Function::ZoneHandle( | 1038 const Function& super_function = Function::ZoneHandle( |
| 1038 GetSuperFunction(supercall_pos, function_name)); | 1039 GetSuperFunction(supercall_pos, function_name)); |
| 1039 | 1040 |
| 1041 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 1040 // 'this' parameter is the first argument to super call. | 1042 // 'this' parameter is the first argument to super call. |
| 1041 AstNode* receiver = LoadReceiver(supercall_pos); | 1043 AstNode* receiver = LoadReceiver(supercall_pos); |
| 1042 ArgumentListNode* arguments = | 1044 arguments->Add(receiver); |
| 1043 ParseActualParameters(receiver, kAllowConst); | 1045 ParseActualParameters(arguments, kAllowConst); |
| 1044 return new StaticCallNode(supercall_pos, super_function, arguments); | 1046 return new StaticCallNode(supercall_pos, super_function, arguments); |
| 1045 } | 1047 } |
| 1046 | 1048 |
| 1047 | 1049 |
| 1048 AstNode* Parser::ParseSuperOperator() { | 1050 AstNode* Parser::ParseSuperOperator() { |
| 1049 TRACE_PARSER("ParseSuperOperator"); | 1051 TRACE_PARSER("ParseSuperOperator"); |
| 1050 AstNode* super_op = NULL; | 1052 AstNode* super_op = NULL; |
| 1051 const intptr_t operator_pos = token_index_; | 1053 const intptr_t operator_pos = token_index_; |
| 1052 | 1054 |
| 1053 if (CurrentToken() == Token::kLBRACK) { | 1055 if (CurrentToken() == Token::kLBRACK) { |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1205 | 1207 |
| 1206 ArgumentListNode* setter_arguments = new ArgumentListNode(field_pos); | 1208 ArgumentListNode* setter_arguments = new ArgumentListNode(field_pos); |
| 1207 setter_arguments->Add(implicit_argument); | 1209 setter_arguments->Add(implicit_argument); |
| 1208 setter_arguments->Add(value); | 1210 setter_arguments->Add(value); |
| 1209 super_field = new StaticCallNode(field_pos, super_setter, setter_arguments); | 1211 super_field = new StaticCallNode(field_pos, super_setter, setter_arguments); |
| 1210 } | 1212 } |
| 1211 return super_field; | 1213 return super_field; |
| 1212 } | 1214 } |
| 1213 | 1215 |
| 1214 | 1216 |
| 1215 void Parser::GenerateSuperInitializerCall(const Class& cls, | 1217 void Parser::GenerateSuperConstructorCall(const Class& cls, |
| 1216 LocalVariable* receiver) { | 1218 LocalVariable* receiver) { |
| 1217 const intptr_t supercall_pos = token_index_; | 1219 const intptr_t supercall_pos = token_index_; |
| 1218 const Class& super_class = Class::Handle(cls.SuperClass()); | 1220 const Class& super_class = Class::Handle(cls.SuperClass()); |
| 1219 // Omit the implicit super() if there is no super class (i.e. | 1221 // Omit the implicit super() if there is no super class (i.e. |
| 1220 // we're not compiling class Object), or if the super class is an | 1222 // we're not compiling class Object), or if the super class is an |
| 1221 // artificially generated "wrapper class" that has no constructor. | 1223 // artificially generated "wrapper class" that has no constructor. |
| 1222 if (super_class.IsNull() || (super_class.num_native_fields() > 0)) { | 1224 if (super_class.IsNull() || (super_class.num_native_fields() > 0)) { |
| 1223 return; | 1225 return; |
| 1224 } | 1226 } |
| 1225 String& ctor_name = String::Handle(super_class.Name()); | 1227 String& ctor_name = String::Handle(super_class.Name()); |
| 1226 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | 1228 String& ctor_suffix = String::Handle(String::NewSymbol(".")); |
| 1227 ctor_name = String::Concat(ctor_name, ctor_suffix); | 1229 ctor_name = String::Concat(ctor_name, ctor_suffix); |
| 1228 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 1230 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 1229 // implicit 'this' parameter is the only argument. | 1231 // Implicit 'this' parameter is the first argument. |
| 1230 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, *receiver); | 1232 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, *receiver); |
| 1231 arguments->Add(implicit_argument); | 1233 arguments->Add(implicit_argument); |
| 1234 // Implicit constructor phase parameter is second argument. |
| 1235 AstNode* phase_parameter = |
| 1236 new LiteralNode(supercall_pos, |
| 1237 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); |
| 1238 arguments->Add(phase_parameter); |
| 1232 const Function& super_ctor = Function::ZoneHandle( | 1239 const Function& super_ctor = Function::ZoneHandle( |
| 1233 super_class.LookupConstructor(ctor_name)); | 1240 super_class.LookupConstructor(ctor_name)); |
| 1234 if (super_ctor.IsNull() || | 1241 if (super_ctor.IsNull() || |
| 1235 !super_ctor.AreValidArguments(arguments->length(), | 1242 !super_ctor.AreValidArguments(arguments->length(), |
| 1236 arguments->names())) { | 1243 arguments->names())) { |
| 1237 ErrorMsg(supercall_pos, | 1244 ErrorMsg(supercall_pos, |
| 1238 "unresolved implicit call to super constructor '%s()'", | 1245 "unresolved implicit call to super constructor '%s()'", |
| 1239 String::Handle(super_class.Name()).ToCString()); | 1246 String::Handle(super_class.Name()).ToCString()); |
| 1240 } | 1247 } |
| 1241 CheckFunctionIsCallable(supercall_pos, super_ctor); | 1248 CheckFunctionIsCallable(supercall_pos, super_ctor); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1256 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | 1263 String& ctor_suffix = String::Handle(String::NewSymbol(".")); |
| 1257 if (CurrentToken() == Token::kPERIOD) { | 1264 if (CurrentToken() == Token::kPERIOD) { |
| 1258 ConsumeToken(); | 1265 ConsumeToken(); |
| 1259 ctor_suffix = String::Concat( | 1266 ctor_suffix = String::Concat( |
| 1260 ctor_suffix, *ExpectIdentifier("constructor name expected")); | 1267 ctor_suffix, *ExpectIdentifier("constructor name expected")); |
| 1261 } | 1268 } |
| 1262 ctor_name = String::Concat(ctor_name, ctor_suffix); | 1269 ctor_name = String::Concat(ctor_name, ctor_suffix); |
| 1263 if (CurrentToken() != Token::kLPAREN) { | 1270 if (CurrentToken() != Token::kLPAREN) { |
| 1264 ErrorMsg("parameter list expected"); | 1271 ErrorMsg("parameter list expected"); |
| 1265 } | 1272 } |
| 1273 |
| 1274 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 1266 // 'this' parameter is the first argument to super class constructor. | 1275 // 'this' parameter is the first argument to super class constructor. |
| 1267 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, *receiver); | 1276 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, *receiver); |
| 1277 arguments->Add(implicit_argument); |
| 1278 // Second implicit parameter is the constructor phase. We optimistically |
| 1279 // assume that we can execute both the super initializer and the super |
| 1280 // constructor body. We may later change this to only execute the |
| 1281 // super initializer. |
| 1282 AstNode* phase_parameter = |
| 1283 new LiteralNode(supercall_pos, |
| 1284 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); |
| 1285 arguments->Add(phase_parameter); |
| 1268 // 'this' parameter must not be accessible to the other super call arguments. | 1286 // 'this' parameter must not be accessible to the other super call arguments. |
| 1269 receiver->set_invisible(true); | 1287 receiver->set_invisible(true); |
| 1270 ArgumentListNode* arguments = | 1288 ParseActualParameters(arguments, kAllowConst); |
| 1271 ParseActualParameters(implicit_argument, kAllowConst); | |
| 1272 receiver->set_invisible(false); | 1289 receiver->set_invisible(false); |
| 1290 |
| 1273 // Resolve the constructor. | 1291 // Resolve the constructor. |
| 1274 const Function& super_ctor = Function::ZoneHandle( | 1292 const Function& super_ctor = Function::ZoneHandle( |
| 1275 super_class.LookupConstructor(ctor_name)); | 1293 super_class.LookupConstructor(ctor_name)); |
| 1276 if (super_ctor.IsNull() || | 1294 if (super_ctor.IsNull() || |
| 1277 !super_ctor.AreValidArguments(arguments->length(), | 1295 !super_ctor.AreValidArguments(arguments->length(), |
| 1278 arguments->names())) { | 1296 arguments->names())) { |
| 1279 ErrorMsg(supercall_pos, | 1297 ErrorMsg(supercall_pos, |
| 1280 "super class constructor '%s' not found", | 1298 "super class constructor '%s' not found", |
| 1281 ctor_name.ToCString()); | 1299 ctor_name.ToCString()); |
| 1282 } | 1300 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1366 FieldInitExpression initializer; | 1384 FieldInitExpression initializer; |
| 1367 initializer.inst_field = &field; | 1385 initializer.inst_field = &field; |
| 1368 initializer.expr = init_expr; | 1386 initializer.expr = init_expr; |
| 1369 initializers->Add(initializer); | 1387 initializers->Add(initializer); |
| 1370 } | 1388 } |
| 1371 } | 1389 } |
| 1372 SetPosition(saved_pos); | 1390 SetPosition(saved_pos); |
| 1373 } | 1391 } |
| 1374 | 1392 |
| 1375 | 1393 |
| 1376 void Parser::ParseInitializers(const Class& cls) { | 1394 void Parser::ParseInitializers(const Class& cls, LocalVariable* receiver) { |
| 1377 TRACE_PARSER("ParseInitializers"); | 1395 TRACE_PARSER("ParseInitializers"); |
| 1378 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1396 bool super_init_seen = false; |
| 1379 AstNode* super_init_statement = NULL; | |
| 1380 if (CurrentToken() == Token::kCOLON) { | 1397 if (CurrentToken() == Token::kCOLON) { |
| 1381 if ((LookaheadToken(1) == Token::kTHIS) && | 1398 if ((LookaheadToken(1) == Token::kTHIS) && |
| 1382 ((LookaheadToken(2) == Token::kLPAREN) || | 1399 ((LookaheadToken(2) == Token::kLPAREN) || |
| 1383 ((LookaheadToken(2) == Token::kPERIOD) && | 1400 ((LookaheadToken(2) == Token::kPERIOD) && |
| 1384 (LookaheadToken(4) == Token::kLPAREN)))) { | 1401 (LookaheadToken(4) == Token::kLPAREN)))) { |
| 1385 // Either we see this(...) or this.xxx(...) which is a | 1402 // Either we see this(...) or this.xxx(...) which is a |
| 1386 // redirected constructor. We don't need to check whether | 1403 // redirected constructor. We don't need to check whether |
| 1387 // const fields are initialized. The other constructor will | 1404 // const fields are initialized. The other constructor will |
| 1388 // guarantee that. | 1405 // guarantee that. |
| 1389 ConsumeToken(); // Colon. | 1406 ConsumeToken(); // Colon. |
| 1390 ParseConstructorRedirection(cls, receiver); | 1407 ParseConstructorRedirection(cls, receiver); |
| 1391 return; | 1408 return; |
| 1392 } | 1409 } |
| 1393 | |
| 1394 do { | 1410 do { |
| 1395 ConsumeToken(); // Colon or comma. | 1411 ConsumeToken(); // Colon or comma. |
| 1412 AstNode* init_statement; |
| 1396 if (CurrentToken() == Token::kSUPER) { | 1413 if (CurrentToken() == Token::kSUPER) { |
| 1397 if (super_init_statement != NULL) { | 1414 if (super_init_seen) { |
| 1398 ErrorMsg("Duplicate call to super constructor"); | 1415 ErrorMsg("Duplicate call to super constructor"); |
| 1399 } | 1416 } |
| 1400 super_init_statement = ParseSuperInitializer(cls, receiver); | 1417 init_statement = ParseSuperInitializer(cls, receiver); |
| 1418 super_init_seen = true; |
| 1401 } else { | 1419 } else { |
| 1402 AstNode* init_statement = ParseInitializer(cls, receiver); | 1420 init_statement = ParseInitializer(cls, receiver); |
| 1403 current_block_->statements->Add(init_statement); | |
| 1404 } | 1421 } |
| 1422 current_block_->statements->Add(init_statement); |
| 1405 } while (CurrentToken() == Token::kCOMMA); | 1423 } while (CurrentToken() == Token::kCOMMA); |
| 1406 } | 1424 } |
| 1407 | 1425 if (!super_init_seen) { |
| 1408 if (super_init_statement != NULL) { | |
| 1409 // Move explicit supercall to the end of the initializer list to | |
| 1410 // avoid executing constructor code on partially initialized objects. | |
| 1411 // TODO(hausner): Fix issue 4995181, evaluation order of constructor | |
| 1412 // initializer lists. | |
| 1413 current_block_->statements->Add(super_init_statement); | |
| 1414 } else { | |
| 1415 // Generate implicit super() if we haven't seen an explicit super call | 1426 // Generate implicit super() if we haven't seen an explicit super call |
| 1416 // or constructor redirection. | 1427 // or constructor redirection. |
| 1417 GenerateSuperInitializerCall(cls, receiver); | 1428 GenerateSuperConstructorCall(cls, receiver); |
| 1418 } | 1429 } |
| 1419 | |
| 1420 CheckConstFieldsInitialized(cls); | 1430 CheckConstFieldsInitialized(cls); |
| 1421 } | 1431 } |
| 1422 | 1432 |
| 1423 | 1433 |
| 1424 void Parser::ParseConstructorRedirection(const Class& cls, | 1434 void Parser::ParseConstructorRedirection(const Class& cls, |
| 1425 LocalVariable* receiver) { | 1435 LocalVariable* receiver) { |
| 1426 ASSERT(CurrentToken() == Token::kTHIS); | 1436 ASSERT(CurrentToken() == Token::kTHIS); |
| 1427 intptr_t call_pos = token_index_; | 1437 intptr_t call_pos = token_index_; |
| 1428 ConsumeToken(); | 1438 ConsumeToken(); |
| 1429 String& ctor_name = String::Handle(cls.Name()); | 1439 String& ctor_name = String::Handle(cls.Name()); |
| 1430 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | 1440 String& ctor_suffix = String::Handle(String::NewSymbol(".")); |
| 1431 | 1441 |
| 1432 if (CurrentToken() == Token::kPERIOD) { | 1442 if (CurrentToken() == Token::kPERIOD) { |
| 1433 ConsumeToken(); | 1443 ConsumeToken(); |
| 1434 ctor_suffix = String::Concat( | 1444 ctor_suffix = String::Concat( |
| 1435 ctor_suffix, *ExpectIdentifier("constructor name expected")); | 1445 ctor_suffix, *ExpectIdentifier("constructor name expected")); |
| 1436 } | 1446 } |
| 1437 ctor_name = String::Concat(ctor_name, ctor_suffix); | 1447 ctor_name = String::Concat(ctor_name, ctor_suffix); |
| 1438 if (CurrentToken() != Token::kLPAREN) { | 1448 if (CurrentToken() != Token::kLPAREN) { |
| 1439 ErrorMsg("parameter list expected"); | 1449 ErrorMsg("parameter list expected"); |
| 1440 } | 1450 } |
| 1441 // 'this' parameter is the first argument to super class constructor. | 1451 |
| 1452 ArgumentListNode* arguments = new ArgumentListNode(call_pos); |
| 1453 // 'this' parameter is the first argument to constructor. |
| 1442 AstNode* implicit_argument = new LoadLocalNode(call_pos, *receiver); | 1454 AstNode* implicit_argument = new LoadLocalNode(call_pos, *receiver); |
| 1443 ArgumentListNode* arguments = | 1455 arguments->Add(implicit_argument); |
| 1444 ParseActualParameters(implicit_argument, kAllowConst); | 1456 // Constructor phase parameter is second argument. |
| 1457 LocalVariable* phase_param = LookupPhaseParameter(); |
| 1458 ASSERT(phase_param != NULL); |
| 1459 AstNode* phase_argument = new LoadLocalNode(call_pos, *phase_param); |
| 1460 arguments->Add(phase_argument); |
| 1461 ParseActualParameters(arguments, kAllowConst); |
| 1445 | 1462 |
| 1446 // Resolve the constructor. | 1463 // Resolve the constructor. |
| 1447 const Function& redirect_ctor = Function::ZoneHandle( | 1464 const Function& redirect_ctor = Function::ZoneHandle( |
| 1448 cls.LookupConstructor(ctor_name)); | 1465 cls.LookupConstructor(ctor_name)); |
| 1449 if (redirect_ctor.IsNull() || | 1466 if (redirect_ctor.IsNull() || |
| 1450 !redirect_ctor.AreValidArguments(arguments->length(), | 1467 !redirect_ctor.AreValidArguments(arguments->length(), |
| 1451 arguments->names())) { | 1468 arguments->names())) { |
| 1452 ErrorMsg(call_pos, "constructor '%s' not found", | 1469 ErrorMsg(call_pos, "constructor '%s' not found", |
| 1453 ctor_name.ToCString()); | 1470 ctor_name.ToCString()); |
| 1454 } | 1471 } |
| 1455 CheckFunctionIsCallable(call_pos, redirect_ctor); | 1472 CheckFunctionIsCallable(call_pos, redirect_ctor); |
| 1456 current_block_->statements->Add( | 1473 current_block_->statements->Add( |
| 1457 new StaticCallNode(call_pos, redirect_ctor, arguments)); | 1474 new StaticCallNode(call_pos, redirect_ctor, arguments)); |
| 1458 } | 1475 } |
| 1459 | 1476 |
| 1460 | 1477 |
| 1461 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { | 1478 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { |
| 1462 ASSERT(func.IsConstructor()); | 1479 ASSERT(func.IsConstructor()); |
| 1463 intptr_t ctor_pos = token_index_; | 1480 intptr_t ctor_pos = token_index_; |
| 1464 | 1481 |
| 1465 // Implicit 'this' is the only parameter/local variable. | 1482 // Implicit 'this' is the only parameter/local variable. |
| 1466 OpenFunctionBlock(func); | 1483 OpenFunctionBlock(func); |
| 1467 | 1484 |
| 1468 | |
| 1469 // Parse expressions of instance fields that have an explicit | 1485 // Parse expressions of instance fields that have an explicit |
| 1470 // initializers. | 1486 // initializers. |
| 1471 GrowableArray<FieldInitExpression> initializers; | 1487 GrowableArray<FieldInitExpression> initializers; |
| 1472 Class& cls = Class::Handle(func.owner()); | 1488 Class& cls = Class::Handle(func.owner()); |
| 1473 ParseInitializedInstanceFields(cls, &initializers); | 1489 ParseInitializedInstanceFields(cls, &initializers); |
| 1474 | 1490 |
| 1475 LocalVariable* receiver = new LocalVariable( | 1491 LocalVariable* receiver = new LocalVariable( |
| 1476 ctor_pos, | 1492 ctor_pos, |
| 1477 String::ZoneHandle(String::NewSymbol(kThisName)), | 1493 String::ZoneHandle(String::NewSymbol(kThisName)), |
| 1478 Type::ZoneHandle(Type::DynamicType())); | 1494 Type::ZoneHandle(Type::DynamicType())); |
| 1479 current_block_->scope->AddVariable(receiver); | 1495 current_block_->scope->AddVariable(receiver); |
| 1480 | 1496 |
| 1497 LocalVariable* phase_parameter = new LocalVariable( |
| 1498 ctor_pos, |
| 1499 String::ZoneHandle(String::NewSymbol(kPhaseParameterName)), |
| 1500 Type::ZoneHandle(Type::DynamicType())); |
| 1501 current_block_->scope->AddVariable(phase_parameter); |
| 1502 |
| 1481 // Now that the "this" parameter is in scope, we can generate the code | 1503 // Now that the "this" parameter is in scope, we can generate the code |
| 1482 // to strore the initializer expressions in the respective instance fields. | 1504 // to strore the initializer expressions in the respective instance fields. |
| 1483 for (int i = 0; i < initializers.length(); i++) { | 1505 for (int i = 0; i < initializers.length(); i++) { |
| 1484 const Field* field = initializers[i].inst_field; | 1506 const Field* field = initializers[i].inst_field; |
| 1485 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver); | 1507 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver); |
| 1486 AstNode* field_init = | 1508 AstNode* field_init = |
| 1487 new StoreInstanceFieldNode(field->token_index(), | 1509 new StoreInstanceFieldNode(field->token_index(), |
| 1488 instance, | 1510 instance, |
| 1489 *field, | 1511 *field, |
| 1490 initializers[i].expr); | 1512 initializers[i].expr); |
| 1491 current_block_->statements->Add(field_init); | 1513 current_block_->statements->Add(field_init); |
| 1492 } | 1514 } |
| 1493 | 1515 |
| 1494 GenerateSuperInitializerCall(cls, receiver); | 1516 GenerateSuperConstructorCall(cls, receiver); |
| 1495 CheckConstFieldsInitialized(cls); | 1517 CheckConstFieldsInitialized(cls); |
| 1496 | 1518 |
| 1497 // Empty constructor body. | 1519 // Empty constructor body. |
| 1498 SequenceNode* statements = CloseBlock(); | 1520 SequenceNode* statements = CloseBlock(); |
| 1499 return statements; | 1521 return statements; |
| 1500 } | 1522 } |
| 1501 | 1523 |
| 1502 | 1524 |
| 1503 // Parser is at the opening parenthesis of the formal parameter declaration | 1525 // Parser is at the opening parenthesis of the formal parameter declaration |
| 1504 // of function. Parse the formal parameters and code. | 1526 // of function. Parse the formal parameters and code. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1524 // The first parameter of a factory is the TypeArguments vector of the type | 1546 // The first parameter of a factory is the TypeArguments vector of the type |
| 1525 // of the instance to be allocated. We name this hidden parameter 'this'. | 1547 // of the instance to be allocated. We name this hidden parameter 'this'. |
| 1526 const bool has_receiver = !func.IsClosureFunction() && | 1548 const bool has_receiver = !func.IsClosureFunction() && |
| 1527 (!func.is_static() || func.IsConstructor() || func.IsFactory()); | 1549 (!func.is_static() || func.IsConstructor() || func.IsFactory()); |
| 1528 const bool are_implicitly_final = func.is_const() && func.IsConstructor(); | 1550 const bool are_implicitly_final = func.is_const() && func.IsConstructor(); |
| 1529 const bool allow_explicit_default_values = true; | 1551 const bool allow_explicit_default_values = true; |
| 1530 ASSERT(CurrentToken() == Token::kLPAREN); | 1552 ASSERT(CurrentToken() == Token::kLPAREN); |
| 1531 if (has_receiver) { | 1553 if (has_receiver) { |
| 1532 params.AddReceiver(token_index_); | 1554 params.AddReceiver(token_index_); |
| 1533 } | 1555 } |
| 1556 if (func.IsConstructor()) { |
| 1557 // Add implicit parameter for constructor phase. |
| 1558 params.AddFinalParameter(token_index_, kPhaseParameterName, |
| 1559 &Type::ZoneHandle(Type::DynamicType())); |
| 1560 } |
| 1534 if (are_implicitly_final) { | 1561 if (are_implicitly_final) { |
| 1535 params.SetImplicitlyFinal(); | 1562 params.SetImplicitlyFinal(); |
| 1536 } | 1563 } |
| 1537 ParseFormalParameterList(allow_explicit_default_values, ¶ms); | 1564 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
| 1538 | 1565 |
| 1539 // The number of parameters and their type are not yet set in local functions, | 1566 // The number of parameters and their type are not yet set in local functions, |
| 1540 // since they are not 'top-level' parsed. | 1567 // since they are not 'top-level' parsed. |
| 1541 if (func.IsLocalFunction()) { | 1568 if (func.IsLocalFunction()) { |
| 1542 AddFormalParamsToFunction(¶ms, func); | 1569 AddFormalParamsToFunction(¶ms, func); |
| 1543 } | 1570 } |
| 1544 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 1571 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
| 1545 ASSERT(Type::Handle(func.result_type()).IsResolved()); | 1572 ASSERT(Type::Handle(func.result_type()).IsResolved()); |
| 1546 ASSERT(func.NumberOfParameters() == params.parameters->length()); | 1573 ASSERT(func.NumberOfParameters() == params.parameters->length()); |
| 1547 | 1574 |
| 1548 // If this is a constructor, initialize instance fields that have an | 1575 // If this is a constructor, initialize instance fields that have an |
| 1549 // explicit initializer expression. This has to be done before code | 1576 // explicit initializer expression. This has to be done before code |
| 1550 // for field initializer parameters are is generated. | 1577 // for field initializer parameters are is generated. |
| 1551 // NB: the instance field initializers have to be compiled before | 1578 // NB: the instance field initializers have to be compiled before |
| 1552 // the parameters are added to the scope, so that a parameter | 1579 // the parameters are added to the scope, so that a parameter |
| 1553 // name cannot shadow a name used in the field initializer expression. | 1580 // name cannot shadow a name used in the field initializer expression. |
| 1581 SequenceNode* init_statements = NULL; |
| 1582 if (func.IsConstructor()) { |
| 1583 GrowableArray<FieldInitExpression> initializers; |
| 1584 ParseInitializedInstanceFields(cls, &initializers); |
| 1554 | 1585 |
| 1555 GrowableArray<FieldInitExpression> initializers; | 1586 // Now populate function scope with the formal parameters. |
| 1556 if (func.IsConstructor()) { | 1587 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1557 ParseInitializedInstanceFields(cls, &initializers); | 1588 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| 1558 } | |
| 1559 | 1589 |
| 1560 // Now populate function scope with the formal parameters. | 1590 // Now that the "this" parameter is in scope, we can generate the code |
| 1561 AddFormalParamsToScope(¶ms, current_block_->scope); | 1591 // to strore the initializer expressions in the respective instance fields. |
| 1592 // We do this before the field parameters and the initializers from the |
| 1593 // constructor's initializer list get compiled. |
| 1594 OpenBlock(); |
| 1595 if (initializers.length() > 0) { |
| 1596 for (int i = 0; i < initializers.length(); i++) { |
| 1597 const Field* field = initializers[i].inst_field; |
| 1598 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver); |
| 1599 AstNode* field_init = |
| 1600 new StoreInstanceFieldNode(field->token_index(), |
| 1601 instance, |
| 1602 *field, |
| 1603 initializers[i].expr); |
| 1604 current_block_->statements->Add(field_init); |
| 1605 } |
| 1606 } |
| 1562 | 1607 |
| 1563 // Now that the "this" parameter is in scope, we can generate the code | 1608 // Turn formal field parameters into field initializers or report error |
| 1564 // to strore the initializer expressions in the respective instance fields. | 1609 // if the function is not a constructor |
| 1565 // We do this before the field parameters and the initializers from the | 1610 if (params.has_field_initializer) { |
| 1566 // constuctor's initializer list get compiled. | 1611 for (int i = 0; i < params.parameters->length(); i++) { |
| 1567 if (initializers.length() > 0) { | 1612 ParamDesc& param = (*params.parameters)[i]; |
| 1568 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1613 if (param.is_field_initializer) { |
| 1569 for (int i = 0; i < initializers.length(); i++) { | 1614 if (!func.IsConstructor()) { |
| 1570 const Field* field = initializers[i].inst_field; | 1615 ErrorMsg(param.name_pos, |
| 1571 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver); | 1616 "field initializer only allowed in constructors"); |
| 1572 AstNode* field_init = | 1617 } |
| 1573 new StoreInstanceFieldNode(field->token_index(), | 1618 |
| 1574 instance, | 1619 const String& field_name = *param.name; |
| 1575 *field, | 1620 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name)); |
| 1576 initializers[i].expr); | 1621 if (field.IsNull()) { |
| 1577 current_block_->statements->Add(field_init); | 1622 ErrorMsg(param.name_pos, |
| 1623 "unresolved reference to instance field '%s'", |
| 1624 field_name.ToCString()); |
| 1625 } |
| 1626 const String& mangled_name = |
| 1627 String::ZoneHandle(MangledInitParamName(field_name)); |
| 1628 AstNode* instance = new LoadLocalNode(param.name_pos, *receiver); |
| 1629 LocalVariable* p = |
| 1630 current_block_->scope->LookupVariable(mangled_name, false); |
| 1631 ASSERT(p != NULL); |
| 1632 AstNode* value = new LoadLocalNode(param.name_pos, *p); |
| 1633 AstNode* initializer = new StoreInstanceFieldNode( |
| 1634 param.name_pos, instance, field, value); |
| 1635 current_block_->statements->Add(initializer); |
| 1636 } |
| 1637 } |
| 1578 } | 1638 } |
| 1579 } | 1639 ParseInitializers(cls, receiver); |
| 1580 | 1640 init_statements = CloseBlock(); |
| 1581 // Turn formal field parameters into field initializers or report error | 1641 LocalVariable* phase_param = LookupPhaseParameter(); |
| 1582 // if the function is not a constructor | 1642 AstNode* phase_value = new LoadLocalNode(token_index_, *phase_param); |
| 1583 if (params.has_field_initializer) { | 1643 AstNode* phase_check = |
| 1584 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1644 new BinaryOpNode(token_index_, Token::kBIT_AND, |
| 1585 for (int i = 0; i < params.parameters->length(); i++) { | 1645 phase_value, |
| 1586 ParamDesc& param = (*params.parameters)[i]; | 1646 new LiteralNode(token_index_, |
| 1587 if (param.is_field_initializer) { | 1647 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); |
| 1588 if (!func.IsConstructor()) { | 1648 AstNode* comparison = |
| 1649 new ComparisonNode(token_index_, Token::kNE_STRICT, |
| 1650 phase_check, |
| 1651 new LiteralNode(token_index_, Smi::ZoneHandle(Smi::New(0)))); |
| 1652 AstNode* guarded_init_statements = |
| 1653 new IfNode(token_index_, comparison, init_statements, NULL); |
| 1654 current_block_->statements->Add(guarded_init_statements); |
| 1655 } else { |
| 1656 // Parsing a function that is not a constructor. |
| 1657 if (params.has_field_initializer) { |
| 1658 for (int i = 0; i < params.parameters->length(); i++) { |
| 1659 ParamDesc& param = (*params.parameters)[i]; |
| 1660 if (param.is_field_initializer) { |
| 1589 ErrorMsg(param.name_pos, | 1661 ErrorMsg(param.name_pos, |
| 1590 "field initializer only allowed in constructors"); | 1662 "field initializer only allowed in constructors"); |
| 1591 } | 1663 } |
| 1592 | |
| 1593 const String& field_name = *param.name; | |
| 1594 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name)); | |
| 1595 if (field.IsNull()) { | |
| 1596 ErrorMsg(param.name_pos, | |
| 1597 "unresolved reference to instance field '%s'", | |
| 1598 field_name.ToCString()); | |
| 1599 } | |
| 1600 const String& mangled_name = | |
| 1601 String::ZoneHandle(MangledInitParamName(field_name)); | |
| 1602 AstNode* instance = new LoadLocalNode(param.name_pos, *receiver); | |
| 1603 LocalVariable* p = | |
| 1604 current_block_->scope->LocalLookupVariable(mangled_name); | |
| 1605 ASSERT(p != NULL); | |
| 1606 AstNode* value = new LoadLocalNode(param.name_pos, *p); | |
| 1607 AstNode* initializer = | |
| 1608 new StoreInstanceFieldNode(param.name_pos, instance, field, value); | |
| 1609 current_block_->statements->Add(initializer); | |
| 1610 } | 1664 } |
| 1611 } | 1665 } |
| 1612 } | 1666 // Populate function scope with the formal parameters. |
| 1613 | 1667 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1614 if (func.IsConstructor()) { | |
| 1615 ParseInitializers(cls); | |
| 1616 } | 1668 } |
| 1617 | 1669 |
| 1618 if (FLAG_enable_type_checks && | 1670 if (FLAG_enable_type_checks && |
| 1619 (current_block_->scope->function_level() > 0)) { | 1671 (current_block_->scope->function_level() > 0)) { |
| 1620 // We are parsing, but not compiling, a local function. | 1672 // We are parsing, but not compiling, a local function. |
| 1621 // The instantiator may be required at run time for generic type checks. | 1673 // The instantiator may be required at run time for generic type checks. |
| 1622 if ((current_class().NumTypeParameters() > 0) && | 1674 if ((current_class().NumTypeParameters() > 0) && |
| 1623 (!current_function().is_static() || | 1675 (!current_function().is_static() || |
| 1624 current_function().IsInFactoryScope())) { | 1676 current_function().IsInFactoryScope())) { |
| 1625 // Make sure that the receiver of the enclosing instance function | 1677 // Make sure that the receiver of the enclosing instance function |
| 1626 // (or implicit first parameter of an enclosing factory) is marked as | 1678 // (or implicit first parameter of an enclosing factory) is marked as |
| 1627 // captured if type checks are enabled, because they may access the | 1679 // captured if type checks are enabled, because they may access the |
| 1628 // receiver to instantiate types. | 1680 // receiver to instantiate types. |
| 1629 CaptureReceiver(); | 1681 CaptureReceiver(); |
| 1630 } | 1682 } |
| 1631 } | 1683 } |
| 1632 | 1684 |
| 1685 if (func.IsConstructor()) { |
| 1686 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| 1687 StaticCallNode* super_call = NULL; |
| 1688 ASSERT(init_statements != NULL); |
| 1689 // Look for the super initializer call in the sequence of initializer |
| 1690 // statements. If it exists and is not the last initializer statement, |
| 1691 // we need to create an implicit super call to the super constructor's |
| 1692 // body. |
| 1693 // Thus, iterate over all but the last initializer to see whether |
| 1694 // it's a super constructor call. |
| 1695 for (int i = 0; i < init_statements->length() - 1; i++) { |
| 1696 if (init_statements->NodeAt(i)->IsStaticCallNode()) { |
| 1697 StaticCallNode* static_call = |
| 1698 init_statements->NodeAt(i)->AsStaticCallNode(); |
| 1699 if (static_call->function().IsConstructor()) { |
| 1700 super_call = static_call; |
| 1701 break; |
| 1702 } |
| 1703 } |
| 1704 } |
| 1705 if (super_call != NULL) { |
| 1706 // Generate an implicit call to the super constructor's body. |
| 1707 // We need to patch the super _initializer_ call so that it |
| 1708 // saves the evaluated actual arguments in temporary variables. |
| 1709 // The temporary variables are necessary so that the argument |
| 1710 // expressions are not evaluated twice. |
| 1711 ArgumentListNode* ctor_args = super_call->arguments(); |
| 1712 // The super initializer call has at least 2 arguments: the |
| 1713 // implicit receiver, and the hidden constructor phase. |
| 1714 ASSERT(ctor_args->length() >= 2); |
| 1715 for (int i = 2; i < ctor_args->length(); i++) { |
| 1716 AstNode* arg = ctor_args->NodeAt(i); |
| 1717 if (!arg->IsLoadLocalNode() && !arg->IsLiteralNode()) { |
| 1718 LocalVariable* temp = |
| 1719 CreateTempConstVariable(arg->token_index(), arg->id(), "sca"); |
| 1720 AstNode* save_temp = |
| 1721 new StoreLocalNode(arg->token_index(), *temp, arg); |
| 1722 ctor_args->SetNodeAt(i, save_temp); |
| 1723 } |
| 1724 } |
| 1725 } |
| 1726 OpenBlock(); |
| 1727 if (super_call != NULL) { |
| 1728 ArgumentListNode* initializer_args = super_call->arguments(); |
| 1729 const Function& super_ctor = super_call->function(); |
| 1730 // Patch the initializer call so it only executes the super |
| 1731 // initializer. |
| 1732 initializer_args->SetNodeAt(1, |
| 1733 new LiteralNode(token_index_, |
| 1734 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); |
| 1735 |
| 1736 ArgumentListNode* super_call_args = new ArgumentListNode(token_index_); |
| 1737 // First argument is the receiver. |
| 1738 super_call_args->Add(new LoadLocalNode(token_index_, *receiver)); |
| 1739 // Second argument is the constructor phase argument. |
| 1740 AstNode* phase_parameter = |
| 1741 new LiteralNode(token_index_, |
| 1742 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))); |
| 1743 super_call_args->Add(phase_parameter); |
| 1744 for (int i = 2; i < initializer_args->length(); i++) { |
| 1745 AstNode* arg = initializer_args->NodeAt(i); |
| 1746 if (arg->IsLiteralNode()) { |
| 1747 LiteralNode* lit = arg->AsLiteralNode(); |
| 1748 super_call_args->Add(new LiteralNode(token_index_, lit->literal())); |
| 1749 } else { |
| 1750 ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode()); |
| 1751 if (arg->IsLoadLocalNode()) { |
| 1752 const LocalVariable& temp = arg->AsLoadLocalNode()->local(); |
| 1753 super_call_args->Add(new LoadLocalNode(token_index_, temp)); |
| 1754 } else if (arg->IsStoreLocalNode()) { |
| 1755 const LocalVariable& temp = arg->AsStoreLocalNode()->local(); |
| 1756 super_call_args->Add(new LoadLocalNode(token_index_, temp)); |
| 1757 } |
| 1758 } |
| 1759 } |
| 1760 ASSERT(super_ctor.AreValidArguments(super_call_args->length(), |
| 1761 super_call_args->names())); |
| 1762 current_block_->statements->Add( |
| 1763 new StaticCallNode(token_index_, super_ctor, super_call_args)); |
| 1764 } |
| 1765 } |
| 1633 if (CurrentToken() == Token::kLBRACE) { | 1766 if (CurrentToken() == Token::kLBRACE) { |
| 1634 ConsumeToken(); | 1767 ConsumeToken(); |
| 1635 ParseStatementSequence(); | 1768 ParseStatementSequence(); |
| 1636 ExpectToken(Token::kRBRACE); | 1769 ExpectToken(Token::kRBRACE); |
| 1637 } else if (CurrentToken() == Token::kARROW) { | 1770 } else if (CurrentToken() == Token::kARROW) { |
| 1638 ConsumeToken(); | 1771 ConsumeToken(); |
| 1639 intptr_t expr_pos = token_index_; | 1772 intptr_t expr_pos = token_index_; |
| 1640 AstNode* expr = ParseExpr(kAllowConst); | 1773 AstNode* expr = ParseExpr(kAllowConst); |
| 1641 ASSERT(expr != NULL); | 1774 ASSERT(expr != NULL); |
| 1642 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); | 1775 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); |
| 1643 } else if (IsLiteral("native")) { | 1776 } else if (IsLiteral("native")) { |
| 1644 ParseNativeFunctionBlock(¶ms, func); | 1777 ParseNativeFunctionBlock(¶ms, func); |
| 1645 } else if (CurrentToken() == Token::kSEMICOLON) { | 1778 } else if (CurrentToken() == Token::kSEMICOLON) { |
| 1646 ConsumeToken(); | 1779 ConsumeToken(); |
| 1647 ASSERT(func.IsConstructor()); | 1780 ASSERT(func.IsConstructor()); |
| 1648 // Some constructors have no function body. | 1781 // Some constructors have no function body. |
| 1649 } else { | 1782 } else { |
| 1650 UnexpectedToken(); | 1783 UnexpectedToken(); |
| 1651 } | 1784 } |
| 1785 if (func.IsConstructor()) { |
| 1786 SequenceNode* ctor_block = CloseBlock(); |
| 1787 LocalVariable* phase_param = LookupPhaseParameter(); |
| 1788 AstNode* phase_value = new LoadLocalNode(token_index_, *phase_param); |
| 1789 AstNode* phase_check = |
| 1790 new BinaryOpNode(token_index_, Token::kBIT_AND, |
| 1791 phase_value, |
| 1792 new LiteralNode(token_index_, |
| 1793 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody)))); |
| 1794 AstNode* comparison = |
| 1795 new ComparisonNode(token_index_, Token::kNE_STRICT, |
| 1796 phase_check, |
| 1797 new LiteralNode(token_index_, Smi::ZoneHandle(Smi::New(0)))); |
| 1798 AstNode* guarded_block_statements = |
| 1799 new IfNode(token_index_, comparison, ctor_block, NULL); |
| 1800 current_block_->statements->Add(guarded_block_statements); |
| 1801 } |
| 1652 | 1802 |
| 1653 SequenceNode* statements = CloseBlock(); | 1803 SequenceNode* statements = CloseBlock(); |
| 1654 return statements; | 1804 return statements; |
| 1655 } | 1805 } |
| 1656 | 1806 |
| 1657 | 1807 |
| 1658 void Parser::SkipIf(Token::Kind token) { | 1808 void Parser::SkipIf(Token::Kind token) { |
| 1659 if (CurrentToken() == token) { | 1809 if (CurrentToken() == token) { |
| 1660 ConsumeToken(); | 1810 ConsumeToken(); |
| 1661 } | 1811 } |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1789 const bool has_this_param = | 1939 const bool has_this_param = |
| 1790 !method->has_static || method->IsConstructor() || method->has_factory; | 1940 !method->has_static || method->IsConstructor() || method->has_factory; |
| 1791 const bool are_implicitly_final = method->has_const; | 1941 const bool are_implicitly_final = method->has_const; |
| 1792 const bool allow_explicit_default_values = | 1942 const bool allow_explicit_default_values = |
| 1793 (!method->has_abstract && !members->is_interface()); | 1943 (!method->has_abstract && !members->is_interface()); |
| 1794 const intptr_t formal_param_pos = token_index_; | 1944 const intptr_t formal_param_pos = token_index_; |
| 1795 method->params.Clear(); | 1945 method->params.Clear(); |
| 1796 if (has_this_param) { | 1946 if (has_this_param) { |
| 1797 method->params.AddReceiver(formal_param_pos); | 1947 method->params.AddReceiver(formal_param_pos); |
| 1798 } | 1948 } |
| 1949 // Constructors have an implicit parameter for the constructor phase. |
| 1950 if (method->IsConstructor()) { |
| 1951 method->params.AddFinalParameter(token_index_, kPhaseParameterName, |
| 1952 &Type::ZoneHandle(Type::DynamicType())); |
| 1953 } |
| 1799 if (are_implicitly_final) { | 1954 if (are_implicitly_final) { |
| 1800 method->params.SetImplicitlyFinal(); | 1955 method->params.SetImplicitlyFinal(); |
| 1801 } | 1956 } |
| 1802 ParseFormalParameterList(allow_explicit_default_values, &method->params); | 1957 ParseFormalParameterList(allow_explicit_default_values, &method->params); |
| 1803 if (method->IsGetter() || method->IsSetter()) { | 1958 if (method->IsGetter() || method->IsSetter()) { |
| 1804 int expected_num_parameters = 0; | 1959 int expected_num_parameters = 0; |
| 1805 if (method->IsGetter()) { | 1960 if (method->IsGetter()) { |
| 1806 expected_num_parameters = (method->has_static) ? 0 : 1; | 1961 expected_num_parameters = (method->has_static) ? 0 : 1; |
| 1807 method->name = &String::ZoneHandle(Field::GetterName(*method->name)); | 1962 method->name = &String::ZoneHandle(Field::GetterName(*method->name)); |
| 1808 } else { | 1963 } else { |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2300 cls.SetFunctions(Array::Handle(NewArray<Function>(members.functions()))); | 2455 cls.SetFunctions(Array::Handle(NewArray<Function>(members.functions()))); |
| 2301 classes->Add(&cls); | 2456 classes->Add(&cls); |
| 2302 } | 2457 } |
| 2303 | 2458 |
| 2304 | 2459 |
| 2305 // 1. Add an implicit constructor if no explicit constructor is present. | 2460 // 1. Add an implicit constructor if no explicit constructor is present. |
| 2306 // 2. Check for cycles in constructor redirection. | 2461 // 2. Check for cycles in constructor redirection. |
| 2307 void Parser::CheckConstructors(ClassDesc* class_desc) { | 2462 void Parser::CheckConstructors(ClassDesc* class_desc) { |
| 2308 // Add an implicit constructor if no explicit constructor is present. | 2463 // Add an implicit constructor if no explicit constructor is present. |
| 2309 if (!class_desc->has_constructor()) { | 2464 if (!class_desc->has_constructor()) { |
| 2310 // The implicit constructor is unnamed, has no parameter, and contains | 2465 // The implicit constructor is unnamed, has no explicit parameter, |
| 2311 // a supercall in the initializer list. | 2466 // and contains a supercall in the initializer list. |
| 2312 String& ctor_name = String::ZoneHandle( | 2467 String& ctor_name = String::ZoneHandle( |
| 2313 String::Concat(class_desc->class_name(), | 2468 String::Concat(class_desc->class_name(), |
| 2314 String::Handle(String::NewSymbol(".")))); | 2469 String::Handle(String::NewSymbol(".")))); |
| 2315 ctor_name = String::NewSymbol(ctor_name); | 2470 ctor_name = String::NewSymbol(ctor_name); |
| 2316 Function& ctor = Function::ZoneHandle( | 2471 Function& ctor = Function::ZoneHandle( |
| 2317 Function::New(ctor_name, | 2472 Function::New(ctor_name, |
| 2318 RawFunction::kConstructor, | 2473 RawFunction::kConstructor, |
| 2319 /* is_static = */ false, | 2474 /* is_static = */ false, |
| 2320 /* is_const = */ false, | 2475 /* is_const = */ false, |
| 2321 class_desc->token_pos())); | 2476 class_desc->token_pos())); |
| 2322 ParamList params; | 2477 ParamList params; |
| 2478 // Add implicit 'this' parameter. |
| 2323 params.AddReceiver(token_index_); | 2479 params.AddReceiver(token_index_); |
| 2480 // Add implicit parameter for constructor phase. |
| 2481 params.AddFinalParameter(token_index_, kPhaseParameterName, |
| 2482 &Type::ZoneHandle(Type::DynamicType())); |
| 2483 |
| 2324 AddFormalParamsToFunction(¶ms, ctor); | 2484 AddFormalParamsToFunction(¶ms, ctor); |
| 2325 // TODO(regis): What are the type arguments? | 2485 // TODO(regis): What are the type arguments? |
| 2326 Type& result_type = Type::ZoneHandle( | 2486 Type& result_type = Type::ZoneHandle( |
| 2327 Type::NewRawType(Class::Handle(class_desc->clazz()))); | 2487 Type::NewRawType(Class::Handle(class_desc->clazz()))); |
| 2328 ctor.set_result_type(result_type); | 2488 ctor.set_result_type(result_type); |
| 2329 class_desc->AddFunction(&ctor); | 2489 class_desc->AddFunction(&ctor); |
| 2330 } | 2490 } |
| 2331 | 2491 |
| 2332 // Check for cycles in constructor redirection. | 2492 // Check for cycles in constructor redirection. |
| 2333 const GrowableArray<MemberDesc>& members = class_desc->members(); | 2493 const GrowableArray<MemberDesc>& members = class_desc->members(); |
| (...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3193 } | 3353 } |
| 3194 | 3354 |
| 3195 | 3355 |
| 3196 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, | 3356 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, |
| 3197 bool test_only) { | 3357 bool test_only) { |
| 3198 const String& this_name = String::Handle(String::NewSymbol(kThisName)); | 3358 const String& this_name = String::Handle(String::NewSymbol(kThisName)); |
| 3199 return from_scope->LookupVariable(this_name, test_only); | 3359 return from_scope->LookupVariable(this_name, test_only); |
| 3200 } | 3360 } |
| 3201 | 3361 |
| 3202 | 3362 |
| 3363 LocalVariable* Parser::LookupPhaseParameter() { |
| 3364 const String& phase_name = |
| 3365 String::Handle(String::NewSymbol(kPhaseParameterName)); |
| 3366 const bool kTestOnly = false; |
| 3367 return current_block_->scope->LookupVariable(phase_name, kTestOnly); |
| 3368 } |
| 3369 |
| 3370 |
| 3203 void Parser::CaptureReceiver() { | 3371 void Parser::CaptureReceiver() { |
| 3204 ASSERT(current_block_->scope->function_level() > 0); | 3372 ASSERT(current_block_->scope->function_level() > 0); |
| 3205 const bool kTestOnly = false; | 3373 const bool kTestOnly = false; |
| 3206 // Side effect of lookup captures the receiver variable. | 3374 // Side effect of lookup captures the receiver variable. |
| 3207 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); | 3375 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); |
| 3208 ASSERT(receiver != NULL); | 3376 ASSERT(receiver != NULL); |
| 3209 } | 3377 } |
| 3210 | 3378 |
| 3211 | 3379 |
| 3212 AstNode* Parser::LoadReceiver(intptr_t token_pos) { | 3380 AstNode* Parser::LoadReceiver(intptr_t token_pos) { |
| (...skipping 1980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5193 Unimplemented("incr operation not implemented"); | 5361 Unimplemented("incr operation not implemented"); |
| 5194 } | 5362 } |
| 5195 expr = incr_op_node; | 5363 expr = incr_op_node; |
| 5196 } else { | 5364 } else { |
| 5197 expr = ParsePostfixExpr(); | 5365 expr = ParsePostfixExpr(); |
| 5198 } | 5366 } |
| 5199 return expr; | 5367 return expr; |
| 5200 } | 5368 } |
| 5201 | 5369 |
| 5202 | 5370 |
| 5203 ArgumentListNode* Parser::ParseActualParameters(AstNode* implicit_argument, | 5371 ArgumentListNode* Parser::ParseActualParameters( |
| 5204 bool require_const) { | 5372 ArgumentListNode* implicit_arguments, |
| 5373 bool require_const) { |
| 5205 TRACE_PARSER("ParseActualParameters"); | 5374 TRACE_PARSER("ParseActualParameters"); |
| 5206 ASSERT(CurrentToken() == Token::kLPAREN); | 5375 ASSERT(CurrentToken() == Token::kLPAREN); |
| 5207 const bool saved_mode = SetAllowFunctionLiterals(true); | 5376 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 5208 ArgumentListNode* arguments = new ArgumentListNode(token_index_); | 5377 ArgumentListNode* arguments; |
| 5209 if (implicit_argument != NULL) { | 5378 if (implicit_arguments == NULL) { |
| 5210 arguments->Add(implicit_argument); | 5379 arguments = new ArgumentListNode(token_index_); |
| 5380 } else { |
| 5381 arguments = implicit_arguments; |
| 5211 } | 5382 } |
| 5212 GrowableArray<const String*> names; | 5383 GrowableArray<const String*> names; |
| 5213 bool named_argument_seen = false; | 5384 bool named_argument_seen = false; |
| 5214 if (LookaheadToken(1) != Token::kRPAREN) { | 5385 if (LookaheadToken(1) != Token::kRPAREN) { |
| 5215 do { | 5386 do { |
| 5216 ASSERT((CurrentToken() == Token::kLPAREN) || | 5387 ASSERT((CurrentToken() == Token::kLPAREN) || |
| 5217 (CurrentToken() == Token::kCOMMA)); | 5388 (CurrentToken() == Token::kCOMMA)); |
| 5218 ConsumeToken(); | 5389 ConsumeToken(); |
| 5219 if ((CurrentToken() == Token::kIDENT) && | 5390 if ((CurrentToken() == Token::kIDENT) && |
| 5220 (LookaheadToken(1) == Token::kCOLON)) { | 5391 (LookaheadToken(1) == Token::kCOLON)) { |
| (...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5800 field.set_value(const_value); | 5971 field.set_value(const_value); |
| 5801 } | 5972 } |
| 5802 } | 5973 } |
| 5803 | 5974 |
| 5804 | 5975 |
| 5805 RawInstance* Parser::EvaluateConstConstructorCall( | 5976 RawInstance* Parser::EvaluateConstConstructorCall( |
| 5806 const Class& type_class, | 5977 const Class& type_class, |
| 5807 const TypeArguments& type_arguments, | 5978 const TypeArguments& type_arguments, |
| 5808 const Function& constructor, | 5979 const Function& constructor, |
| 5809 ArgumentListNode* arguments) { | 5980 ArgumentListNode* arguments) { |
| 5810 GrowableArray<const Object*> arg_values(arguments->length() + 1); | 5981 // +2 for implicit receiver and constructor phase arguments. |
| 5982 GrowableArray<const Object*> arg_values(arguments->length() + 2); |
| 5811 Instance& instance = Instance::Handle(); | 5983 Instance& instance = Instance::Handle(); |
| 5812 if (!constructor.IsFactory()) { | 5984 if (!constructor.IsFactory()) { |
| 5813 instance = Instance::New(type_class); | 5985 instance = Instance::New(type_class); |
| 5814 if (!type_arguments.IsNull()) { | 5986 if (!type_arguments.IsNull()) { |
| 5815 // TODO(regis): Where should we check the constraints on type parameters? | 5987 // TODO(regis): Where should we check the constraints on type parameters? |
| 5816 if (!type_arguments.IsInstantiated()) { | 5988 if (!type_arguments.IsInstantiated()) { |
| 5817 ErrorMsg("type must be constant in const constructor"); | 5989 ErrorMsg("type must be constant in const constructor"); |
| 5818 } | 5990 } |
| 5819 instance.SetTypeArguments(type_arguments); | 5991 instance.SetTypeArguments(type_arguments); |
| 5820 } | 5992 } |
| 5821 arg_values.Add(&instance); | 5993 arg_values.Add(&instance); |
| 5994 arg_values.Add(&Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); |
| 5822 } else { | 5995 } else { |
| 5823 // Prepend type_arguments to list of arguments to factory. | 5996 // Prepend type_arguments to list of arguments to factory. |
| 5824 ASSERT(type_arguments.IsZoneHandle()); | 5997 ASSERT(type_arguments.IsZoneHandle()); |
| 5825 arg_values.Add(&type_arguments); | 5998 arg_values.Add(&type_arguments); |
| 5826 } | 5999 } |
| 5827 for (int i = 0; i < arguments->length(); i++) { | 6000 for (int i = 0; i < arguments->length(); i++) { |
| 5828 AstNode* arg = arguments->NodeAt(i); | 6001 AstNode* arg = arguments->NodeAt(i); |
| 5829 // Arguments have been evaluated to a literal value already. | 6002 // Arguments have been evaluated to a literal value already. |
| 5830 ASSERT(arg->IsLiteralNode()); | 6003 ASSERT(arg->IsLiteralNode()); |
| 5831 arg_values.Add(&arg->AsLiteralNode()->literal()); | 6004 arg_values.Add(&arg->AsLiteralNode()->literal()); |
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6476 } | 6649 } |
| 6477 | 6650 |
| 6478 // Parse constructor parameters. | 6651 // Parse constructor parameters. |
| 6479 if (CurrentToken() != Token::kLPAREN) { | 6652 if (CurrentToken() != Token::kLPAREN) { |
| 6480 ErrorMsg("'(' expected"); | 6653 ErrorMsg("'(' expected"); |
| 6481 } | 6654 } |
| 6482 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); | 6655 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); |
| 6483 | 6656 |
| 6484 // A constructor has an implicit 'this' parameter (instance to construct) | 6657 // A constructor has an implicit 'this' parameter (instance to construct) |
| 6485 // and a factory has an implicit 'this' parameter (type_arguments). | 6658 // and a factory has an implicit 'this' parameter (type_arguments). |
| 6486 intptr_t arguments_length = arguments->length() + 1; | 6659 // A constructor has a second implicit 'phase' parameter. |
| 6660 intptr_t arguments_length = arguments->length() + 2; |
| 6487 | 6661 |
| 6488 if (type_class.is_interface()) { | 6662 if (type_class.is_interface()) { |
| 6489 // We need to make sure that an appropriate constructor is | 6663 // We need to make sure that an appropriate constructor is |
| 6490 // declared in the interface. | 6664 // declared in the interface. |
| 6491 const String& constructor_name = | 6665 const String& constructor_name = |
| 6492 BuildConstructorName(type_class_name, named_constructor); | 6666 BuildConstructorName(type_class_name, named_constructor); |
| 6493 const String& external_constructor_name = | 6667 const String& external_constructor_name = |
| 6494 (named_constructor ? constructor_name : type_class_name); | 6668 (named_constructor ? constructor_name : type_class_name); |
| 6495 Function& constructor = Function::ZoneHandle( | 6669 Function& constructor = Function::ZoneHandle( |
| 6496 type_class.LookupConstructor(constructor_name)); | 6670 type_class.LookupConstructor(constructor_name)); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6541 | 6715 |
| 6542 // Make sure that an appropriate constructor exists. | 6716 // Make sure that an appropriate constructor exists. |
| 6543 const String& constructor_name = | 6717 const String& constructor_name = |
| 6544 BuildConstructorName(type_class_name, named_constructor); | 6718 BuildConstructorName(type_class_name, named_constructor); |
| 6545 const String& external_constructor_name = | 6719 const String& external_constructor_name = |
| 6546 (named_constructor ? constructor_name : type_class_name); | 6720 (named_constructor ? constructor_name : type_class_name); |
| 6547 Function& constructor = Function::ZoneHandle( | 6721 Function& constructor = Function::ZoneHandle( |
| 6548 type_class.LookupConstructor(constructor_name)); | 6722 type_class.LookupConstructor(constructor_name)); |
| 6549 if (constructor.IsNull()) { | 6723 if (constructor.IsNull()) { |
| 6550 constructor = type_class.LookupFactory(constructor_name); | 6724 constructor = type_class.LookupFactory(constructor_name); |
| 6725 // A factory does not have the implicit 'phase' parameter. |
| 6726 arguments_length -= 1; |
| 6551 } | 6727 } |
| 6552 if (constructor.IsNull()) { | 6728 if (constructor.IsNull()) { |
| 6553 ErrorMsg(new_pos, "class '%s' has no constructor or factory named '%s'", | 6729 ErrorMsg(new_pos, "class '%s' has no constructor or factory named '%s'", |
| 6554 String::Handle(type_class.Name()).ToCString(), | 6730 String::Handle(type_class.Name()).ToCString(), |
| 6555 external_constructor_name.ToCString()); | 6731 external_constructor_name.ToCString()); |
| 6556 } | 6732 } |
| 6557 if (!constructor.AreValidArguments(arguments_length, arguments->names())) { | 6733 if (!constructor.AreValidArguments(arguments_length, arguments->names())) { |
| 6558 ErrorMsg(new_pos, "invalid arguments passed to constructor '%s' " | 6734 ErrorMsg(new_pos, "invalid arguments passed to constructor '%s' " |
| 6559 "for class '%s'", | 6735 "for class '%s'", |
| 6560 external_constructor_name.ToCString(), | 6736 external_constructor_name.ToCString(), |
| (...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7022 } | 7198 } |
| 7023 | 7199 |
| 7024 | 7200 |
| 7025 void Parser::SkipNestedExpr() { | 7201 void Parser::SkipNestedExpr() { |
| 7026 const bool saved_mode = SetAllowFunctionLiterals(true); | 7202 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7027 SkipExpr(); | 7203 SkipExpr(); |
| 7028 SetAllowFunctionLiterals(saved_mode); | 7204 SetAllowFunctionLiterals(saved_mode); |
| 7029 } | 7205 } |
| 7030 | 7206 |
| 7031 } // namespace dart | 7207 } // namespace dart |
| OLD | NEW |