| 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 |