| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "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 1265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1276 return native_name; | 1276 return native_name; |
| 1277 } | 1277 } |
| 1278 | 1278 |
| 1279 | 1279 |
| 1280 // Resolve and return the dynamic function of the given name in the superclass. | 1280 // Resolve and return the dynamic function of the given name in the superclass. |
| 1281 // If it is not found, and resolve_getter is true, try to resolve a getter of | 1281 // If it is not found, and resolve_getter is true, try to resolve a getter of |
| 1282 // the same name. If it is still not found, return noSuchMethod and | 1282 // the same name. If it is still not found, return noSuchMethod and |
| 1283 // set is_no_such_method to true.. | 1283 // set is_no_such_method to true.. |
| 1284 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, | 1284 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, |
| 1285 const String& name, | 1285 const String& name, |
| 1286 ArgumentListNode* arguments, |
| 1286 bool resolve_getter, | 1287 bool resolve_getter, |
| 1287 bool* is_no_such_method) { | 1288 bool* is_no_such_method) { |
| 1288 const Class& super_class = Class::Handle(current_class().SuperClass()); | 1289 const Class& super_class = Class::Handle(current_class().SuperClass()); |
| 1289 if (super_class.IsNull()) { | 1290 if (super_class.IsNull()) { |
| 1290 ErrorMsg(token_pos, "class '%s' does not have a superclass", | 1291 ErrorMsg(token_pos, "class '%s' does not have a superclass", |
| 1291 String::Handle(current_class().Name()).ToCString()); | 1292 String::Handle(current_class().Name()).ToCString()); |
| 1292 } | 1293 } |
| 1293 Function& super_func = | 1294 Function& super_func = Function::Handle( |
| 1294 Function::Handle(Resolver::ResolveDynamicAnyArgs(super_class, name)); | 1295 Resolver::ResolveDynamicAnyArgs(super_class, name)); |
| 1295 if (super_func.IsNull() && resolve_getter) { | 1296 if (!super_func.IsNull() && |
| 1297 !super_func.AreValidArguments(arguments->length(), |
| 1298 arguments->names(), |
| 1299 NULL)) { |
| 1300 super_func = Function::null(); |
| 1301 } else if (super_func.IsNull() && resolve_getter) { |
| 1296 const String& getter_name = String::ZoneHandle(Field::GetterName(name)); | 1302 const String& getter_name = String::ZoneHandle(Field::GetterName(name)); |
| 1297 super_func = Resolver::ResolveDynamicAnyArgs(super_class, getter_name); | 1303 super_func = Resolver::ResolveDynamicAnyArgs(super_class, getter_name); |
| 1298 ASSERT(super_func.IsNull() || | 1304 ASSERT(super_func.IsNull() || |
| 1299 (super_func.kind() != RawFunction::kConstImplicitGetter)); | 1305 (super_func.kind() != RawFunction::kConstImplicitGetter)); |
| 1300 } | 1306 } |
| 1301 if (super_func.IsNull()) { | 1307 if (super_func.IsNull()) { |
| 1302 const String& no_such_method_name = String::Handle(Symbols::NoSuchMethod()); | 1308 const String& no_such_method_name = String::Handle(Symbols::NoSuchMethod()); |
| 1303 super_func = | 1309 super_func = |
| 1304 Resolver::ResolveDynamicAnyArgs(super_class, no_such_method_name); | 1310 Resolver::ResolveDynamicAnyArgs(super_class, no_such_method_name); |
| 1305 ASSERT(!super_func.IsNull()); | 1311 ASSERT(!super_func.IsNull()); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1374 call_pos, function_name, function_args)); | 1380 call_pos, function_name, function_args)); |
| 1375 return arguments; | 1381 return arguments; |
| 1376 } | 1382 } |
| 1377 | 1383 |
| 1378 | 1384 |
| 1379 AstNode* Parser::ParseSuperCall(const String& function_name) { | 1385 AstNode* Parser::ParseSuperCall(const String& function_name) { |
| 1380 TRACE_PARSER("ParseSuperCall"); | 1386 TRACE_PARSER("ParseSuperCall"); |
| 1381 ASSERT(CurrentToken() == Token::kLPAREN); | 1387 ASSERT(CurrentToken() == Token::kLPAREN); |
| 1382 const intptr_t supercall_pos = TokenPos(); | 1388 const intptr_t supercall_pos = TokenPos(); |
| 1383 | 1389 |
| 1390 // 'this' parameter is the first argument to super call. |
| 1391 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 1392 AstNode* receiver = LoadReceiver(supercall_pos); |
| 1393 arguments->Add(receiver); |
| 1394 ParseActualParameters(arguments, kAllowConst); |
| 1395 |
| 1384 const bool kResolveGetter = true; | 1396 const bool kResolveGetter = true; |
| 1385 bool is_no_such_method = false; | 1397 bool is_no_such_method = false; |
| 1386 const Function& super_function = Function::ZoneHandle( | 1398 const Function& super_function = Function::ZoneHandle( |
| 1387 GetSuperFunction(supercall_pos, | 1399 GetSuperFunction(supercall_pos, |
| 1388 function_name, | 1400 function_name, |
| 1401 arguments, |
| 1389 kResolveGetter, | 1402 kResolveGetter, |
| 1390 &is_no_such_method)); | 1403 &is_no_such_method)); |
| 1391 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | |
| 1392 if (super_function.IsGetterFunction() || | 1404 if (super_function.IsGetterFunction() || |
| 1393 super_function.IsImplicitGetterFunction()) { | 1405 super_function.IsImplicitGetterFunction()) { |
| 1394 // 'this' is not passed as parameter to the closure. | |
| 1395 ParseActualParameters(arguments, kAllowConst); | |
| 1396 const Class& super_class = Class::ZoneHandle(current_class().SuperClass()); | 1406 const Class& super_class = Class::ZoneHandle(current_class().SuperClass()); |
| 1397 AstNode* closure = new StaticGetterNode(supercall_pos, | 1407 AstNode* closure = new StaticGetterNode(supercall_pos, |
| 1398 LoadReceiver(supercall_pos), | 1408 LoadReceiver(supercall_pos), |
| 1399 /* is_super_getter */ true, | 1409 /* is_super_getter */ true, |
| 1400 super_class, | 1410 super_class, |
| 1401 function_name); | 1411 function_name); |
| 1402 EnsureExpressionTemp(); | 1412 EnsureExpressionTemp(); |
| 1403 return new ClosureCallNode(supercall_pos, closure, arguments); | 1413 // 'this' is not passed as parameter to the closure. |
| 1414 ArgumentListNode* closure_arguments = new ArgumentListNode(supercall_pos); |
| 1415 for (int i = 1; i < arguments->length(); i++) { |
| 1416 closure_arguments->Add(arguments->NodeAt(i)); |
| 1417 } |
| 1418 return new ClosureCallNode(supercall_pos, closure, closure_arguments); |
| 1404 } | 1419 } |
| 1405 // 'this' parameter is the first argument to super call. | |
| 1406 AstNode* receiver = LoadReceiver(supercall_pos); | |
| 1407 arguments->Add(receiver); | |
| 1408 ParseActualParameters(arguments, kAllowConst); | |
| 1409 if (is_no_such_method) { | 1420 if (is_no_such_method) { |
| 1410 arguments = BuildNoSuchMethodArguments( | 1421 arguments = BuildNoSuchMethodArguments( |
| 1411 supercall_pos, function_name, *arguments); | 1422 supercall_pos, function_name, *arguments); |
| 1412 } | 1423 } |
| 1413 return new StaticCallNode(supercall_pos, super_function, arguments); | 1424 return new StaticCallNode(supercall_pos, super_function, arguments); |
| 1414 } | 1425 } |
| 1415 | 1426 |
| 1416 | 1427 |
| 1417 // Simple test if a node is side effect free. | 1428 // Simple test if a node is side effect free. |
| 1418 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { | 1429 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { |
| 1419 if (node->IsLiteralNode()) { | 1430 if (node->IsLiteralNode()) { |
| 1420 return true; | 1431 return true; |
| 1421 } | 1432 } |
| 1422 if (node->IsLoadLocalNode() && !node->AsLoadLocalNode()->HasPseudo()) { | 1433 if (node->IsLoadLocalNode() && !node->AsLoadLocalNode()->HasPseudo()) { |
| 1423 return true; | 1434 return true; |
| 1424 } | 1435 } |
| 1425 return false; | 1436 return false; |
| 1426 } | 1437 } |
| 1427 | 1438 |
| 1428 | 1439 |
| 1429 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { | 1440 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { |
| 1430 ASSERT(super->IsSuper()); | 1441 ASSERT(super->IsSuper()); |
| 1431 AstNode* super_op = NULL; | 1442 AstNode* super_op = NULL; |
| 1432 const intptr_t super_pos = super->token_pos(); | 1443 const intptr_t super_pos = super->token_pos(); |
| 1433 if ((op == Token::kNEGATE) || | 1444 if ((op == Token::kNEGATE) || |
| 1434 (op == Token::kBIT_NOT)) { | 1445 (op == Token::kBIT_NOT)) { |
| 1435 // Resolve the operator function in the superclass. | 1446 // Resolve the operator function in the superclass. |
| 1436 const String& operator_function_name = | 1447 const String& operator_function_name = |
| 1437 String::ZoneHandle(Symbols::New(Token::Str(op))); | 1448 String::ZoneHandle(Symbols::New(Token::Str(op))); |
| 1449 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); |
| 1450 AstNode* receiver = LoadReceiver(super_pos); |
| 1451 op_arguments->Add(receiver); |
| 1438 const bool kResolveGetter = false; | 1452 const bool kResolveGetter = false; |
| 1439 bool is_no_such_method = false; | 1453 bool is_no_such_method = false; |
| 1440 const Function& super_operator = Function::ZoneHandle( | 1454 const Function& super_operator = Function::ZoneHandle( |
| 1441 GetSuperFunction(super_pos, | 1455 GetSuperFunction(super_pos, |
| 1442 operator_function_name, | 1456 operator_function_name, |
| 1457 op_arguments, |
| 1443 kResolveGetter, | 1458 kResolveGetter, |
| 1444 &is_no_such_method)); | 1459 &is_no_such_method)); |
| 1445 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); | |
| 1446 AstNode* receiver = LoadReceiver(super_pos); | |
| 1447 op_arguments->Add(receiver); | |
| 1448 if (is_no_such_method) { | 1460 if (is_no_such_method) { |
| 1449 op_arguments = BuildNoSuchMethodArguments( | 1461 op_arguments = BuildNoSuchMethodArguments( |
| 1450 super_pos, operator_function_name, *op_arguments); | 1462 super_pos, operator_function_name, *op_arguments); |
| 1451 } | 1463 } |
| 1452 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); | 1464 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); |
| 1453 } else { | 1465 } else { |
| 1454 ErrorMsg(super_pos, "illegal super operator call"); | 1466 ErrorMsg(super_pos, "illegal super operator call"); |
| 1455 } | 1467 } |
| 1456 return super_op; | 1468 return super_op; |
| 1457 } | 1469 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1475 (CurrentToken() == Token::kNE)) { | 1487 (CurrentToken() == Token::kNE)) { |
| 1476 Token::Kind op = CurrentToken(); | 1488 Token::Kind op = CurrentToken(); |
| 1477 ConsumeToken(); | 1489 ConsumeToken(); |
| 1478 | 1490 |
| 1479 bool negate_result = false; | 1491 bool negate_result = false; |
| 1480 if (op == Token::kNE) { | 1492 if (op == Token::kNE) { |
| 1481 op = Token::kEQ; | 1493 op = Token::kEQ; |
| 1482 negate_result = true; | 1494 negate_result = true; |
| 1483 } | 1495 } |
| 1484 | 1496 |
| 1485 // Resolve the operator function in the superclass. | |
| 1486 const String& operator_function_name = | |
| 1487 String::Handle(Symbols::New(Token::Str(op))); | |
| 1488 const bool kResolveGetter = false; | |
| 1489 bool is_no_such_method = false; | |
| 1490 const Function& super_operator = Function::ZoneHandle( | |
| 1491 GetSuperFunction(operator_pos, | |
| 1492 operator_function_name, | |
| 1493 kResolveGetter, | |
| 1494 &is_no_such_method)); | |
| 1495 | |
| 1496 ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kBIT_OR)); | 1497 ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kBIT_OR)); |
| 1497 AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1); | 1498 AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1); |
| 1498 | 1499 |
| 1499 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos); | 1500 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos); |
| 1500 AstNode* receiver = LoadReceiver(operator_pos); | 1501 AstNode* receiver = LoadReceiver(operator_pos); |
| 1501 op_arguments->Add(receiver); | 1502 op_arguments->Add(receiver); |
| 1502 op_arguments->Add(other_operand); | 1503 op_arguments->Add(other_operand); |
| 1503 | 1504 |
| 1505 // Resolve the operator function in the superclass. |
| 1506 const String& operator_function_name = |
| 1507 String::ZoneHandle(Symbols::New(Token::Str(op))); |
| 1508 const bool kResolveGetter = false; |
| 1509 bool is_no_such_method = false; |
| 1510 const Function& super_operator = Function::ZoneHandle( |
| 1511 GetSuperFunction(operator_pos, |
| 1512 operator_function_name, |
| 1513 op_arguments, |
| 1514 kResolveGetter, |
| 1515 &is_no_such_method)); |
| 1504 if (is_no_such_method) { | 1516 if (is_no_such_method) { |
| 1505 op_arguments = BuildNoSuchMethodArguments( | 1517 op_arguments = BuildNoSuchMethodArguments( |
| 1506 operator_pos, operator_function_name, *op_arguments); | 1518 operator_pos, operator_function_name, *op_arguments); |
| 1507 } | 1519 } |
| 1508 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); | 1520 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); |
| 1509 if (negate_result) { | 1521 if (negate_result) { |
| 1510 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); | 1522 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); |
| 1511 } | 1523 } |
| 1512 } | 1524 } |
| 1513 return super_op; | 1525 return super_op; |
| 1514 } | 1526 } |
| 1515 | 1527 |
| 1516 | 1528 |
| 1517 AstNode* Parser::CreateImplicitClosureNode(const Function& func, | 1529 AstNode* Parser::CreateImplicitClosureNode(const Function& func, |
| 1518 intptr_t token_pos, | 1530 intptr_t token_pos, |
| 1519 AstNode* receiver) { | 1531 AstNode* receiver) { |
| 1520 Function& implicit_closure_function = | 1532 Function& implicit_closure_function = |
| 1521 Function::ZoneHandle(func.ImplicitClosureFunction()); | 1533 Function::ZoneHandle(func.ImplicitClosureFunction()); |
| 1522 if (receiver != NULL) { | 1534 if (receiver != NULL) { |
| 1523 // If we create an implicit instance closure from inside a closure of a | 1535 // If we create an implicit instance closure from inside a closure of a |
| 1524 // parameterized class, make sure that the receiver is captured as | 1536 // parameterized class, make sure that the receiver is captured as |
| 1525 // instantiator. | 1537 // instantiator. |
| 1526 if (current_block_->scope->function_level() > 0) { | 1538 if (current_block_->scope->function_level() > 0) { |
| 1527 const Class& signature_class = Class::Handle(func.signature_class()); | 1539 const Class& signature_class = Class::Handle( |
| 1540 implicit_closure_function.signature_class()); |
| 1528 if (signature_class.NumTypeParameters() > 0) { | 1541 if (signature_class.NumTypeParameters() > 0) { |
| 1529 CaptureInstantiator(); | 1542 CaptureInstantiator(); |
| 1530 } | 1543 } |
| 1531 } | 1544 } |
| 1532 } | 1545 } |
| 1533 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); | 1546 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); |
| 1534 } | 1547 } |
| 1535 | 1548 |
| 1536 | 1549 |
| 1537 AstNode* Parser::ParseSuperFieldAccess(const String& field_name) { | 1550 AstNode* Parser::ParseSuperFieldAccess(const String& field_name) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1558 field_pos, implicit_argument, true, super_class, field_name); | 1571 field_pos, implicit_argument, true, super_class, field_name); |
| 1559 } | 1572 } |
| 1560 } | 1573 } |
| 1561 if (super_getter.IsNull()) { | 1574 if (super_getter.IsNull()) { |
| 1562 // Check if this is an access to an implicit closure using 'super'. | 1575 // Check if this is an access to an implicit closure using 'super'. |
| 1563 // If a function exists of the specified field_name then try | 1576 // If a function exists of the specified field_name then try |
| 1564 // accessing it as a getter, at runtime we will handle this by | 1577 // accessing it as a getter, at runtime we will handle this by |
| 1565 // creating an implicit closure of the function and returning it. | 1578 // creating an implicit closure of the function and returning it. |
| 1566 const Function& super_function = Function::ZoneHandle( | 1579 const Function& super_function = Function::ZoneHandle( |
| 1567 Resolver::ResolveDynamicAnyArgs(super_class, field_name)); | 1580 Resolver::ResolveDynamicAnyArgs(super_class, field_name)); |
| 1568 if (super_function.IsNull()) { | 1581 if (!super_function.IsNull()) { |
| 1569 ErrorMsg(field_pos, "field or getter '%s' not found in superclass", | 1582 // In case CreateAssignmentNode is called later on this |
| 1570 field_name.ToCString()); | 1583 // CreateImplicitClosureNode, it will be replaced by a StaticSetterNode. |
| 1584 return CreateImplicitClosureNode(super_function, |
| 1585 field_pos, |
| 1586 implicit_argument); |
| 1571 } | 1587 } |
| 1572 return CreateImplicitClosureNode(super_function, | 1588 // No function or field exists of the specified field_name. |
| 1573 field_pos, | 1589 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called. |
| 1574 implicit_argument); | |
| 1575 } | 1590 } |
| 1576 | |
| 1577 return new StaticGetterNode( | 1591 return new StaticGetterNode( |
| 1578 field_pos, implicit_argument, true, super_class, field_name); | 1592 field_pos, implicit_argument, true, super_class, field_name); |
| 1579 } | 1593 } |
| 1580 | 1594 |
| 1581 | 1595 |
| 1582 void Parser::GenerateSuperConstructorCall(const Class& cls, | 1596 void Parser::GenerateSuperConstructorCall(const Class& cls, |
| 1583 LocalVariable* receiver) { | 1597 LocalVariable* receiver) { |
| 1584 const intptr_t supercall_pos = TokenPos(); | 1598 const intptr_t supercall_pos = TokenPos(); |
| 1585 const Class& super_class = Class::Handle(cls.SuperClass()); | 1599 const Class& super_class = Class::Handle(cls.SuperClass()); |
| 1586 // Omit the implicit super() if there is no super class (i.e. | 1600 // Omit the implicit super() if there is no super class (i.e. |
| (...skipping 5282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6869 *expr = right_node; | 6883 *expr = right_node; |
| 6870 return left_node; | 6884 return left_node; |
| 6871 } | 6885 } |
| 6872 return *expr; | 6886 return *expr; |
| 6873 } | 6887 } |
| 6874 | 6888 |
| 6875 | 6889 |
| 6876 // Ensure that the expression temp is allocated for nodes that may need it. | 6890 // Ensure that the expression temp is allocated for nodes that may need it. |
| 6877 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) { | 6891 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) { |
| 6878 AstNode* result = original->MakeAssignmentNode(rhs); | 6892 AstNode* result = original->MakeAssignmentNode(rhs); |
| 6879 if ((result == NULL) && original->IsStaticGetterNode()) { | |
| 6880 const String& setter_name = String::ZoneHandle( | |
| 6881 Field::SetterSymbol(original->AsStaticGetterNode()->field_name())); | |
| 6882 result = ThrowNoSuchMethodError(original->token_pos(), setter_name); | |
| 6883 } | |
| 6884 // TODO(hausner): if we decide to throw a no such method error on | |
| 6885 // assignment to a final variable, we need to do the same as in the | |
| 6886 // StaticGetterNode above. | |
| 6887 if ((result != NULL) && | 6893 if ((result != NULL) && |
| 6888 (result->IsStoreIndexedNode() || | 6894 (result->IsStoreIndexedNode() || |
| 6889 result->IsInstanceSetterNode() || | 6895 result->IsInstanceSetterNode() || |
| 6890 result->IsStaticSetterNode() || | 6896 result->IsStaticSetterNode() || |
| 6891 result->IsStoreStaticFieldNode() || | 6897 result->IsStoreStaticFieldNode() || |
| 6892 result->IsStoreLocalNode())) { | 6898 result->IsStoreLocalNode())) { |
| 6893 EnsureExpressionTemp(); | 6899 EnsureExpressionTemp(); |
| 6894 } | 6900 } |
| 6895 return result; | 6901 return result; |
| 6896 } | 6902 } |
| (...skipping 2797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9694 void Parser::SkipQualIdent() { | 9700 void Parser::SkipQualIdent() { |
| 9695 ASSERT(IsIdentifier()); | 9701 ASSERT(IsIdentifier()); |
| 9696 ConsumeToken(); | 9702 ConsumeToken(); |
| 9697 if (CurrentToken() == Token::kPERIOD) { | 9703 if (CurrentToken() == Token::kPERIOD) { |
| 9698 ConsumeToken(); // Consume the kPERIOD token. | 9704 ConsumeToken(); // Consume the kPERIOD token. |
| 9699 ExpectIdentifier("identifier expected after '.'"); | 9705 ExpectIdentifier("identifier expected after '.'"); |
| 9700 } | 9706 } |
| 9701 } | 9707 } |
| 9702 | 9708 |
| 9703 } // namespace dart | 9709 } // namespace dart |
| OLD | NEW |