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

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: Fix comments 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 | « src/compiler/ast-graph-builder.cc ('k') | 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 LoadLookupSlot to get the callee and receiver. Reuse the context
1654 // and name arguments as the return registers (since these are
1655 // consecutive), and them move into callee and receiver registers.
1656 builder()
1657 ->CallRuntimeForPair(Runtime::kLoadLookupSlot, context, 2, context)
1658 .MoveRegister(context, callee)
1659 .MoveRegister(name, receiver);
1660 break;
1661 }
1662 // Fall through.
1663 }
1638 case Call::OTHER_CALL: { 1664 case Call::OTHER_CALL: {
1639 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); 1665 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
1640 VisitForAccumulatorValue(callee_expr); 1666 VisitForAccumulatorValue(callee_expr);
1641 builder()->StoreAccumulatorInRegister(callee); 1667 builder()->StoreAccumulatorInRegister(callee);
1642 break; 1668 break;
1643 } 1669 }
1644 case Call::NAMED_SUPER_PROPERTY_CALL: 1670 case Call::NAMED_SUPER_PROPERTY_CALL:
1645 case Call::KEYED_SUPER_PROPERTY_CALL: 1671 case Call::KEYED_SUPER_PROPERTY_CALL:
1646 case Call::LOOKUP_SLOT_CALL: 1672 case Call::LOOKUP_SLOT_CALL:
1647 case Call::SUPER_CALL: 1673 case Call::SUPER_CALL:
1648 case Call::POSSIBLY_EVAL_CALL:
1649 UNIMPLEMENTED(); 1674 UNIMPLEMENTED();
1650 } 1675 }
1651 1676
1652 // Evaluate all arguments to the function call and store in sequential 1677 // Evaluate all arguments to the function call and store in sequential
1653 // registers. 1678 // registers.
1654 Register arg = VisitArguments(args); 1679 Register arg = VisitArguments(args);
1655 CHECK(args->length() == 0 || arg.index() == receiver.index() + 1); 1680 CHECK(args->length() == 0 || arg.index() == receiver.index() + 1);
1656 1681
1657 // TODO(rmcilroy): Deal with possible direct eval here? 1682 // Resolve callee for a potential direct eval call. This block will mutate the
1683 // callee value.
1684 if (possibly_eval && args->length() > 0) {
1685 TemporaryRegisterScope temporary_register_scope(builder());
1686 temporary_register_scope.PrepareForConsecutiveAllocations(5);
1687 Register callee_for_eval =
1688 temporary_register_scope.NextConsecutiveRegister();
1689 Register source = temporary_register_scope.NextConsecutiveRegister();
1690 Register function = temporary_register_scope.NextConsecutiveRegister();
1691 Register language = temporary_register_scope.NextConsecutiveRegister();
1692 Register position = temporary_register_scope.NextConsecutiveRegister();
1693
1694 // Set up arguments for ResolvePossiblyDirectEval by copying callee, source
1695 // strings and function closure, and loading language and
1696 // position.
1697 builder()
1698 ->MoveRegister(callee, callee_for_eval)
1699 .MoveRegister(arg, source)
1700 .MoveRegister(Register::function_closure(), function)
1701 .LoadLiteral(Smi::FromInt(language_mode()))
1702 .StoreAccumulatorInRegister(language)
1703 .LoadLiteral(
1704 Smi::FromInt(execution_context()->scope()->start_position()))
1705 .StoreAccumulatorInRegister(position);
1706
1707 // Call ResolvePossiblyDirectEval and modify the callee.
1708 builder()
1709 ->CallRuntime(Runtime::kResolvePossiblyDirectEval, callee_for_eval, 5)
1710 .StoreAccumulatorInRegister(callee);
1711 }
1712
1658 // TODO(rmcilroy): Use CallIC to allow call type feedback. 1713 // TODO(rmcilroy): Use CallIC to allow call type feedback.
1659 builder()->Call(callee, receiver, args->length(), 1714 builder()->Call(callee, receiver, args->length(),
1660 feedback_index(expr->CallFeedbackICSlot())); 1715 feedback_index(expr->CallFeedbackICSlot()));
1661 execution_result()->SetResultInAccumulator(); 1716 execution_result()->SetResultInAccumulator();
1662 } 1717 }
1663 1718
1664 1719
1665 void BytecodeGenerator::VisitCallNew(CallNew* expr) { 1720 void BytecodeGenerator::VisitCallNew(CallNew* expr) {
1666 Register constructor = execution_result()->NewRegister(); 1721 Register constructor = execution_result()->NewRegister();
1667 VisitForAccumulatorValue(expr->expression()); 1722 VisitForAccumulatorValue(expr->expression());
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
2045 Register::function_closure(), 1); 2100 Register::function_closure(), 1);
2046 } 2101 }
2047 execution_result()->SetResultInAccumulator(); 2102 execution_result()->SetResultInAccumulator();
2048 } 2103 }
2049 2104
2050 2105
2051 void BytecodeGenerator::VisitBuildLocalActivationContext() { 2106 void BytecodeGenerator::VisitBuildLocalActivationContext() {
2052 Scope* scope = this->scope(); 2107 Scope* scope = this->scope();
2053 2108
2054 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) { 2109 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) {
2055 UNIMPLEMENTED(); 2110 Variable* variable = scope->receiver();
2111 Register receiver(builder()->Parameter(0));
2112 // Context variable (at bottom of the context chain).
2113 DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
2114 builder()->LoadAccumulatorWithRegister(receiver).StoreContextSlot(
2115 execution_context()->reg(), variable->index());
2056 } 2116 }
2057 2117
2058 // Copy parameters into context if necessary. 2118 // Copy parameters into context if necessary.
2059 int num_parameters = scope->num_parameters(); 2119 int num_parameters = scope->num_parameters();
2060 for (int i = 0; i < num_parameters; i++) { 2120 for (int i = 0; i < num_parameters; i++) {
2061 Variable* variable = scope->parameter(i); 2121 Variable* variable = scope->parameter(i);
2062 if (!variable->IsContextSlot()) continue; 2122 if (!variable->IsContextSlot()) continue;
2063 2123
2064 // The parameter indices are shifted by 1 (receiver is variable 2124 // The parameter indices are shifted by 1 (receiver is variable
2065 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 2125 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
2225 } 2285 }
2226 2286
2227 2287
2228 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 2288 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
2229 return info()->feedback_vector()->GetIndex(slot); 2289 return info()->feedback_vector()->GetIndex(slot);
2230 } 2290 }
2231 2291
2232 } // namespace interpreter 2292 } // namespace interpreter
2233 } // namespace internal 2293 } // namespace internal
2234 } // namespace v8 2294 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.cc ('k') | test/cctest/interpreter/test-bytecode-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698