Chromium Code Reviews| Index: src/x64/full-codegen-x64.cc |
| diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc |
| index b8cb3ee31a334b6ddac4888be4b359d6f69343e9..29c130abda5ebbca202d1c6294c1487b74bd0c59 100644 |
| --- a/src/x64/full-codegen-x64.cc |
| +++ b/src/x64/full-codegen-x64.cc |
| @@ -3032,6 +3032,47 @@ void FullCodeGenerator::EmitInitializeThisAfterSuper( |
| } |
| +// See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. |
| +void FullCodeGenerator::PushCalleeAndWithBaseObject(VariableProxy* callee) { |
| + if (callee->var()->IsLookupSlot()) { |
| + Label slow, done; |
| + |
| + { |
| + PreservePositionScope scope(masm()->positions_recorder()); |
| + // Generate code for loading from variables potentially shadowed by |
| + // eval-introduced variables. |
| + EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
| + } |
| + __ bind(&slow); |
| + // Call the runtime to find the function to call (returned in rax) and |
| + // the object holding it (returned in rdx). |
| + __ Push(context_register()); |
| + __ Push(callee->name()); |
| + __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
| + __ Push(rax); // Function. |
| + __ Push(rdx); // Receiver. |
| + |
| + // If fast case code has been generated, emit code to push the function |
| + // and receiver and have the slow path jump around this code. |
| + if (done.is_linked()) { |
| + Label call; |
| + __ jmp(&call, Label::kNear); |
| + __ bind(&done); |
| + // Push function. |
| + __ Push(rax); |
| + // The receiver is implicitly the global receiver. Indicate this by |
| + // passing the hole to the call function stub. |
|
Toon Verwaest
2015/06/24 13:30:43
Seems like you are passing in undefined instead ..
arv (Not doing code reviews)
2015/06/24 13:36:50
Old code had the same comment bug :-)
|
| + __ PushRoot(Heap::kUndefinedValueRootIndex); |
| + __ bind(&call); |
| + } |
| + } else { |
| + VisitForStackValue(callee); |
| + // refEnv.WithBaseObject() |
| + __ PushRoot(Heap::kUndefinedValueRootIndex); |
| + } |
| +} |
| + |
| + |
| void FullCodeGenerator::VisitCall(Call* expr) { |
| #ifdef DEBUG |
| // We want to verify that RecordJSReturnSite gets called on all paths |
| @@ -3050,8 +3091,7 @@ void FullCodeGenerator::VisitCall(Call* expr) { |
| ZoneList<Expression*>* args = expr->arguments(); |
| int arg_count = args->length(); |
| { PreservePositionScope pos_scope(masm()->positions_recorder()); |
| - VisitForStackValue(callee); |
| - __ PushRoot(Heap::kUndefinedValueRootIndex); // Reserved receiver slot. |
| + PushCalleeAndWithBaseObject(callee->AsVariableProxy()); |
| // Push the arguments. |
| for (int i = 0; i < arg_count; i++) { |
| @@ -3082,40 +3122,8 @@ void FullCodeGenerator::VisitCall(Call* expr) { |
| } else if (call_type == Call::LOOKUP_SLOT_CALL) { |
| // Call to a lookup slot (dynamically introduced variable). |
| - VariableProxy* proxy = callee->AsVariableProxy(); |
| - Label slow, done; |
| - |
| - { PreservePositionScope scope(masm()->positions_recorder()); |
| - // Generate code for loading from variables potentially shadowed by |
| - // eval-introduced variables. |
| - EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); |
| - } |
| - __ bind(&slow); |
| - // Call the runtime to find the function to call (returned in rax) and |
| - // the object holding it (returned in rdx). |
| - __ Push(context_register()); |
| - __ Push(proxy->name()); |
| - __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
| - __ Push(rax); // Function. |
| - __ Push(rdx); // Receiver. |
| + PushCalleeAndWithBaseObject(callee->AsVariableProxy()); |
| PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS); |
| - |
| - // If fast case code has been generated, emit code to push the function |
| - // and receiver and have the slow path jump around this code. |
| - if (done.is_linked()) { |
| - Label call; |
| - __ jmp(&call, Label::kNear); |
| - __ bind(&done); |
| - // Push function. |
| - __ Push(rax); |
| - // The receiver is implicitly the global receiver. Indicate this by |
| - // passing the hole to the call function stub. |
| - __ PushRoot(Heap::kUndefinedValueRootIndex); |
| - __ bind(&call); |
| - } |
| - |
| - // The receiver is either the global receiver or an object found by |
| - // LoadContextSlot. |
| EmitCall(expr); |
| } else if (call_type == Call::PROPERTY_CALL) { |
| Property* property = callee->AsProperty(); |