| 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/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1211 return; | 1211 return; |
| 1212 } | 1212 } |
| 1213 | 1213 |
| 1214 | 1214 |
| 1215 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) { | 1215 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) { |
| 1216 const AbstractType& type = node->type(); | 1216 const AbstractType& type = node->type(); |
| 1217 // Type may be malbounded, but not malformed. | 1217 // Type may be malbounded, but not malformed. |
| 1218 ASSERT(type.IsFinalized() && !type.IsMalformed()); | 1218 ASSERT(type.IsFinalized() && !type.IsMalformed()); |
| 1219 if (type.IsInstantiated()) { | 1219 if (type.IsInstantiated()) { |
| 1220 ReturnDefinition(new (Z) ConstantInstr(type)); | 1220 ReturnDefinition(new (Z) ConstantInstr(type)); |
| 1221 return; |
| 1222 } |
| 1223 const TokenPosition token_pos = node->token_pos(); |
| 1224 Value* instantiator_type_arguments = NULL; |
| 1225 if (type.IsInstantiated(kClass)) { |
| 1226 instantiator_type_arguments = BuildNullValue(token_pos); |
| 1221 } else { | 1227 } else { |
| 1222 const Class& instantiator_class = | 1228 instantiator_type_arguments = BuildInstantiatorTypeArguments(token_pos); |
| 1223 Class::ZoneHandle(Z, owner()->function().Owner()); | |
| 1224 Value* instantiator_value = BuildInstantiatorTypeArguments( | |
| 1225 node->token_pos(), instantiator_class, NULL); | |
| 1226 ReturnDefinition(new (Z) InstantiateTypeInstr( | |
| 1227 node->token_pos(), type, instantiator_class, instantiator_value)); | |
| 1228 } | 1229 } |
| 1230 Value* function_type_arguments = NULL; |
| 1231 if (type.IsInstantiated(kCurrentFunction)) { |
| 1232 // TODO(regis): function_type_arguments = BuildNullValue((token_pos); |
| 1233 } else { |
| 1234 function_type_arguments = BuildFunctionTypeArguments(token_pos); |
| 1235 } |
| 1236 ReturnDefinition(new (Z) InstantiateTypeInstr( |
| 1237 token_pos, type, instantiator_type_arguments, function_type_arguments)); |
| 1229 } | 1238 } |
| 1230 | 1239 |
| 1231 | 1240 |
| 1232 // Returns true if the type check can be skipped, for example, if the | 1241 // Returns true if the type check can be skipped, for example, if the |
| 1233 // destination type is dynamic or if the compile type of the value is a subtype | 1242 // destination type is dynamic or if the compile type of the value is a subtype |
| 1234 // of the destination type. | 1243 // of the destination type. |
| 1235 bool EffectGraphVisitor::CanSkipTypeCheck(TokenPosition token_pos, | 1244 bool EffectGraphVisitor::CanSkipTypeCheck(TokenPosition token_pos, |
| 1236 Value* value, | 1245 Value* value, |
| 1237 const AbstractType& dst_type, | 1246 const AbstractType& dst_type, |
| 1238 const String& dst_name) { | 1247 const String& dst_name) { |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1397 Join(for_test, for_true, for_right); | 1406 Join(for_test, for_true, for_right); |
| 1398 } | 1407 } |
| 1399 ReturnDefinition(BuildLoadExprTemp(node->token_pos())); | 1408 ReturnDefinition(BuildLoadExprTemp(node->token_pos())); |
| 1400 return; | 1409 return; |
| 1401 } | 1410 } |
| 1402 | 1411 |
| 1403 EffectGraphVisitor::VisitBinaryOpNode(node); | 1412 EffectGraphVisitor::VisitBinaryOpNode(node); |
| 1404 } | 1413 } |
| 1405 | 1414 |
| 1406 | 1415 |
| 1407 void EffectGraphVisitor::BuildTypecheckPushArguments( | 1416 PushArgumentInstr* EffectGraphVisitor::PushInstantiatorTypeArguments( |
| 1408 TokenPosition token_pos, | 1417 const AbstractType& type, |
| 1409 PushArgumentInstr** push_instantiator_type_arguments_result) { | 1418 TokenPosition token_pos) { |
| 1410 const Class& instantiator_class = | 1419 if (type.IsInstantiated(kClass)) { |
| 1411 Class::Handle(Z, owner()->function().Owner()); | 1420 return PushArgument(BuildNullValue(token_pos)); |
| 1412 // Since called only when type tested against is not instantiated. | |
| 1413 ASSERT(instantiator_class.IsGeneric()); | |
| 1414 Value* instantiator_type_arguments = NULL; | |
| 1415 Value* instantiator = BuildInstantiator(token_pos); | |
| 1416 if (instantiator == NULL) { | |
| 1417 // No instantiator when inside factory. | |
| 1418 instantiator_type_arguments = | |
| 1419 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | |
| 1420 } else { | 1421 } else { |
| 1421 instantiator_type_arguments = BuildInstantiatorTypeArguments( | 1422 Value* instantiator_type_args = BuildInstantiatorTypeArguments(token_pos); |
| 1422 token_pos, instantiator_class, instantiator); | 1423 return PushArgument(instantiator_type_args); |
| 1423 } | 1424 } |
| 1424 *push_instantiator_type_arguments_result = | |
| 1425 PushArgument(instantiator_type_arguments); | |
| 1426 } | 1425 } |
| 1427 | 1426 |
| 1428 | 1427 |
| 1429 void EffectGraphVisitor::BuildTypecheckArguments( | 1428 PushArgumentInstr* EffectGraphVisitor::PushFunctionTypeArguments( |
| 1430 TokenPosition token_pos, | 1429 const AbstractType& type, |
| 1431 Value** instantiator_type_arguments_result) { | 1430 TokenPosition token_pos) { |
| 1432 Value* instantiator = NULL; | 1431 if (type.IsInstantiated(kCurrentFunction)) { |
| 1433 Value* instantiator_type_arguments = NULL; | 1432 return PushArgument(BuildNullValue(token_pos)); |
| 1434 const Class& instantiator_class = | |
| 1435 Class::Handle(Z, owner()->function().Owner()); | |
| 1436 // Since called only when type tested against is not instantiated. | |
| 1437 ASSERT(instantiator_class.IsGeneric()); | |
| 1438 instantiator = BuildInstantiator(token_pos); | |
| 1439 if (instantiator == NULL) { | |
| 1440 // No instantiator when inside factory. | |
| 1441 instantiator_type_arguments = | |
| 1442 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | |
| 1443 } else { | 1433 } else { |
| 1444 instantiator_type_arguments = BuildInstantiatorTypeArguments( | 1434 Value* function_type_args = BuildFunctionTypeArguments(token_pos); |
| 1445 token_pos, instantiator_class, instantiator); | 1435 return PushArgument(function_type_args); |
| 1446 } | 1436 } |
| 1447 *instantiator_type_arguments_result = instantiator_type_arguments; | |
| 1448 } | 1437 } |
| 1449 | 1438 |
| 1450 | 1439 |
| 1451 Value* EffectGraphVisitor::BuildNullValue(TokenPosition token_pos) { | 1440 Value* EffectGraphVisitor::BuildNullValue(TokenPosition token_pos) { |
| 1452 return Bind( | 1441 return Bind( |
| 1453 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()), token_pos)); | 1442 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()), token_pos)); |
| 1454 } | 1443 } |
| 1455 | 1444 |
| 1456 | 1445 |
| 1457 // Used for testing incoming arguments. | 1446 // Used for testing incoming arguments. |
| 1458 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( | 1447 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( |
| 1459 TokenPosition token_pos, | 1448 TokenPosition token_pos, |
| 1460 Value* value, | 1449 Value* value, |
| 1461 const AbstractType& dst_type, | 1450 const AbstractType& dst_type, |
| 1462 const String& dst_name) { | 1451 const String& dst_name) { |
| 1463 // Build the type check computation. | 1452 // Build the type check computation. |
| 1464 Value* instantiator_type_arguments = NULL; | 1453 Value* instantiator_type_arguments = NULL; |
| 1465 if (dst_type.IsInstantiated()) { | 1454 Value* function_type_arguments = NULL; |
| 1455 if (dst_type.IsInstantiated(kClass)) { |
| 1466 instantiator_type_arguments = BuildNullValue(token_pos); | 1456 instantiator_type_arguments = BuildNullValue(token_pos); |
| 1467 } else { | 1457 } else { |
| 1468 BuildTypecheckArguments(token_pos, &instantiator_type_arguments); | 1458 instantiator_type_arguments = BuildInstantiatorTypeArguments(token_pos); |
| 1459 } |
| 1460 if (dst_type.IsInstantiated(kCurrentFunction)) { |
| 1461 // TODO(regis): function_type_arguments = BuildNullValue(token_pos); |
| 1462 } else { |
| 1463 function_type_arguments = BuildFunctionTypeArguments(token_pos); |
| 1469 } | 1464 } |
| 1470 | 1465 |
| 1471 const intptr_t deopt_id = Thread::Current()->GetNextDeoptId(); | 1466 const intptr_t deopt_id = Thread::Current()->GetNextDeoptId(); |
| 1472 return new (Z) | 1467 return new (Z) AssertAssignableInstr( |
| 1473 AssertAssignableInstr(token_pos, value, instantiator_type_arguments, | 1468 token_pos, value, instantiator_type_arguments, function_type_arguments, |
| 1474 dst_type, dst_name, deopt_id); | 1469 dst_type, dst_name, deopt_id); |
| 1475 } | 1470 } |
| 1476 | 1471 |
| 1477 | 1472 |
| 1478 // Used for type casts and to test assignments. | 1473 // Used for type casts and to test assignments. |
| 1479 Value* EffectGraphVisitor::BuildAssignableValue(TokenPosition token_pos, | 1474 Value* EffectGraphVisitor::BuildAssignableValue(TokenPosition token_pos, |
| 1480 Value* value, | 1475 Value* value, |
| 1481 const AbstractType& dst_type, | 1476 const AbstractType& dst_type, |
| 1482 const String& dst_name) { | 1477 const String& dst_name) { |
| 1483 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { | 1478 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { |
| 1484 return value; | 1479 return value; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1521 return; | 1516 return; |
| 1522 } | 1517 } |
| 1523 ValueGraphVisitor for_left_value(owner()); | 1518 ValueGraphVisitor for_left_value(owner()); |
| 1524 node->left()->Visit(&for_left_value); | 1519 node->left()->Visit(&for_left_value); |
| 1525 Append(for_left_value); | 1520 Append(for_left_value); |
| 1526 | 1521 |
| 1527 // We now know type is a real class (!num, !int, !smi, !string) | 1522 // We now know type is a real class (!num, !int, !smi, !string) |
| 1528 // and the type check could NOT be removed at compile time. | 1523 // and the type check could NOT be removed at compile time. |
| 1529 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 1524 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
| 1530 if (simpleInstanceOfType(type)) { | 1525 if (simpleInstanceOfType(type)) { |
| 1531 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); | |
| 1532 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1526 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1533 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2); | 1527 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1534 arguments->Add(push_left); | 1528 arguments->Add(push_left); |
| 1535 Value* type_const = Bind(new (Z) ConstantInstr(type)); | 1529 Value* type_const = Bind(new (Z) ConstantInstr(type)); |
| 1536 arguments->Add(PushArgument(type_const)); | 1530 arguments->Add(PushArgument(type_const)); |
| 1537 const intptr_t kNumArgsChecked = 2; | 1531 const intptr_t kNumArgsChecked = 2; |
| 1538 Definition* result = new (Z) InstanceCallInstr( | 1532 Definition* result = new (Z) InstanceCallInstr( |
| 1539 node->token_pos(), | 1533 node->token_pos(), |
| 1540 Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()), node->kind(), | 1534 Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()), node->kind(), |
| 1541 arguments, | 1535 arguments, |
| 1542 Object::null_array(), // No argument names. | 1536 Object::null_array(), // No argument names. |
| 1543 kNumArgsChecked, owner()->ic_data_array()); | 1537 kNumArgsChecked, owner()->ic_data_array()); |
| 1544 if (negate_result) { | 1538 if (negate_result) { |
| 1545 result = new (Z) BooleanNegateInstr(Bind(result)); | 1539 result = new (Z) BooleanNegateInstr(Bind(result)); |
| 1546 } | 1540 } |
| 1547 ReturnDefinition(result); | 1541 ReturnDefinition(result); |
| 1548 return; | 1542 return; |
| 1549 } | 1543 } |
| 1550 | 1544 |
| 1551 PushArgumentInstr* push_type_args = NULL; | 1545 PushArgumentInstr* push_instantiator_type_args = |
| 1552 if (type.IsInstantiated()) { | 1546 PushInstantiatorTypeArguments(type, node->token_pos()); |
| 1553 push_type_args = PushArgument(BuildNullValue(node->token_pos())); | 1547 // TODO(regis): PushArgumentInstr* push_function_type_args = |
| 1554 } else { | 1548 // PushFunctionTypeArguments(type, node->token_pos()); |
| 1555 BuildTypecheckPushArguments(node->token_pos(), &push_type_args); | |
| 1556 } | |
| 1557 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1549 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1558 new (Z) ZoneGrowableArray<PushArgumentInstr*>(3); | 1550 new (Z) ZoneGrowableArray<PushArgumentInstr*>(3); |
| 1559 arguments->Add(push_left); | 1551 arguments->Add(push_left); |
| 1560 arguments->Add(push_type_args); | 1552 arguments->Add(push_instantiator_type_args); |
| 1561 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); | 1553 // TODO(regis): arguments->Add(push_function_type_args); |
| 1562 Value* type_const = Bind(new (Z) ConstantInstr(type)); | 1554 Value* type_const = Bind(new (Z) ConstantInstr(type)); |
| 1563 arguments->Add(PushArgument(type_const)); | 1555 arguments->Add(PushArgument(type_const)); |
| 1564 const intptr_t kNumArgsChecked = 1; | 1556 const intptr_t kNumArgsChecked = 1; |
| 1565 Definition* result = new (Z) InstanceCallInstr( | 1557 Definition* result = new (Z) InstanceCallInstr( |
| 1566 node->token_pos(), Library::PrivateCoreLibName(Symbols::_instanceOf()), | 1558 node->token_pos(), Library::PrivateCoreLibName(Symbols::_instanceOf()), |
| 1567 node->kind(), arguments, | 1559 node->kind(), arguments, |
| 1568 Object::null_array(), // No argument names. | 1560 Object::null_array(), // No argument names. |
| 1569 kNumArgsChecked, owner()->ic_data_array()); | 1561 kNumArgsChecked, owner()->ic_data_array()); |
| 1570 if (negate_result) { | 1562 if (negate_result) { |
| 1571 result = new (Z) BooleanNegateInstr(Bind(result)); | 1563 result = new (Z) BooleanNegateInstr(Bind(result)); |
| 1572 } | 1564 } |
| 1573 ReturnDefinition(result); | 1565 ReturnDefinition(result); |
| 1574 } | 1566 } |
| 1575 | 1567 |
| 1576 | 1568 |
| 1577 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 1569 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| 1578 ASSERT(Token::IsTypeCastOperator(node->kind())); | 1570 ASSERT(Token::IsTypeCastOperator(node->kind())); |
| 1579 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); | 1571 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); |
| 1580 const AbstractType& type = node->right()->AsTypeNode()->type(); | 1572 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 1581 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); | 1573 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); |
| 1582 ValueGraphVisitor for_value(owner()); | 1574 ValueGraphVisitor for_value(owner()); |
| 1583 node->left()->Visit(&for_value); | 1575 node->left()->Visit(&for_value); |
| 1584 Append(for_value); | 1576 Append(for_value); |
| 1585 if (CanSkipTypeCheck(node->token_pos(), for_value.value(), type, | 1577 if (CanSkipTypeCheck(node->token_pos(), for_value.value(), type, |
| 1586 Symbols::InTypeCast())) { | 1578 Symbols::InTypeCast())) { |
| 1587 ReturnValue(for_value.value()); | 1579 ReturnValue(for_value.value()); |
| 1588 return; | 1580 return; |
| 1589 } | 1581 } |
| 1590 PushArgumentInstr* push_left = PushArgument(for_value.value()); | 1582 PushArgumentInstr* push_left = PushArgument(for_value.value()); |
| 1591 PushArgumentInstr* push_type_args = NULL; | 1583 PushArgumentInstr* push_instantiator_type_args = |
| 1592 if (type.IsInstantiated()) { | 1584 PushInstantiatorTypeArguments(type, node->token_pos()); |
| 1593 push_type_args = PushArgument(BuildNullValue(node->token_pos())); | 1585 // TODO(regis): PushArgumentInstr* push_function_type_args = |
| 1594 } else { | 1586 // PushFunctionTypeArguments(type, node->token_pos()); |
| 1595 BuildTypecheckPushArguments(node->token_pos(), &push_type_args); | |
| 1596 } | |
| 1597 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1587 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1598 new (Z) ZoneGrowableArray<PushArgumentInstr*>(3); | 1588 new (Z) ZoneGrowableArray<PushArgumentInstr*>(3); |
| 1599 arguments->Add(push_left); | 1589 arguments->Add(push_left); |
| 1600 arguments->Add(push_type_args); | 1590 arguments->Add(push_instantiator_type_args); |
| 1591 // TODO(regis): arguments->Add(push_function_type_args); |
| 1601 Value* type_arg = Bind(new (Z) ConstantInstr(type)); | 1592 Value* type_arg = Bind(new (Z) ConstantInstr(type)); |
| 1602 arguments->Add(PushArgument(type_arg)); | 1593 arguments->Add(PushArgument(type_arg)); |
| 1603 const intptr_t kNumArgsChecked = 1; | 1594 const intptr_t kNumArgsChecked = 1; |
| 1604 InstanceCallInstr* call = new (Z) InstanceCallInstr( | 1595 InstanceCallInstr* call = new (Z) InstanceCallInstr( |
| 1605 node->token_pos(), Library::PrivateCoreLibName(Symbols::_as()), | 1596 node->token_pos(), Library::PrivateCoreLibName(Symbols::_as()), |
| 1606 node->kind(), arguments, | 1597 node->kind(), arguments, |
| 1607 Object::null_array(), // No argument names. | 1598 Object::null_array(), // No argument names. |
| 1608 kNumArgsChecked, owner()->ic_data_array()); | 1599 kNumArgsChecked, owner()->ic_data_array()); |
| 1609 ReturnDefinition(call); | 1600 ReturnDefinition(call); |
| 1610 } | 1601 } |
| (...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2365 Value* closure_val = Bind(alloc); | 2356 Value* closure_val = Bind(alloc); |
| 2366 { | 2357 { |
| 2367 LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val); | 2358 LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val); |
| 2368 // Store instantiator type arguments if scope class is generic. | 2359 // Store instantiator type arguments if scope class is generic. |
| 2369 const Type& function_type = Type::ZoneHandle(Z, function.SignatureType()); | 2360 const Type& function_type = Type::ZoneHandle(Z, function.SignatureType()); |
| 2370 const Class& scope_cls = Class::ZoneHandle(Z, function_type.type_class()); | 2361 const Class& scope_cls = Class::ZoneHandle(Z, function_type.type_class()); |
| 2371 if (scope_cls.IsGeneric()) { | 2362 if (scope_cls.IsGeneric()) { |
| 2372 ASSERT(function.Owner() == scope_cls.raw()); | 2363 ASSERT(function.Owner() == scope_cls.raw()); |
| 2373 Value* closure_tmp_val = | 2364 Value* closure_tmp_val = |
| 2374 Bind(new (Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); | 2365 Bind(new (Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); |
| 2375 const Class& instantiator_class = | 2366 Value* type_arguments = BuildInstantiatorTypeArguments(node->token_pos()); |
| 2376 Class::Handle(Z, owner()->function().Owner()); | |
| 2377 Value* type_arguments = BuildInstantiatorTypeArguments( | |
| 2378 node->token_pos(), instantiator_class, NULL); | |
| 2379 Do(new (Z) StoreInstanceFieldInstr(Closure::instantiator_offset(), | 2367 Do(new (Z) StoreInstanceFieldInstr(Closure::instantiator_offset(), |
| 2380 closure_tmp_val, type_arguments, | 2368 closure_tmp_val, type_arguments, |
| 2381 kEmitStoreBarrier, node->token_pos())); | 2369 kEmitStoreBarrier, node->token_pos())); |
| 2382 } | 2370 } |
| 2383 | 2371 |
| 2384 // Store function. | 2372 // Store function. |
| 2385 Value* closure_tmp_val = | 2373 Value* closure_tmp_val = |
| 2386 Bind(new (Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); | 2374 Bind(new (Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); |
| 2387 Value* func_val = | 2375 Value* func_val = |
| 2388 Bind(new (Z) ConstantInstr(Function::ZoneHandle(Z, function.raw()))); | 2376 Bind(new (Z) ConstantInstr(Function::ZoneHandle(Z, function.raw()))); |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2691 return NULL; | 2679 return NULL; |
| 2692 } | 2680 } |
| 2693 | 2681 |
| 2694 LocalVariable* instantiator = owner()->parsed_function().instantiator(); | 2682 LocalVariable* instantiator = owner()->parsed_function().instantiator(); |
| 2695 ASSERT(instantiator != NULL); | 2683 ASSERT(instantiator != NULL); |
| 2696 Value* result = Bind(BuildLoadLocal(*instantiator, token_pos)); | 2684 Value* result = Bind(BuildLoadLocal(*instantiator, token_pos)); |
| 2697 return result; | 2685 return result; |
| 2698 } | 2686 } |
| 2699 | 2687 |
| 2700 | 2688 |
| 2701 // 'expression_temp_var' may not be used inside this method if 'instantiator' | |
| 2702 // is not NULL. | |
| 2703 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | 2689 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
| 2704 TokenPosition token_pos, | 2690 TokenPosition token_pos) { |
| 2705 const Class& instantiator_class, | 2691 const Class& instantiator_class = |
| 2706 Value* instantiator) { | 2692 Class::Handle(Z, owner()->function().Owner()); |
| 2707 if (!instantiator_class.IsGeneric()) { | 2693 if (!instantiator_class.IsGeneric()) { |
| 2708 // The type arguments are compile time constants. | 2694 // The type arguments are compile time constants. |
| 2709 TypeArguments& type_arguments = | 2695 TypeArguments& type_arguments = |
| 2710 TypeArguments::ZoneHandle(Z, TypeArguments::null()); | 2696 TypeArguments::ZoneHandle(Z, TypeArguments::null()); |
| 2711 // Type is temporary. Only its type arguments are preserved. | 2697 // Type is temporary. Only its type arguments are preserved. |
| 2712 Type& type = Type::Handle(Z, Type::New(instantiator_class, type_arguments, | 2698 Type& type = Type::Handle(Z, Type::New(instantiator_class, type_arguments, |
| 2713 token_pos, Heap::kNew)); | 2699 token_pos, Heap::kNew)); |
| 2714 type ^= ClassFinalizer::FinalizeType(instantiator_class, type, | 2700 type ^= ClassFinalizer::FinalizeType(instantiator_class, type, |
| 2715 ClassFinalizer::kFinalize); | 2701 ClassFinalizer::kFinalize); |
| 2716 ASSERT(!type.IsMalformedOrMalbounded()); | 2702 ASSERT(!type.IsMalformedOrMalbounded()); |
| 2717 type_arguments = type.arguments(); | 2703 type_arguments = type.arguments(); |
| 2718 type_arguments = type_arguments.Canonicalize(); | 2704 type_arguments = type_arguments.Canonicalize(); |
| 2719 return Bind(new (Z) ConstantInstr(type_arguments)); | 2705 return Bind(new (Z) ConstantInstr(type_arguments)); |
| 2720 } | 2706 } |
| 2721 Function& outer_function = Function::Handle(Z, owner()->function().raw()); | 2707 Function& outer_function = Function::Handle(Z, owner()->function().raw()); |
| 2722 while (outer_function.IsLocalFunction()) { | 2708 while (outer_function.IsLocalFunction()) { |
| 2723 outer_function = outer_function.parent_function(); | 2709 outer_function = outer_function.parent_function(); |
| 2724 } | 2710 } |
| 2725 if (outer_function.IsFactory()) { | 2711 if (outer_function.IsFactory()) { |
| 2726 // No instantiator for factories. | 2712 // Note that in the factory case, the instantiator is the first parameter |
| 2727 ASSERT(instantiator == NULL); | 2713 // of the factory, i.e. already a TypeArguments object. |
| 2728 LocalVariable* instantiator_var = owner()->parsed_function().instantiator(); | 2714 LocalVariable* instantiator_var = owner()->parsed_function().instantiator(); |
| 2729 ASSERT(instantiator_var != NULL); | 2715 ASSERT(instantiator_var != NULL); |
| 2730 return Bind(BuildLoadLocal(*instantiator_var, token_pos)); | 2716 return Bind(BuildLoadLocal(*instantiator_var, token_pos)); |
| 2731 } | 2717 } |
| 2732 if (instantiator == NULL) { | |
| 2733 instantiator = BuildInstantiator(token_pos); | |
| 2734 } | |
| 2735 // The instantiator is the receiver of the caller, which is not a factory. | 2718 // The instantiator is the receiver of the caller, which is not a factory. |
| 2736 // The receiver cannot be null; extract its TypeArguments object. | 2719 // The receiver cannot be null; extract its TypeArguments object. |
| 2737 // Note that in the factory case, the instantiator is the first parameter | 2720 Value* instantiator = BuildInstantiator(token_pos); |
| 2738 // of the factory, i.e. already a TypeArguments object. | |
| 2739 intptr_t type_arguments_field_offset = | 2721 intptr_t type_arguments_field_offset = |
| 2740 instantiator_class.type_arguments_field_offset(); | 2722 instantiator_class.type_arguments_field_offset(); |
| 2741 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); | 2723 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); |
| 2742 | 2724 |
| 2743 return Bind(new (Z) LoadFieldInstr( | 2725 return Bind(new (Z) LoadFieldInstr( |
| 2744 instantiator, type_arguments_field_offset, | 2726 instantiator, type_arguments_field_offset, |
| 2745 Type::ZoneHandle(Z, Type::null()), // Not an instance, no type. | 2727 Type::ZoneHandle(Z, Type::null()), // Not an instance, no type. |
| 2746 token_pos)); | 2728 token_pos)); |
| 2747 } | 2729 } |
| 2748 | 2730 |
| 2749 | 2731 |
| 2732 Value* EffectGraphVisitor::BuildFunctionTypeArguments(TokenPosition token_pos) { |
| 2733 UNIMPLEMENTED(); |
| 2734 return NULL; |
| 2735 } |
| 2736 |
| 2737 |
| 2750 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( | 2738 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( |
| 2751 TokenPosition token_pos, | 2739 TokenPosition token_pos, |
| 2752 const TypeArguments& type_arguments) { | 2740 const TypeArguments& type_arguments) { |
| 2753 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { | 2741 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { |
| 2754 return Bind(new (Z) ConstantInstr(type_arguments)); | 2742 return Bind(new (Z) ConstantInstr(type_arguments)); |
| 2755 } | 2743 } |
| 2756 // The type arguments are uninstantiated. | 2744 // The type arguments are uninstantiated. |
| 2757 const Class& instantiator_class = | 2745 const Class& instantiator_class = |
| 2758 Class::ZoneHandle(Z, owner()->function().Owner()); | 2746 Class::ZoneHandle(Z, owner()->function().Owner()); |
| 2759 Value* instantiator_value = | 2747 Value* instantiator_type_args = BuildInstantiatorTypeArguments(token_pos); |
| 2760 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | |
| 2761 const bool use_instantiator_type_args = | 2748 const bool use_instantiator_type_args = |
| 2762 type_arguments.IsUninstantiatedIdentity() || | 2749 type_arguments.IsUninstantiatedIdentity() || |
| 2763 type_arguments.CanShareInstantiatorTypeArguments(instantiator_class); | 2750 type_arguments.CanShareInstantiatorTypeArguments(instantiator_class); |
| 2764 if (use_instantiator_type_args) { | 2751 if (use_instantiator_type_args) { |
| 2765 return instantiator_value; | 2752 return instantiator_type_args; |
| 2753 } |
| 2754 Value* function_type_args = NULL; |
| 2755 if (type_arguments.IsInstantiated(kCurrentFunction)) { |
| 2756 // TODO(regis): function_type_args = BuildNullValue(token_pos); |
| 2766 } else { | 2757 } else { |
| 2767 return Bind(new (Z) InstantiateTypeArgumentsInstr( | 2758 function_type_args = BuildFunctionTypeArguments(token_pos); |
| 2768 token_pos, type_arguments, instantiator_class, instantiator_value)); | |
| 2769 } | 2759 } |
| 2760 return Bind(new (Z) InstantiateTypeArgumentsInstr( |
| 2761 token_pos, type_arguments, instantiator_class, instantiator_type_args, |
| 2762 function_type_args)); |
| 2770 } | 2763 } |
| 2771 | 2764 |
| 2772 | 2765 |
| 2773 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 2766 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 2774 if (node->constructor().IsFactory()) { | 2767 if (node->constructor().IsFactory()) { |
| 2775 EffectGraphVisitor::VisitConstructorCallNode(node); | 2768 EffectGraphVisitor::VisitConstructorCallNode(node); |
| 2776 return; | 2769 return; |
| 2777 } | 2770 } |
| 2778 | 2771 |
| 2779 // t_n contains the allocated and initialized object. | 2772 // t_n contains the allocated and initialized object. |
| (...skipping 1577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4357 graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, block_marks); | 4350 graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, block_marks); |
| 4358 ASSERT(found); | 4351 ASSERT(found); |
| 4359 } | 4352 } |
| 4360 | 4353 |
| 4361 | 4354 |
| 4362 void FlowGraphBuilder::Bailout(const char* reason) const { | 4355 void FlowGraphBuilder::Bailout(const char* reason) const { |
| 4363 parsed_function_.Bailout("FlowGraphBuilder", reason); | 4356 parsed_function_.Bailout("FlowGraphBuilder", reason); |
| 4364 } | 4357 } |
| 4365 | 4358 |
| 4366 } // namespace dart | 4359 } // namespace dart |
| OLD | NEW |