Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 1508293003: [Interpreter] Add support for calling eval. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/cctest/interpreter/test-bytecode-generator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/compiler.h" 8 #include "src/compiler.h"
9 #include "src/interpreter/control-flow-builders.h" 9 #include "src/interpreter/control-flow-builders.h"
10 #include "src/objects.h" 10 #include "src/objects.h"
(...skipping 1597 matching lines...) Expand 10 before | Expand all | Expand 10 after
1608 // the semantics of the underlying call type. 1608 // the semantics of the underlying call type.
1609 Register callee = execution_result()->NewRegister(); 1609 Register callee = execution_result()->NewRegister();
1610 1610
1611 // The receiver and arguments need to be allocated consecutively for 1611 // The receiver and arguments need to be allocated consecutively for
1612 // Call(). Future optimizations could avoid this there are no 1612 // Call(). Future optimizations could avoid this there are no
1613 // arguments or the receiver and arguments are already consecutive. 1613 // arguments or the receiver and arguments are already consecutive.
1614 ZoneList<Expression*>* args = expr->arguments(); 1614 ZoneList<Expression*>* args = expr->arguments();
1615 execution_result()->PrepareForConsecutiveAllocations(args->length() + 1); 1615 execution_result()->PrepareForConsecutiveAllocations(args->length() + 1);
1616 Register receiver = execution_result()->NextConsecutiveRegister(); 1616 Register receiver = execution_result()->NextConsecutiveRegister();
1617 1617
1618 bool possibly_eval = false;
1618 switch (call_type) { 1619 switch (call_type) {
1619 case Call::NAMED_PROPERTY_CALL: 1620 case Call::NAMED_PROPERTY_CALL:
1620 case Call::KEYED_PROPERTY_CALL: { 1621 case Call::KEYED_PROPERTY_CALL: {
1621 Property* property = callee_expr->AsProperty(); 1622 Property* property = callee_expr->AsProperty();
1622 VisitForAccumulatorValue(property->obj()); 1623 VisitForAccumulatorValue(property->obj());
1623 builder()->StoreAccumulatorInRegister(receiver); 1624 builder()->StoreAccumulatorInRegister(receiver);
1624 VisitPropertyLoadForAccumulator(receiver, property); 1625 VisitPropertyLoadForAccumulator(receiver, property);
1625 builder()->StoreAccumulatorInRegister(callee); 1626 builder()->StoreAccumulatorInRegister(callee);
1626 break; 1627 break;
1627 } 1628 }
1628 case Call::GLOBAL_CALL: { 1629 case Call::GLOBAL_CALL: {
1629 // Receiver is undefined for global calls. 1630 // Receiver is undefined for global calls.
1630 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); 1631 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
1631 // Load callee as a global variable. 1632 // Load callee as a global variable.
1632 VariableProxy* proxy = callee_expr->AsVariableProxy(); 1633 VariableProxy* proxy = callee_expr->AsVariableProxy();
1633 VisitVariableLoadForAccumulatorValue(proxy->var(), 1634 VisitVariableLoadForAccumulatorValue(proxy->var(),
1634 proxy->VariableFeedbackSlot()); 1635 proxy->VariableFeedbackSlot());
1635 builder()->StoreAccumulatorInRegister(callee); 1636 builder()->StoreAccumulatorInRegister(callee);
1636 break; 1637 break;
1637 } 1638 }
1639 case Call::POSSIBLY_EVAL_CALL: {
1640 possibly_eval = true;
1641 if (callee_expr->AsVariableProxy()->var()->IsLookupSlot()) {
1642 TemporaryRegisterScope temporary_register_scope(builder());
1643 temporary_register_scope.PrepareForConsecutiveAllocations(2);
1644 Register context = temporary_register_scope.NextConsecutiveRegister();
1645 Register name = temporary_register_scope.NextConsecutiveRegister();
1646
1647 Variable* variable = callee_expr->AsVariableProxy()->var();
1648 builder()
1649 ->MoveRegister(Register::function_context(), context)
1650 .LoadLiteral(variable->name())
1651 .StoreAccumulatorInRegister(name);
1652
1653 // Call LoadLookupSlotCallee/Receiver to get the Callee and Receiver
Michael Starzinger 2016/01/08 13:40:47 nit: Comment is outdated, also s/Callee/callee/ an
rmcilroy 2016/01/08 14:34:30 Done.
1654 // Reuse the context and name arguments as the return registers (since
1655 // these are consecutive), and them move into callee and reciever
1656 // registers.
1657 builder()
1658 ->CallRuntimeForPair(Runtime::kLoadLookupSlot, context, 2, context)
1659 .MoveRegister(context, callee)
1660 .MoveRegister(name, receiver);
1661 break;
1662 }
1663 // Fall through.
1664 }
1638 case Call::OTHER_CALL: { 1665 case Call::OTHER_CALL: {
1639 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); 1666 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
1640 VisitForAccumulatorValue(callee_expr); 1667 VisitForAccumulatorValue(callee_expr);
1641 builder()->StoreAccumulatorInRegister(callee); 1668 builder()->StoreAccumulatorInRegister(callee);
1642 break; 1669 break;
1643 } 1670 }
1644 case Call::NAMED_SUPER_PROPERTY_CALL: 1671 case Call::NAMED_SUPER_PROPERTY_CALL:
1645 case Call::KEYED_SUPER_PROPERTY_CALL: 1672 case Call::KEYED_SUPER_PROPERTY_CALL:
1646 case Call::LOOKUP_SLOT_CALL: 1673 case Call::LOOKUP_SLOT_CALL:
1647 case Call::SUPER_CALL: 1674 case Call::SUPER_CALL:
1648 case Call::POSSIBLY_EVAL_CALL:
1649 UNIMPLEMENTED(); 1675 UNIMPLEMENTED();
1650 } 1676 }
1651 1677
1652 // Evaluate all arguments to the function call and store in sequential 1678 // Evaluate all arguments to the function call and store in sequential
1653 // registers. 1679 // registers.
1654 Register arg = VisitArguments(args); 1680 Register arg = VisitArguments(args);
1655 CHECK(args->length() == 0 || arg.index() == receiver.index() + 1); 1681 CHECK(args->length() == 0 || arg.index() == receiver.index() + 1);
1656 1682
1657 // TODO(rmcilroy): Deal with possible direct eval here? 1683 // Resolve callee and receiver for a potential direct eval call. This block
1684 // will mutate the callee and receiver values.
Michael Starzinger 2016/01/08 13:40:47 nit: This comment is outdated (also in the AstGrap
rmcilroy 2016/01/08 14:34:30 Done (also in AstGraphBuilder).
1685 if (possibly_eval && args->length() > 0) {
1686 TemporaryRegisterScope temporary_register_scope(builder());
1687 temporary_register_scope.PrepareForConsecutiveAllocations(5);
1688 Register callee_for_eval =
1689 temporary_register_scope.NextConsecutiveRegister();
1690 Register source = temporary_register_scope.NextConsecutiveRegister();
1691 Register function = temporary_register_scope.NextConsecutiveRegister();
1692 Register language = temporary_register_scope.NextConsecutiveRegister();
1693 Register position = temporary_register_scope.NextConsecutiveRegister();
1694
1695 // Set up arguments for ResolvePossiblyDirectEval by copying callee, source
1696 // strings and function closure, and loading language and
1697 // position.
1698 builder()
1699 ->MoveRegister(callee, callee_for_eval)
1700 .MoveRegister(arg, source)
1701 .MoveRegister(Register::function_closure(), function)
1702 .LoadLiteral(Smi::FromInt(language_mode()))
1703 .StoreAccumulatorInRegister(language)
1704 .LoadLiteral(
1705 Smi::FromInt(execution_context()->scope()->start_position()))
1706 .StoreAccumulatorInRegister(position);
1707
1708 // Call ResolvePossiblyDirectEval and modify the callee.
1709 builder()
1710 ->CallRuntime(Runtime::kResolvePossiblyDirectEval, callee_for_eval, 5)
1711 .StoreAccumulatorInRegister(callee);
1712 }
1713
1658 // TODO(rmcilroy): Use CallIC to allow call type feedback. 1714 // TODO(rmcilroy): Use CallIC to allow call type feedback.
1659 builder()->Call(callee, receiver, args->length(), 1715 builder()->Call(callee, receiver, args->length(),
1660 feedback_index(expr->CallFeedbackICSlot())); 1716 feedback_index(expr->CallFeedbackICSlot()));
1661 execution_result()->SetResultInAccumulator(); 1717 execution_result()->SetResultInAccumulator();
1662 } 1718 }
1663 1719
1664 1720
1665 void BytecodeGenerator::VisitCallNew(CallNew* expr) { 1721 void BytecodeGenerator::VisitCallNew(CallNew* expr) {
1666 Register constructor = execution_result()->NewRegister(); 1722 Register constructor = execution_result()->NewRegister();
1667 VisitForAccumulatorValue(expr->expression()); 1723 VisitForAccumulatorValue(expr->expression());
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
2045 Register::function_closure(), 1); 2101 Register::function_closure(), 1);
2046 } 2102 }
2047 execution_result()->SetResultInAccumulator(); 2103 execution_result()->SetResultInAccumulator();
2048 } 2104 }
2049 2105
2050 2106
2051 void BytecodeGenerator::VisitBuildLocalActivationContext() { 2107 void BytecodeGenerator::VisitBuildLocalActivationContext() {
2052 Scope* scope = this->scope(); 2108 Scope* scope = this->scope();
2053 2109
2054 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) { 2110 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) {
2055 UNIMPLEMENTED(); 2111 Variable* variable = scope->receiver();
2112 Register receiver(builder()->Parameter(0));
2113 // Context variable (at bottom of the context chain).
2114 DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
2115 builder()->LoadAccumulatorWithRegister(receiver).StoreContextSlot(
2116 execution_context()->reg(), variable->index());
2056 } 2117 }
2057 2118
2058 // Copy parameters into context if necessary. 2119 // Copy parameters into context if necessary.
2059 int num_parameters = scope->num_parameters(); 2120 int num_parameters = scope->num_parameters();
2060 for (int i = 0; i < num_parameters; i++) { 2121 for (int i = 0; i < num_parameters; i++) {
2061 Variable* variable = scope->parameter(i); 2122 Variable* variable = scope->parameter(i);
2062 if (!variable->IsContextSlot()) continue; 2123 if (!variable->IsContextSlot()) continue;
2063 2124
2064 // The parameter indices are shifted by 1 (receiver is variable 2125 // The parameter indices are shifted by 1 (receiver is variable
2065 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 2126 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
2225 } 2286 }
2226 2287
2227 2288
2228 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 2289 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
2229 return info()->feedback_vector()->GetIndex(slot); 2290 return info()->feedback_vector()->GetIndex(slot);
2230 } 2291 }
2231 2292
2232 } // namespace interpreter 2293 } // namespace interpreter
2233 } // namespace internal 2294 } // namespace internal
2234 } // namespace v8 2295 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/cctest/interpreter/test-bytecode-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698