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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 ContextScope* Previous(Scope* scope) { | 48 ContextScope* Previous(Scope* scope) { |
49 int depth = scope_->ContextChainLength(scope); | 49 int depth = scope_->ContextChainLength(scope); |
50 if (depth > depth_) { | 50 if (depth > depth_) { |
51 return nullptr; | 51 return nullptr; |
52 } | 52 } |
53 | 53 |
54 ContextScope* previous = this; | 54 ContextScope* previous = this; |
55 for (int i = depth; i > 0; --i) { | 55 for (int i = depth; i > 0; --i) { |
56 previous = previous->outer_; | 56 previous = previous->outer_; |
57 } | 57 } |
58 DCHECK_EQ(previous->scope_, scope); | |
59 return previous; | 58 return previous; |
60 } | 59 } |
61 | 60 |
62 Scope* scope() const { return scope_; } | 61 Scope* scope() const { return scope_; } |
63 Register reg() const { return register_; } | 62 Register reg() const { return register_; } |
64 | 63 |
65 private: | 64 private: |
66 BytecodeGenerator* generator_; | 65 BytecodeGenerator* generator_; |
67 Scope* scope_; | 66 Scope* scope_; |
68 ContextScope* outer_; | 67 ContextScope* outer_; |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 MakeBytecodeBody(); | 301 MakeBytecodeBody(); |
303 } | 302 } |
304 | 303 |
305 set_scope(nullptr); | 304 set_scope(nullptr); |
306 set_info(nullptr); | 305 set_info(nullptr); |
307 return builder_.ToBytecodeArray(); | 306 return builder_.ToBytecodeArray(); |
308 } | 307 } |
309 | 308 |
310 | 309 |
311 void BytecodeGenerator::MakeBytecodeBody() { | 310 void BytecodeGenerator::MakeBytecodeBody() { |
| 311 // Build the arguments object if it is used. |
| 312 VisitArgumentsObject(scope()->arguments()); |
| 313 |
| 314 // Build assignment to {.this_function} variable if it is used. |
| 315 VisitThisFunctionVariable(scope()->this_function_var()); |
| 316 |
| 317 // Build assignment to {new.target} variable if it is used. |
| 318 VisitNewTargetVariable(scope()->new_target_var()); |
| 319 |
| 320 // TODO(rmcilroy): Emit tracing call if requested to do so. |
| 321 if (FLAG_trace) { |
| 322 UNIMPLEMENTED(); |
| 323 } |
| 324 |
| 325 // Visit illegal re-declaration and bail out if it exists. |
| 326 if (scope()->HasIllegalRedeclaration()) { |
| 327 Visit(scope()->GetIllegalRedeclaration()); |
| 328 return; |
| 329 } |
| 330 |
312 // Visit declarations within the function scope. | 331 // Visit declarations within the function scope. |
313 VisitDeclarations(scope()->declarations()); | 332 VisitDeclarations(scope()->declarations()); |
314 | 333 |
315 // Visit statements in the function body. | 334 // Visit statements in the function body. |
316 VisitStatements(info()->literal()->body()); | 335 VisitStatements(info()->literal()->body()); |
317 } | 336 } |
318 | 337 |
319 | 338 |
320 void BytecodeGenerator::VisitBlock(Block* stmt) { | 339 void BytecodeGenerator::VisitBlock(Block* stmt) { |
321 builder()->EnterBlock(); | 340 builder()->EnterBlock(); |
(...skipping 1324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1646 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, | 1665 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, |
1647 ObjectLiteralProperty* property, | 1666 ObjectLiteralProperty* property, |
1648 int slot_number) { | 1667 int slot_number) { |
1649 Expression* expr = property->value(); | 1668 Expression* expr = property->value(); |
1650 if (!FunctionLiteral::NeedsHomeObject(expr)) return; | 1669 if (!FunctionLiteral::NeedsHomeObject(expr)) return; |
1651 | 1670 |
1652 UNIMPLEMENTED(); | 1671 UNIMPLEMENTED(); |
1653 } | 1672 } |
1654 | 1673 |
1655 | 1674 |
| 1675 void BytecodeGenerator::VisitArgumentsObject(Variable* variable) { |
| 1676 if (variable == nullptr) return; |
| 1677 |
| 1678 DCHECK(variable->IsContextSlot() || variable->IsStackAllocated()); |
| 1679 |
| 1680 // Allocate and initialize a new arguments object and assign to the |
| 1681 // {arguments} variable. |
| 1682 CreateArgumentsType type = |
| 1683 is_strict(language_mode()) || !info()->has_simple_parameters() |
| 1684 ? CreateArgumentsType::kUnmappedArguments |
| 1685 : CreateArgumentsType::kMappedArguments; |
| 1686 builder()->CreateArguments(type); |
| 1687 VisitVariableAssignment(variable, FeedbackVectorSlot::Invalid()); |
| 1688 } |
| 1689 |
| 1690 |
| 1691 void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) { |
| 1692 if (variable == nullptr) return; |
| 1693 |
| 1694 // TODO(rmcilroy): Remove once we have tests which exercise this code path. |
| 1695 UNIMPLEMENTED(); |
| 1696 |
| 1697 // Store the closure we were called with in the this_function_var. |
| 1698 builder()->LoadAccumulatorWithRegister(Register::function_closure()); |
| 1699 VisitVariableAssignment(variable, FeedbackVectorSlot::Invalid()); |
| 1700 } |
| 1701 |
| 1702 |
| 1703 void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) { |
| 1704 if (variable == nullptr) return; |
| 1705 |
| 1706 // TODO(rmcilroy): Remove once we have tests which exercise this code path. |
| 1707 UNIMPLEMENTED(); |
| 1708 |
| 1709 // Store the closure we were called with in the this_function_var. |
| 1710 builder()->CallRuntime(Runtime::kGetOriginalConstructor, Register(), 0); |
| 1711 VisitVariableAssignment(variable, FeedbackVectorSlot::Invalid()); |
| 1712 } |
| 1713 |
| 1714 |
1656 void BytecodeGenerator::VisitFunctionClosureForContext() { | 1715 void BytecodeGenerator::VisitFunctionClosureForContext() { |
1657 AccumulatorResultScope accumulator_execution_result(this); | 1716 AccumulatorResultScope accumulator_execution_result(this); |
1658 Scope* closure_scope = execution_context()->scope()->ClosureScope(); | 1717 Scope* closure_scope = execution_context()->scope()->ClosureScope(); |
1659 if (closure_scope->is_script_scope() || | 1718 if (closure_scope->is_script_scope() || |
1660 closure_scope->is_module_scope()) { | 1719 closure_scope->is_module_scope()) { |
1661 // Contexts nested in the native context have a canonical empty function as | 1720 // Contexts nested in the native context have a canonical empty function as |
1662 // their closure, not the anonymous closure containing the global code. | 1721 // their closure, not the anonymous closure containing the global code. |
1663 // Pass a SMI sentinel and let the runtime look up the empty function. | 1722 // Pass a SMI sentinel and let the runtime look up the empty function. |
1664 builder()->LoadLiteral(Smi::FromInt(0)); | 1723 builder()->LoadLiteral(Smi::FromInt(0)); |
1665 } else { | 1724 } else { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1757 } | 1816 } |
1758 | 1817 |
1759 | 1818 |
1760 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 1819 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
1761 return info()->feedback_vector()->GetIndex(slot); | 1820 return info()->feedback_vector()->GetIndex(slot); |
1762 } | 1821 } |
1763 | 1822 |
1764 } // namespace interpreter | 1823 } // namespace interpreter |
1765 } // namespace internal | 1824 } // namespace internal |
1766 } // namespace v8 | 1825 } // namespace v8 |
OLD | NEW |