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/interpreter.h" | 5 #include "src/interpreter/interpreter.h" |
6 | 6 |
7 #include <fstream> | 7 #include <fstream> |
8 #include <memory> | 8 #include <memory> |
9 | 9 |
10 #include "src/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
(...skipping 1453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1464 | 1464 |
1465 // TailCall <callable> <receiver> <arg_count> <feedback_slot_id> | 1465 // TailCall <callable> <receiver> <arg_count> <feedback_slot_id> |
1466 // | 1466 // |
1467 // Tail call a JSfunction or Callable in |callable| with the |receiver| and | 1467 // Tail call a JSfunction or Callable in |callable| with the |receiver| and |
1468 // |arg_count| arguments in subsequent registers. Collect type feedback | 1468 // |arg_count| arguments in subsequent registers. Collect type feedback |
1469 // into |feedback_slot_id| | 1469 // into |feedback_slot_id| |
1470 void Interpreter::DoTailCall(InterpreterAssembler* assembler) { | 1470 void Interpreter::DoTailCall(InterpreterAssembler* assembler) { |
1471 DoJSCall(assembler, TailCallMode::kAllow); | 1471 DoJSCall(assembler, TailCallMode::kAllow); |
1472 } | 1472 } |
1473 | 1473 |
1474 void Interpreter::DoCallRuntimeCommon(InterpreterAssembler* assembler) { | 1474 // CallRuntime <function_id> <first_arg> <arg_count> |
| 1475 // |
| 1476 // Call the runtime function |function_id| with the first argument in |
| 1477 // register |first_arg| and |arg_count| arguments in subsequent |
| 1478 // registers. |
| 1479 void Interpreter::DoCallRuntime(InterpreterAssembler* assembler) { |
1475 Node* function_id = __ BytecodeOperandRuntimeId(0); | 1480 Node* function_id = __ BytecodeOperandRuntimeId(0); |
1476 Node* first_arg_reg = __ BytecodeOperandReg(1); | 1481 Node* first_arg_reg = __ BytecodeOperandReg(1); |
1477 Node* first_arg = __ RegisterLocation(first_arg_reg); | 1482 Node* first_arg = __ RegisterLocation(first_arg_reg); |
1478 Node* args_count = __ BytecodeOperandCount(2); | 1483 Node* args_count = __ BytecodeOperandCount(2); |
1479 Node* context = __ GetContext(); | 1484 Node* context = __ GetContext(); |
1480 Node* result = __ CallRuntimeN(function_id, context, first_arg, args_count); | 1485 Node* result = __ CallRuntimeN(function_id, context, first_arg, args_count); |
1481 __ SetAccumulator(result); | 1486 __ SetAccumulator(result); |
1482 __ Dispatch(); | 1487 __ Dispatch(); |
1483 } | 1488 } |
1484 | 1489 |
1485 // CallRuntime <function_id> <first_arg> <arg_count> | |
1486 // | |
1487 // Call the runtime function |function_id| with the first argument in | |
1488 // register |first_arg| and |arg_count| arguments in subsequent | |
1489 // registers. | |
1490 void Interpreter::DoCallRuntime(InterpreterAssembler* assembler) { | |
1491 DoCallRuntimeCommon(assembler); | |
1492 } | |
1493 | |
1494 // InvokeIntrinsic <function_id> <first_arg> <arg_count> | 1490 // InvokeIntrinsic <function_id> <first_arg> <arg_count> |
1495 // | 1491 // |
1496 // Implements the semantic equivalent of calling the runtime function | 1492 // Implements the semantic equivalent of calling the runtime function |
1497 // |function_id| with the first argument in |first_arg| and |arg_count| | 1493 // |function_id| with the first argument in |first_arg| and |arg_count| |
1498 // arguments in subsequent registers. | 1494 // arguments in subsequent registers. |
1499 void Interpreter::DoInvokeIntrinsic(InterpreterAssembler* assembler) { | 1495 void Interpreter::DoInvokeIntrinsic(InterpreterAssembler* assembler) { |
1500 Node* function_id = __ BytecodeOperandIntrinsicId(0); | 1496 Node* function_id = __ BytecodeOperandIntrinsicId(0); |
1501 Node* first_arg_reg = __ BytecodeOperandReg(1); | 1497 Node* first_arg_reg = __ BytecodeOperandReg(1); |
1502 Node* arg_count = __ BytecodeOperandCount(2); | 1498 Node* arg_count = __ BytecodeOperandCount(2); |
1503 Node* context = __ GetContext(); | 1499 Node* context = __ GetContext(); |
1504 IntrinsicsHelper helper(assembler); | 1500 IntrinsicsHelper helper(assembler); |
1505 Node* result = | 1501 Node* result = |
1506 helper.InvokeIntrinsic(function_id, context, first_arg_reg, arg_count); | 1502 helper.InvokeIntrinsic(function_id, context, first_arg_reg, arg_count); |
1507 __ SetAccumulator(result); | 1503 __ SetAccumulator(result); |
1508 __ Dispatch(); | 1504 __ Dispatch(); |
1509 } | 1505 } |
1510 | 1506 |
1511 void Interpreter::DoCallRuntimeForPairCommon(InterpreterAssembler* assembler) { | 1507 // CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return> |
| 1508 // |
| 1509 // Call the runtime function |function_id| which returns a pair, with the |
| 1510 // first argument in register |first_arg| and |arg_count| arguments in |
| 1511 // subsequent registers. Returns the result in <first_return> and |
| 1512 // <first_return + 1> |
| 1513 void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) { |
1512 // Call the runtime function. | 1514 // Call the runtime function. |
1513 Node* function_id = __ BytecodeOperandRuntimeId(0); | 1515 Node* function_id = __ BytecodeOperandRuntimeId(0); |
1514 Node* first_arg_reg = __ BytecodeOperandReg(1); | 1516 Node* first_arg_reg = __ BytecodeOperandReg(1); |
1515 Node* first_arg = __ RegisterLocation(first_arg_reg); | 1517 Node* first_arg = __ RegisterLocation(first_arg_reg); |
1516 Node* args_count = __ BytecodeOperandCount(2); | 1518 Node* args_count = __ BytecodeOperandCount(2); |
1517 Node* context = __ GetContext(); | 1519 Node* context = __ GetContext(); |
1518 Node* result_pair = | 1520 Node* result_pair = |
1519 __ CallRuntimeN(function_id, context, first_arg, args_count, 2); | 1521 __ CallRuntimeN(function_id, context, first_arg, args_count, 2); |
1520 | 1522 |
1521 // Store the results in <first_return> and <first_return + 1> | 1523 // Store the results in <first_return> and <first_return + 1> |
1522 Node* first_return_reg = __ BytecodeOperandReg(3); | 1524 Node* first_return_reg = __ BytecodeOperandReg(3); |
1523 Node* second_return_reg = __ NextRegister(first_return_reg); | 1525 Node* second_return_reg = __ NextRegister(first_return_reg); |
1524 Node* result0 = __ Projection(0, result_pair); | 1526 Node* result0 = __ Projection(0, result_pair); |
1525 Node* result1 = __ Projection(1, result_pair); | 1527 Node* result1 = __ Projection(1, result_pair); |
1526 __ StoreRegister(result0, first_return_reg); | 1528 __ StoreRegister(result0, first_return_reg); |
1527 __ StoreRegister(result1, second_return_reg); | 1529 __ StoreRegister(result1, second_return_reg); |
1528 __ Dispatch(); | 1530 __ Dispatch(); |
1529 } | 1531 } |
1530 | 1532 |
1531 // CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return> | 1533 // CallJSRuntime <context_index> <receiver> <arg_count> |
1532 // | 1534 // |
1533 // Call the runtime function |function_id| which returns a pair, with the | 1535 // Call the JS runtime function that has the |context_index| with the receiver |
1534 // first argument in register |first_arg| and |arg_count| arguments in | 1536 // in register |receiver| and |arg_count| arguments in subsequent registers. |
1535 // subsequent registers. Returns the result in <first_return> and | 1537 void Interpreter::DoCallJSRuntime(InterpreterAssembler* assembler) { |
1536 // <first_return + 1> | |
1537 void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) { | |
1538 DoCallRuntimeForPairCommon(assembler); | |
1539 } | |
1540 | |
1541 void Interpreter::DoCallJSRuntimeCommon(InterpreterAssembler* assembler) { | |
1542 Node* context_index = __ BytecodeOperandIdx(0); | 1538 Node* context_index = __ BytecodeOperandIdx(0); |
1543 Node* receiver_reg = __ BytecodeOperandReg(1); | 1539 Node* receiver_reg = __ BytecodeOperandReg(1); |
1544 Node* first_arg = __ RegisterLocation(receiver_reg); | 1540 Node* first_arg = __ RegisterLocation(receiver_reg); |
1545 Node* receiver_args_count = __ BytecodeOperandCount(2); | 1541 Node* receiver_args_count = __ BytecodeOperandCount(2); |
1546 Node* receiver_count = __ Int32Constant(1); | 1542 Node* receiver_count = __ Int32Constant(1); |
1547 Node* args_count = __ Int32Sub(receiver_args_count, receiver_count); | 1543 Node* args_count = __ Int32Sub(receiver_args_count, receiver_count); |
1548 | 1544 |
1549 // Get the function to call from the native context. | 1545 // Get the function to call from the native context. |
1550 Node* context = __ GetContext(); | 1546 Node* context = __ GetContext(); |
1551 Node* native_context = | 1547 Node* native_context = |
1552 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); | 1548 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); |
1553 Node* function = __ LoadContextSlot(native_context, context_index); | 1549 Node* function = __ LoadContextSlot(native_context, context_index); |
1554 | 1550 |
1555 // Call the function. | 1551 // Call the function. |
1556 Node* result = __ CallJS(function, context, first_arg, args_count, | 1552 Node* result = __ CallJS(function, context, first_arg, args_count, |
1557 TailCallMode::kDisallow); | 1553 TailCallMode::kDisallow); |
1558 __ SetAccumulator(result); | 1554 __ SetAccumulator(result); |
1559 __ Dispatch(); | 1555 __ Dispatch(); |
1560 } | 1556 } |
1561 | 1557 |
1562 // CallJSRuntime <context_index> <receiver> <arg_count> | 1558 // New <constructor> <first_arg> <arg_count> |
1563 // | 1559 // |
1564 // Call the JS runtime function that has the |context_index| with the receiver | 1560 // Call operator new with |constructor| and the first argument in |
1565 // in register |receiver| and |arg_count| arguments in subsequent registers. | 1561 // register |first_arg| and |arg_count| arguments in subsequent |
1566 void Interpreter::DoCallJSRuntime(InterpreterAssembler* assembler) { | 1562 // registers. The new.target is in the accumulator. |
1567 DoCallJSRuntimeCommon(assembler); | 1563 // |
1568 } | 1564 void Interpreter::DoNew(InterpreterAssembler* assembler) { |
1569 | |
1570 void Interpreter::DoCallConstruct(InterpreterAssembler* assembler) { | |
1571 Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_); | 1565 Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_); |
1572 Node* new_target = __ GetAccumulator(); | 1566 Node* new_target = __ GetAccumulator(); |
1573 Node* constructor_reg = __ BytecodeOperandReg(0); | 1567 Node* constructor_reg = __ BytecodeOperandReg(0); |
1574 Node* constructor = __ LoadRegister(constructor_reg); | 1568 Node* constructor = __ LoadRegister(constructor_reg); |
1575 Node* first_arg_reg = __ BytecodeOperandReg(1); | 1569 Node* first_arg_reg = __ BytecodeOperandReg(1); |
1576 Node* first_arg = __ RegisterLocation(first_arg_reg); | 1570 Node* first_arg = __ RegisterLocation(first_arg_reg); |
1577 Node* args_count = __ BytecodeOperandCount(2); | 1571 Node* args_count = __ BytecodeOperandCount(2); |
1578 Node* slot_id = __ BytecodeOperandIdx(3); | 1572 Node* slot_id = __ BytecodeOperandIdx(3); |
1579 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 1573 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
1580 Node* context = __ GetContext(); | 1574 Node* context = __ GetContext(); |
1581 Node* result = __ CallConstruct(constructor, context, new_target, first_arg, | 1575 Node* result = __ CallConstruct(constructor, context, new_target, first_arg, |
1582 args_count, slot_id, type_feedback_vector); | 1576 args_count, slot_id, type_feedback_vector); |
1583 __ SetAccumulator(result); | 1577 __ SetAccumulator(result); |
1584 __ Dispatch(); | 1578 __ Dispatch(); |
1585 } | 1579 } |
1586 | 1580 |
1587 // New <constructor> <first_arg> <arg_count> | |
1588 // | |
1589 // Call operator new with |constructor| and the first argument in | |
1590 // register |first_arg| and |arg_count| arguments in subsequent | |
1591 // registers. The new.target is in the accumulator. | |
1592 // | |
1593 void Interpreter::DoNew(InterpreterAssembler* assembler) { | |
1594 DoCallConstruct(assembler); | |
1595 } | |
1596 | |
1597 // TestEqual <src> | 1581 // TestEqual <src> |
1598 // | 1582 // |
1599 // Test if the value in the <src> register equals the accumulator. | 1583 // Test if the value in the <src> register equals the accumulator. |
1600 void Interpreter::DoTestEqual(InterpreterAssembler* assembler) { | 1584 void Interpreter::DoTestEqual(InterpreterAssembler* assembler) { |
1601 DoCompareOpWithFeedback<EqualStub>(assembler); | 1585 DoCompareOpWithFeedback<EqualStub>(assembler); |
1602 } | 1586 } |
1603 | 1587 |
1604 // TestNotEqual <src> | 1588 // TestNotEqual <src> |
1605 // | 1589 // |
1606 // Test if the value in the <src> register is not equal to the accumulator. | 1590 // Test if the value in the <src> register is not equal to the accumulator. |
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2464 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, | 2448 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, |
2465 __ SmiTag(new_state)); | 2449 __ SmiTag(new_state)); |
2466 __ SetAccumulator(old_state); | 2450 __ SetAccumulator(old_state); |
2467 | 2451 |
2468 __ Dispatch(); | 2452 __ Dispatch(); |
2469 } | 2453 } |
2470 | 2454 |
2471 } // namespace interpreter | 2455 } // namespace interpreter |
2472 } // namespace internal | 2456 } // namespace internal |
2473 } // namespace v8 | 2457 } // namespace v8 |
OLD | NEW |