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/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
9 #include "src/interpreter/bytecode-register-allocator.h" | 9 #include "src/interpreter/bytecode-register-allocator.h" |
10 #include "src/interpreter/control-flow-builders.h" | 10 #include "src/interpreter/control-flow-builders.h" |
(...skipping 2157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2168 | 2168 |
2169 void BytecodeGenerator::VisitCall(Call* expr) { | 2169 void BytecodeGenerator::VisitCall(Call* expr) { |
2170 Expression* callee_expr = expr->expression(); | 2170 Expression* callee_expr = expr->expression(); |
2171 Call::CallType call_type = expr->GetCallType(isolate()); | 2171 Call::CallType call_type = expr->GetCallType(isolate()); |
2172 | 2172 |
2173 // Prepare the callee and the receiver to the function call. This depends on | 2173 // Prepare the callee and the receiver to the function call. This depends on |
2174 // the semantics of the underlying call type. | 2174 // the semantics of the underlying call type. |
2175 | 2175 |
2176 // The receiver and arguments need to be allocated consecutively for | 2176 // The receiver and arguments need to be allocated consecutively for |
2177 // Call(). We allocate the callee and receiver consecutively for calls to | 2177 // Call(). We allocate the callee and receiver consecutively for calls to |
2178 // kLoadLookupSlot. Future optimizations could avoid this there are no | 2178 // %LoadLookupSlotForCall. Future optimizations could avoid this there are |
2179 // arguments or the receiver and arguments are already consecutive. | 2179 // no arguments or the receiver and arguments are already consecutive. |
2180 ZoneList<Expression*>* args = expr->arguments(); | 2180 ZoneList<Expression*>* args = expr->arguments(); |
2181 register_allocator()->PrepareForConsecutiveAllocations(args->length() + 2); | 2181 register_allocator()->PrepareForConsecutiveAllocations(args->length() + 2); |
2182 Register callee = register_allocator()->NextConsecutiveRegister(); | 2182 Register callee = register_allocator()->NextConsecutiveRegister(); |
2183 Register receiver = register_allocator()->NextConsecutiveRegister(); | 2183 Register receiver = register_allocator()->NextConsecutiveRegister(); |
2184 | 2184 |
2185 switch (call_type) { | 2185 switch (call_type) { |
2186 case Call::NAMED_PROPERTY_CALL: | 2186 case Call::NAMED_PROPERTY_CALL: |
2187 case Call::KEYED_PROPERTY_CALL: { | 2187 case Call::KEYED_PROPERTY_CALL: { |
2188 Property* property = callee_expr->AsProperty(); | 2188 Property* property = callee_expr->AsProperty(); |
2189 VisitForAccumulatorValue(property->obj()); | 2189 VisitForAccumulatorValue(property->obj()); |
2190 builder()->StoreAccumulatorInRegister(receiver); | 2190 builder()->StoreAccumulatorInRegister(receiver); |
2191 VisitPropertyLoadForAccumulator(receiver, property); | 2191 VisitPropertyLoadForAccumulator(receiver, property); |
2192 builder()->StoreAccumulatorInRegister(callee); | 2192 builder()->StoreAccumulatorInRegister(callee); |
2193 break; | 2193 break; |
2194 } | 2194 } |
2195 case Call::GLOBAL_CALL: { | 2195 case Call::GLOBAL_CALL: { |
2196 // Receiver is undefined for global calls. | 2196 // Receiver is undefined for global calls. |
2197 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); | 2197 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); |
2198 // Load callee as a global variable. | 2198 // Load callee as a global variable. |
2199 VariableProxy* proxy = callee_expr->AsVariableProxy(); | 2199 VariableProxy* proxy = callee_expr->AsVariableProxy(); |
2200 VisitVariableLoadForAccumulatorValue(proxy->var(), | 2200 VisitVariableLoadForAccumulatorValue(proxy->var(), |
2201 proxy->VariableFeedbackSlot()); | 2201 proxy->VariableFeedbackSlot()); |
2202 builder()->StoreAccumulatorInRegister(callee); | 2202 builder()->StoreAccumulatorInRegister(callee); |
2203 break; | 2203 break; |
2204 } | 2204 } |
2205 case Call::LOOKUP_SLOT_CALL: | 2205 case Call::LOOKUP_SLOT_CALL: |
2206 case Call::POSSIBLY_EVAL_CALL: { | 2206 case Call::POSSIBLY_EVAL_CALL: { |
2207 if (callee_expr->AsVariableProxy()->var()->IsLookupSlot()) { | 2207 if (callee_expr->AsVariableProxy()->var()->IsLookupSlot()) { |
2208 RegisterAllocationScope inner_register_scope(this); | 2208 RegisterAllocationScope inner_register_scope(this); |
2209 register_allocator()->PrepareForConsecutiveAllocations(2); | 2209 Register name = register_allocator()->NewRegister(); |
2210 Register context = register_allocator()->NextConsecutiveRegister(); | |
2211 Register name = register_allocator()->NextConsecutiveRegister(); | |
2212 | 2210 |
2213 // Call LoadLookupSlot to get the callee and receiver. | 2211 // Call %LoadLookupSlotForCall to get the callee and receiver. |
2214 DCHECK(Register::AreContiguous(callee, receiver)); | 2212 DCHECK(Register::AreContiguous(callee, receiver)); |
2215 Variable* variable = callee_expr->AsVariableProxy()->var(); | 2213 Variable* variable = callee_expr->AsVariableProxy()->var(); |
2216 builder() | 2214 builder() |
2217 ->MoveRegister(Register::current_context(), context) | 2215 ->LoadLiteral(variable->name()) |
2218 .LoadLiteral(variable->name()) | |
2219 .StoreAccumulatorInRegister(name) | 2216 .StoreAccumulatorInRegister(name) |
2220 .CallRuntimeForPair(Runtime::kLoadLookupSlot, context, 2, callee); | 2217 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, name, 1, |
| 2218 callee); |
2221 break; | 2219 break; |
2222 } | 2220 } |
2223 // Fall through. | 2221 // Fall through. |
2224 DCHECK_EQ(call_type, Call::POSSIBLY_EVAL_CALL); | 2222 DCHECK_EQ(call_type, Call::POSSIBLY_EVAL_CALL); |
2225 } | 2223 } |
2226 case Call::OTHER_CALL: { | 2224 case Call::OTHER_CALL: { |
2227 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); | 2225 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); |
2228 VisitForAccumulatorValue(callee_expr); | 2226 VisitForAccumulatorValue(callee_expr); |
2229 builder()->StoreAccumulatorInRegister(callee); | 2227 builder()->StoreAccumulatorInRegister(callee); |
2230 break; | 2228 break; |
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2873 } | 2871 } |
2874 | 2872 |
2875 | 2873 |
2876 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 2874 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
2877 return info()->feedback_vector()->GetIndex(slot); | 2875 return info()->feedback_vector()->GetIndex(slot); |
2878 } | 2876 } |
2879 | 2877 |
2880 } // namespace interpreter | 2878 } // namespace interpreter |
2881 } // namespace internal | 2879 } // namespace internal |
2882 } // namespace v8 | 2880 } // namespace v8 |
OLD | NEW |