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 |