OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/interpreter/bytecode-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/interpreter/control-flow-builders.h" | 8 #include "src/interpreter/control-flow-builders.h" |
9 #include "src/objects.h" | 9 #include "src/objects.h" |
10 #include "src/parser.h" | 10 #include "src/parser.h" |
(...skipping 1405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1416 switch (expr->op()) { | 1416 switch (expr->op()) { |
1417 case Token::Value::NOT: | 1417 case Token::Value::NOT: |
1418 VisitNot(expr); | 1418 VisitNot(expr); |
1419 break; | 1419 break; |
1420 case Token::Value::TYPEOF: | 1420 case Token::Value::TYPEOF: |
1421 VisitTypeOf(expr); | 1421 VisitTypeOf(expr); |
1422 break; | 1422 break; |
1423 case Token::Value::VOID: | 1423 case Token::Value::VOID: |
1424 VisitVoid(expr); | 1424 VisitVoid(expr); |
1425 break; | 1425 break; |
| 1426 case Token::Value::DELETE: |
| 1427 VisitDelete(expr); |
| 1428 break; |
1426 case Token::Value::BIT_NOT: | 1429 case Token::Value::BIT_NOT: |
1427 case Token::Value::DELETE: | 1430 case Token::Value::ADD: |
1428 UNIMPLEMENTED(); | 1431 case Token::Value::SUB: |
| 1432 // These operators are converted to an equivalent binary operators in |
| 1433 // the parser. These operators are not expected to be visited here. |
| 1434 UNREACHABLE(); |
1429 default: | 1435 default: |
1430 UNREACHABLE(); | 1436 UNREACHABLE(); |
1431 } | 1437 } |
1432 } | 1438 } |
1433 | 1439 |
1434 | 1440 |
| 1441 void BytecodeGenerator::VisitDelete(UnaryOperation* expr) { |
| 1442 if (expr->expression()->IsProperty()) { |
| 1443 // Delete of an object property is allowed both in sloppy |
| 1444 // and strict modes. |
| 1445 Property* property = expr->expression()->AsProperty(); |
| 1446 Register object = VisitForRegisterValue(property->obj()); |
| 1447 VisitForAccumulatorValue(property->key()); |
| 1448 builder()->Delete(object, language_mode()); |
| 1449 } else if (expr->expression()->IsVariableProxy()) { |
| 1450 // Delete of an unqualified identifier is allowed in sloppy mode but is |
| 1451 // not allowed in strict mode. Deleting 'this' is allowed in both modes. |
| 1452 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 1453 Variable* variable = proxy->var(); |
| 1454 DCHECK(is_sloppy(language_mode()) || variable->HasThisName(isolate())); |
| 1455 switch (variable->location()) { |
| 1456 case VariableLocation::GLOBAL: |
| 1457 case VariableLocation::UNALLOCATED: { |
| 1458 // Global var, let, const or variables not explicitly declared. |
| 1459 Register global_object = execution_result()->NewRegister(); |
| 1460 builder() |
| 1461 ->LoadContextSlot(execution_context()->reg(), |
| 1462 Context::GLOBAL_OBJECT_INDEX) |
| 1463 .StoreAccumulatorInRegister(global_object) |
| 1464 .LoadLiteral(variable->name()) |
| 1465 .Delete(global_object, language_mode()); |
| 1466 break; |
| 1467 } |
| 1468 case VariableLocation::PARAMETER: |
| 1469 case VariableLocation::LOCAL: |
| 1470 case VariableLocation::CONTEXT: { |
| 1471 // Deleting local var/let/const, context variables, and arguments |
| 1472 // does not have any effect. |
| 1473 if (variable->HasThisName(isolate())) { |
| 1474 builder()->LoadTrue(); |
| 1475 } else { |
| 1476 builder()->LoadFalse(); |
| 1477 } |
| 1478 break; |
| 1479 } |
| 1480 case VariableLocation::LOOKUP: { |
| 1481 UNIMPLEMENTED(); |
| 1482 break; |
| 1483 } |
| 1484 default: |
| 1485 UNREACHABLE(); |
| 1486 } |
| 1487 } else { |
| 1488 // Delete of an unresolvable reference returns true. |
| 1489 VisitForEffect(expr->expression()); |
| 1490 builder()->LoadTrue(); |
| 1491 } |
| 1492 execution_result()->SetResultInAccumulator(); |
| 1493 } |
| 1494 |
| 1495 |
1435 void BytecodeGenerator::VisitCountOperation(CountOperation* expr) { | 1496 void BytecodeGenerator::VisitCountOperation(CountOperation* expr) { |
1436 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); | 1497 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); |
1437 | 1498 |
1438 // Left-hand side can only be a property, a global or a variable slot. | 1499 // Left-hand side can only be a property, a global or a variable slot. |
1439 Property* property = expr->expression()->AsProperty(); | 1500 Property* property = expr->expression()->AsProperty(); |
1440 LhsKind assign_type = Property::GetAssignType(property); | 1501 LhsKind assign_type = Property::GetAssignType(property); |
1441 | 1502 |
1442 // TODO(rmcilroy): Set is_postfix to false if visiting for effect. | 1503 // TODO(rmcilroy): Set is_postfix to false if visiting for effect. |
1443 bool is_postfix = expr->is_postfix(); | 1504 bool is_postfix = expr->is_postfix(); |
1444 | 1505 |
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1880 } | 1941 } |
1881 | 1942 |
1882 | 1943 |
1883 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 1944 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
1884 return info()->feedback_vector()->GetIndex(slot); | 1945 return info()->feedback_vector()->GetIndex(slot); |
1885 } | 1946 } |
1886 | 1947 |
1887 } // namespace interpreter | 1948 } // namespace interpreter |
1888 } // namespace internal | 1949 } // namespace internal |
1889 } // namespace v8 | 1950 } // namespace v8 |
OLD | NEW |