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 1320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1331 } else { | 1331 } else { |
1332 EffectGraphVisitor for_right(owner()); | 1332 EffectGraphVisitor for_right(owner()); |
1333 node->right()->Visit(&for_right); | 1333 node->right()->Visit(&for_right); |
1334 if (node->kind() == Token::kAND) { | 1334 if (node->kind() == Token::kAND) { |
1335 Join(for_left, for_right, empty); | 1335 Join(for_left, for_right, empty); |
1336 } else { | 1336 } else { |
1337 Join(for_left, empty, for_right); | 1337 Join(for_left, empty, for_right); |
1338 } | 1338 } |
1339 } | 1339 } |
1340 return; | 1340 return; |
1341 } else if (node->kind() == Token::kIFNULL) { | |
1342 // left ?? right. This operation cannot be overloaded. | |
1343 // temp = left; temp === null ? right : temp | |
1344 ValueGraphVisitor for_left_value(owner()); | |
1345 node->left()->Visit(&for_left_value); | |
1346 Append(for_left_value); | |
1347 Do(BuildStoreExprTemp(for_left_value.value())); | |
1348 | |
1349 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); | |
1350 LoadLocalNode* load_temp = | |
1351 new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var); | |
1352 LiteralNode* null_constant = | |
1353 new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance()); | |
1354 ComparisonNode* check_is_null = | |
1355 new(Z) ComparisonNode(Scanner::kNoSourcePos, | |
1356 Token::kEQ_STRICT, | |
1357 load_temp, | |
1358 null_constant); | |
1359 TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos); | |
1360 check_is_null->Visit(&for_test); | |
1361 | |
1362 ValueGraphVisitor for_right_value(owner()); | |
1363 node->right()->Visit(&for_right_value); | |
1364 for_right_value.Do(BuildStoreExprTemp(for_right_value.value())); | |
1365 | |
1366 ValueGraphVisitor for_temp(owner()); | |
1367 // Nothing to do, left value is already loaded into temp. | |
1368 | |
1369 Join(for_test, for_right_value, for_temp); | |
1370 return; | |
1371 } | 1341 } |
| 1342 ASSERT(node->kind() != Token::kIFNULL); |
1372 ValueGraphVisitor for_left_value(owner()); | 1343 ValueGraphVisitor for_left_value(owner()); |
1373 node->left()->Visit(&for_left_value); | 1344 node->left()->Visit(&for_left_value); |
1374 Append(for_left_value); | 1345 Append(for_left_value); |
1375 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 1346 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
1376 | 1347 |
1377 ValueGraphVisitor for_right_value(owner()); | 1348 ValueGraphVisitor for_right_value(owner()); |
1378 node->right()->Visit(&for_right_value); | 1349 node->right()->Visit(&for_right_value); |
1379 Append(for_right_value); | 1350 Append(for_right_value); |
1380 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 1351 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
1381 | 1352 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1435 Join(for_test, for_right, for_false); | 1406 Join(for_test, for_right, for_false); |
1436 } else { | 1407 } else { |
1437 ASSERT(node->kind() == Token::kOR); | 1408 ASSERT(node->kind() == Token::kOR); |
1438 ValueGraphVisitor for_true(owner()); | 1409 ValueGraphVisitor for_true(owner()); |
1439 Value* constant_true = for_true.Bind(new(Z) ConstantInstr(Bool::True())); | 1410 Value* constant_true = for_true.Bind(new(Z) ConstantInstr(Bool::True())); |
1440 for_true.Do(BuildStoreExprTemp(constant_true)); | 1411 for_true.Do(BuildStoreExprTemp(constant_true)); |
1441 Join(for_test, for_true, for_right); | 1412 Join(for_test, for_true, for_right); |
1442 } | 1413 } |
1443 ReturnDefinition(BuildLoadExprTemp()); | 1414 ReturnDefinition(BuildLoadExprTemp()); |
1444 return; | 1415 return; |
1445 } else if (node->kind() == Token::kIFNULL) { | |
1446 // left ?? right. This operation cannot be overloaded. | |
1447 // temp = left; temp === null ? right : temp | |
1448 ValueGraphVisitor for_left_value(owner()); | |
1449 node->left()->Visit(&for_left_value); | |
1450 Append(for_left_value); | |
1451 Do(BuildStoreExprTemp(for_left_value.value())); | |
1452 | |
1453 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); | |
1454 LoadLocalNode* load_temp = | |
1455 new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var); | |
1456 LiteralNode* null_constant = | |
1457 new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance()); | |
1458 ComparisonNode* check_is_null = | |
1459 new(Z) ComparisonNode(Scanner::kNoSourcePos, | |
1460 Token::kEQ_STRICT, | |
1461 load_temp, | |
1462 null_constant); | |
1463 TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos); | |
1464 check_is_null->Visit(&for_test); | |
1465 | |
1466 ValueGraphVisitor for_right_value(owner()); | |
1467 node->right()->Visit(&for_right_value); | |
1468 for_right_value.Do(BuildStoreExprTemp(for_right_value.value())); | |
1469 | |
1470 ValueGraphVisitor for_temp(owner()); | |
1471 // Nothing to do, left value is already loaded into temp. | |
1472 | |
1473 Join(for_test, for_right_value, for_temp); | |
1474 ReturnDefinition(BuildLoadExprTemp()); | |
1475 return; | |
1476 } | 1416 } |
1477 | 1417 |
1478 EffectGraphVisitor::VisitBinaryOpNode(node); | 1418 EffectGraphVisitor::VisitBinaryOpNode(node); |
1479 } | 1419 } |
1480 | 1420 |
1481 | 1421 |
1482 static const String& BinaryOpAndMaskName(BinaryOpNode* node) { | 1422 static const String& BinaryOpAndMaskName(BinaryOpNode* node) { |
1483 if (node->kind() == Token::kSHL) { | 1423 if (node->kind() == Token::kSHL) { |
1484 return Library::PrivateCoreLibName(Symbols::_leftShiftWithMask32()); | 1424 return Library::PrivateCoreLibName(Symbols::_leftShiftWithMask32()); |
1485 } | 1425 } |
(...skipping 3187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4673 Report::MessageF(Report::kBailout, | 4613 Report::MessageF(Report::kBailout, |
4674 Script::Handle(function.script()), | 4614 Script::Handle(function.script()), |
4675 function.token_pos(), | 4615 function.token_pos(), |
4676 "FlowGraphBuilder Bailout: %s %s", | 4616 "FlowGraphBuilder Bailout: %s %s", |
4677 String::Handle(function.name()).ToCString(), | 4617 String::Handle(function.name()).ToCString(), |
4678 reason); | 4618 reason); |
4679 UNREACHABLE(); | 4619 UNREACHABLE(); |
4680 } | 4620 } |
4681 | 4621 |
4682 } // namespace dart | 4622 } // namespace dart |
OLD | NEW |