OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
10 #include "src/compiler/machine-operator.h" | 10 #include "src/compiler/machine-operator.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 if (FLAG_loop_assignment_analysis) { | 65 if (FLAG_loop_assignment_analysis) { |
66 // TODO(turbofan): use a temporary zone for the loop assignment analysis. | 66 // TODO(turbofan): use a temporary zone for the loop assignment analysis. |
67 AstLoopAssignmentAnalyzer analyzer(zone(), info()); | 67 AstLoopAssignmentAnalyzer analyzer(zone(), info()); |
68 loop_assignment_analysis_ = analyzer.Analyze(); | 68 loop_assignment_analysis_ = analyzer.Analyze(); |
69 } | 69 } |
70 | 70 |
71 // Initialize the top-level environment. | 71 // Initialize the top-level environment. |
72 Environment env(this, scope, graph()->start()); | 72 Environment env(this, scope, graph()->start()); |
73 set_environment(&env); | 73 set_environment(&env); |
74 | 74 |
| 75 // Initialize the incoming context. |
| 76 Node* outer_context = GetFunctionContext(); |
| 77 set_current_context(outer_context); |
| 78 |
| 79 // Build receiver check for sloppy mode if necessary. |
| 80 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? |
| 81 Node* original_receiver = env.Lookup(scope->receiver()); |
| 82 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); |
| 83 env.Bind(scope->receiver(), patched_receiver); |
| 84 |
75 // Build node to initialize local function context. | 85 // Build node to initialize local function context. |
76 Node* closure = GetFunctionClosure(); | 86 Node* closure = GetFunctionClosure(); |
77 Node* outer = GetFunctionContext(); | 87 Node* inner_context = BuildLocalFunctionContext(outer_context, closure); |
78 Node* inner = BuildLocalFunctionContext(outer, closure); | |
79 | 88 |
80 // Push top-level function scope for the function body. | 89 // Push top-level function scope for the function body. |
81 ContextScope top_context(this, scope, inner); | 90 ContextScope top_context(this, scope, inner_context); |
82 | 91 |
83 // Build the arguments object if it is used. | 92 // Build the arguments object if it is used. |
84 BuildArgumentsObject(scope->arguments()); | 93 BuildArgumentsObject(scope->arguments()); |
85 | 94 |
86 // Emit tracing call if requested to do so. | 95 // Emit tracing call if requested to do so. |
87 if (FLAG_trace) { | 96 if (FLAG_trace) { |
88 NewNode(javascript()->CallRuntime(Runtime::kTraceEnter, 0)); | 97 NewNode(javascript()->CallRuntime(Runtime::kTraceEnter, 0)); |
89 } | 98 } |
90 | 99 |
91 // Visit implicit declaration of the function name. | 100 // Visit implicit declaration of the function name. |
(...skipping 1674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1766 DCHECK(environment()->stack_height() >= arity); | 1775 DCHECK(environment()->stack_height() >= arity); |
1767 Node** all = info()->zone()->NewArray<Node*>(arity); | 1776 Node** all = info()->zone()->NewArray<Node*>(arity); |
1768 for (int i = arity - 1; i >= 0; --i) { | 1777 for (int i = arity - 1; i >= 0; --i) { |
1769 all[i] = environment()->Pop(); | 1778 all[i] = environment()->Pop(); |
1770 } | 1779 } |
1771 Node* value = NewNode(op, arity, all); | 1780 Node* value = NewNode(op, arity, all); |
1772 return value; | 1781 return value; |
1773 } | 1782 } |
1774 | 1783 |
1775 | 1784 |
| 1785 Node* AstGraphBuilder::BuildPatchReceiverToGlobalProxy(Node* receiver) { |
| 1786 // Sloppy mode functions and builtins need to replace the receiver with the |
| 1787 // global proxy when called as functions (without an explicit receiver |
| 1788 // object). Otherwise there is nothing left to do here. |
| 1789 if (info()->strict_mode() != SLOPPY || info()->is_native()) return receiver; |
| 1790 |
| 1791 // There is no need to perform patching if the receiver is never used. Note |
| 1792 // that scope predicates are purely syntactical, a call to eval might still |
| 1793 // inspect the receiver value. |
| 1794 if (!info()->scope()->uses_this() && !info()->scope()->inner_uses_this() && |
| 1795 !info()->scope()->calls_sloppy_eval()) { |
| 1796 return receiver; |
| 1797 } |
| 1798 |
| 1799 IfBuilder receiver_check(this); |
| 1800 Node* undefined = jsgraph()->UndefinedConstant(); |
| 1801 Node* check = NewNode(javascript()->StrictEqual(), receiver, undefined); |
| 1802 receiver_check.If(check); |
| 1803 receiver_check.Then(); |
| 1804 environment()->Push(BuildLoadGlobalProxy()); |
| 1805 receiver_check.Else(); |
| 1806 environment()->Push(receiver); |
| 1807 receiver_check.End(); |
| 1808 return environment()->Pop(); |
| 1809 } |
| 1810 |
| 1811 |
1776 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) { | 1812 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) { |
1777 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 1813 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
1778 if (heap_slots <= 0) return context; | 1814 if (heap_slots <= 0) return context; |
1779 set_current_context(context); | |
1780 | 1815 |
1781 // Allocate a new local context. | 1816 // Allocate a new local context. |
1782 const Operator* op = javascript()->CreateFunctionContext(); | 1817 const Operator* op = javascript()->CreateFunctionContext(); |
1783 Node* local_context = NewNode(op, closure); | 1818 Node* local_context = NewNode(op, closure); |
1784 set_current_context(local_context); | 1819 set_current_context(local_context); |
1785 | 1820 |
1786 // Copy parameters into context if necessary. | 1821 // Copy parameters into context if necessary. |
1787 int num_parameters = info()->scope()->num_parameters(); | 1822 int num_parameters = info()->scope()->num_parameters(); |
1788 for (int i = 0; i < num_parameters; i++) { | 1823 for (int i = 0; i < num_parameters; i++) { |
1789 Variable* variable = info()->scope()->parameter(i); | 1824 Variable* variable = info()->scope()->parameter(i); |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2062 | 2097 |
2063 | 2098 |
2064 Node* AstGraphBuilder::BuildLoadGlobalObject() { | 2099 Node* AstGraphBuilder::BuildLoadGlobalObject() { |
2065 Node* context = GetFunctionContext(); | 2100 Node* context = GetFunctionContext(); |
2066 const Operator* load_op = | 2101 const Operator* load_op = |
2067 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true); | 2102 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true); |
2068 return NewNode(load_op, context); | 2103 return NewNode(load_op, context); |
2069 } | 2104 } |
2070 | 2105 |
2071 | 2106 |
| 2107 Node* AstGraphBuilder::BuildLoadGlobalProxy() { |
| 2108 Node* global = BuildLoadGlobalObject(); |
| 2109 Node* proxy = |
| 2110 BuildLoadObjectField(global, JSGlobalObject::kGlobalProxyOffset); |
| 2111 return proxy; |
| 2112 } |
| 2113 |
| 2114 |
2072 Node* AstGraphBuilder::BuildToBoolean(Node* input) { | 2115 Node* AstGraphBuilder::BuildToBoolean(Node* input) { |
2073 // TODO(titzer): this should be in a JSOperatorReducer. | 2116 // TODO(titzer): this should be in a JSOperatorReducer. |
2074 switch (input->opcode()) { | 2117 switch (input->opcode()) { |
2075 case IrOpcode::kInt32Constant: | 2118 case IrOpcode::kInt32Constant: |
2076 return jsgraph_->BooleanConstant(!Int32Matcher(input).Is(0)); | 2119 return jsgraph_->BooleanConstant(!Int32Matcher(input).Is(0)); |
2077 case IrOpcode::kFloat64Constant: | 2120 case IrOpcode::kFloat64Constant: |
2078 return jsgraph_->BooleanConstant(!Float64Matcher(input).Is(0)); | 2121 return jsgraph_->BooleanConstant(!Float64Matcher(input).Is(0)); |
2079 case IrOpcode::kNumberConstant: | 2122 case IrOpcode::kNumberConstant: |
2080 return jsgraph_->BooleanConstant(!NumberMatcher(input).Is(0)); | 2123 return jsgraph_->BooleanConstant(!NumberMatcher(input).Is(0)); |
2081 case IrOpcode::kHeapConstant: { | 2124 case IrOpcode::kHeapConstant: { |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2184 | 2227 |
2185 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( | 2228 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( |
2186 IterationStatement* stmt) { | 2229 IterationStatement* stmt) { |
2187 if (loop_assignment_analysis_ == NULL) return NULL; | 2230 if (loop_assignment_analysis_ == NULL) return NULL; |
2188 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); | 2231 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); |
2189 } | 2232 } |
2190 | 2233 |
2191 } // namespace compiler | 2234 } // namespace compiler |
2192 } // namespace internal | 2235 } // namespace internal |
2193 } // namespace v8 | 2236 } // namespace v8 |
OLD | NEW |