Simplify dispatch in FullCodeGenerator::VisitCall a bit.
This makes FullCodeGenerator::VisitCall be independent of the target architecture. Only the EmitPossiblyEvalCall case was dependent and is hoisted into an emitter method. R=rossberg@chromium.org Review URL: https://codereview.chromium.org/1428953002 Cr-Commit-Position: refs/heads/master@{#31693}
This commit is contained in:
parent
06eb555fa3
commit
0b293d877c
@ -3572,6 +3572,14 @@ void MacroAssembler::TryGetFunctionPrototype(Register function, Register result,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::PushRoot(Heap::RootListIndex index) {
|
||||
UseScratchRegisterScope temps(this);
|
||||
Register temp = temps.AcquireX();
|
||||
LoadRoot(temp, index);
|
||||
Push(temp);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::CompareRoot(const Register& obj,
|
||||
Heap::RootListIndex index) {
|
||||
UseScratchRegisterScope temps(this);
|
||||
|
@ -1461,6 +1461,9 @@ class MacroAssembler : public Assembler {
|
||||
// register.
|
||||
void LoadElementsKindFromMap(Register result, Register map);
|
||||
|
||||
// Load the value from the root list and push it onto the stack.
|
||||
void PushRoot(Heap::RootListIndex index);
|
||||
|
||||
// Compare the object in a register to a value from the root list.
|
||||
void CompareRoot(const Register& obj, Heap::RootListIndex index);
|
||||
|
||||
|
@ -3040,86 +3040,40 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitCall(Call* expr) {
|
||||
#ifdef DEBUG
|
||||
// We want to verify that RecordJSReturnSite gets called on all paths
|
||||
// through this function. Avoid early returns.
|
||||
expr->return_is_recorded_ = false;
|
||||
#endif
|
||||
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
||||
// In a call to eval, we first call
|
||||
// RuntimeHidden_asResolvePossiblyDirectEval to resolve the function we need
|
||||
// to call. Then we call the resolved function using the given arguments.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
Comment cmnt(masm_, "[ Call");
|
||||
Expression* callee = expr->expression();
|
||||
Call::CallType call_type = expr->GetCallType(isolate());
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
|
||||
if (call_type == Call::POSSIBLY_EVAL_CALL) {
|
||||
// In a call to eval, we first call
|
||||
// RuntimeHidden_asResolvePossiblyDirectEval to resolve the function we need
|
||||
// to call. Then we call the resolved function using the given arguments.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
|
||||
// Push the arguments.
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Push a copy of the function (found below the arguments) and
|
||||
// resolve eval.
|
||||
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
__ push(r1);
|
||||
EmitResolvePossiblyDirectEval(arg_count);
|
||||
|
||||
// Touch up the stack with the resolved function.
|
||||
__ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
|
||||
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
|
||||
|
||||
// Record source position for debugger.
|
||||
SetCallPosition(expr, arg_count);
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
context()->DropAndPlug(1, r0);
|
||||
} else if (call_type == Call::GLOBAL_CALL) {
|
||||
EmitCallWithLoadIC(expr);
|
||||
|
||||
} else if (call_type == Call::LOOKUP_SLOT_CALL) {
|
||||
// Call to a lookup slot (dynamically introduced variable).
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
EmitCall(expr);
|
||||
} else if (call_type == Call::NAMED_PROPERTY_CALL) {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::KEYED_PROPERTY_CALL) {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitKeyedCallWithLoadIC(expr, property->key());
|
||||
} else if (call_type == Call::NAMED_SUPER_PROPERTY_CALL) {
|
||||
EmitSuperCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::KEYED_SUPER_PROPERTY_CALL) {
|
||||
EmitKeyedSuperCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::SUPER_CALL) {
|
||||
EmitSuperConstructorCall(expr);
|
||||
} else {
|
||||
DCHECK(call_type == Call::OTHER_CALL);
|
||||
// Call to an arbitrary expression not handled specially above.
|
||||
VisitForStackValue(callee);
|
||||
__ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
|
||||
__ push(r1);
|
||||
// Emit function call.
|
||||
EmitCall(expr);
|
||||
// Push the arguments.
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// RecordJSReturnSite should have been called.
|
||||
DCHECK(expr->return_is_recorded_);
|
||||
#endif
|
||||
// Push a copy of the function (found below the arguments) and
|
||||
// resolve eval.
|
||||
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
__ push(r1);
|
||||
EmitResolvePossiblyDirectEval(arg_count);
|
||||
|
||||
// Touch up the stack with the resolved function.
|
||||
__ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
|
||||
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
|
||||
|
||||
// Record source position for debugger.
|
||||
SetCallPosition(expr, arg_count);
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
context()->DropAndPlug(1, r0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2744,89 +2744,42 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitCall(Call* expr) {
|
||||
#ifdef DEBUG
|
||||
// We want to verify that RecordJSReturnSite gets called on all paths
|
||||
// through this function. Avoid early returns.
|
||||
expr->return_is_recorded_ = false;
|
||||
#endif
|
||||
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
||||
// to resolve the function we need to call. Then we call the resolved
|
||||
// function using the given arguments.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
Comment cmnt(masm_, "[ Call");
|
||||
Expression* callee = expr->expression();
|
||||
Call::CallType call_type = expr->GetCallType(isolate());
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
|
||||
if (call_type == Call::POSSIBLY_EVAL_CALL) {
|
||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
||||
// to resolve the function we need to call. Then we call the resolved
|
||||
// function using the given arguments.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
|
||||
// Push the arguments.
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Push a copy of the function (found below the arguments) and
|
||||
// resolve eval.
|
||||
__ Peek(x10, (arg_count + 1) * kPointerSize);
|
||||
__ Push(x10);
|
||||
EmitResolvePossiblyDirectEval(arg_count);
|
||||
|
||||
// Touch up the stack with the resolved function.
|
||||
__ Poke(x0, (arg_count + 1) * kPointerSize);
|
||||
|
||||
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
|
||||
|
||||
// Record source position for debugger.
|
||||
SetCallPosition(expr, arg_count);
|
||||
|
||||
// Call the evaluated function.
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ Peek(x1, (arg_count + 1) * kXRegSize);
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
__ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
context()->DropAndPlug(1, x0);
|
||||
|
||||
} else if (call_type == Call::GLOBAL_CALL) {
|
||||
EmitCallWithLoadIC(expr);
|
||||
|
||||
} else if (call_type == Call::LOOKUP_SLOT_CALL) {
|
||||
// Call to a lookup slot (dynamically introduced variable).
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
EmitCall(expr);
|
||||
} else if (call_type == Call::NAMED_PROPERTY_CALL) {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::KEYED_PROPERTY_CALL) {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitKeyedCallWithLoadIC(expr, property->key());
|
||||
} else if (call_type == Call::NAMED_SUPER_PROPERTY_CALL) {
|
||||
EmitSuperCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::KEYED_SUPER_PROPERTY_CALL) {
|
||||
EmitKeyedSuperCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::SUPER_CALL) {
|
||||
EmitSuperConstructorCall(expr);
|
||||
} else {
|
||||
DCHECK(call_type == Call::OTHER_CALL);
|
||||
// Call to an arbitrary expression not handled specially above.
|
||||
VisitForStackValue(callee);
|
||||
__ LoadRoot(x1, Heap::kUndefinedValueRootIndex);
|
||||
__ Push(x1);
|
||||
// Emit function call.
|
||||
EmitCall(expr);
|
||||
// Push the arguments.
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// RecordJSReturnSite should have been called.
|
||||
DCHECK(expr->return_is_recorded_);
|
||||
#endif
|
||||
// Push a copy of the function (found below the arguments) and
|
||||
// resolve eval.
|
||||
__ Peek(x10, (arg_count + 1) * kPointerSize);
|
||||
__ Push(x10);
|
||||
EmitResolvePossiblyDirectEval(arg_count);
|
||||
|
||||
// Touch up the stack with the resolved function.
|
||||
__ Poke(x0, (arg_count + 1) * kPointerSize);
|
||||
|
||||
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
|
||||
|
||||
// Record source position for debugger.
|
||||
SetCallPosition(expr, arg_count);
|
||||
|
||||
// Call the evaluated function.
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ Peek(x1, (arg_count + 1) * kXRegSize);
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
__ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
context()->DropAndPlug(1, x0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1425,6 +1425,66 @@ void FullCodeGenerator::ExitTryBlock(int handler_index) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitCall(Call* expr) {
|
||||
#ifdef DEBUG
|
||||
// We want to verify that RecordJSReturnSite gets called on all paths
|
||||
// through this function. Avoid early returns.
|
||||
expr->return_is_recorded_ = false;
|
||||
#endif
|
||||
|
||||
Comment cmnt(masm_, "[ Call");
|
||||
Expression* callee = expr->expression();
|
||||
Call::CallType call_type = expr->GetCallType(isolate());
|
||||
|
||||
switch (call_type) {
|
||||
case Call::POSSIBLY_EVAL_CALL:
|
||||
EmitPossiblyEvalCall(expr);
|
||||
break;
|
||||
case Call::GLOBAL_CALL:
|
||||
EmitCallWithLoadIC(expr);
|
||||
break;
|
||||
case Call::LOOKUP_SLOT_CALL:
|
||||
// Call to a lookup slot (dynamically introduced variable).
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
EmitCall(expr);
|
||||
break;
|
||||
case Call::NAMED_PROPERTY_CALL: {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitCallWithLoadIC(expr);
|
||||
break;
|
||||
}
|
||||
case Call::KEYED_PROPERTY_CALL: {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitKeyedCallWithLoadIC(expr, property->key());
|
||||
break;
|
||||
}
|
||||
case Call::NAMED_SUPER_PROPERTY_CALL:
|
||||
EmitSuperCallWithLoadIC(expr);
|
||||
break;
|
||||
case Call::KEYED_SUPER_PROPERTY_CALL:
|
||||
EmitKeyedSuperCallWithLoadIC(expr);
|
||||
break;
|
||||
case Call::SUPER_CALL:
|
||||
EmitSuperConstructorCall(expr);
|
||||
break;
|
||||
case Call::OTHER_CALL:
|
||||
// Call to an arbitrary expression not handled specially above.
|
||||
VisitForStackValue(callee);
|
||||
__ PushRoot(Heap::kUndefinedValueRootIndex);
|
||||
// Emit function call.
|
||||
EmitCall(expr);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// RecordJSReturnSite should have been called.
|
||||
DCHECK(expr->return_is_recorded_);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); }
|
||||
|
||||
|
||||
|
@ -477,6 +477,7 @@ class FullCodeGenerator: public AstVisitor {
|
||||
void EmitSuperCallWithLoadIC(Call* expr);
|
||||
void EmitKeyedCallWithLoadIC(Call* expr, Expression* key);
|
||||
void EmitKeyedSuperCallWithLoadIC(Call* expr);
|
||||
void EmitPossiblyEvalCall(Call* expr);
|
||||
|
||||
#define FOR_EACH_FULL_CODE_INTRINSIC(F) \
|
||||
F(IsSmi) \
|
||||
|
@ -2929,83 +2929,38 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitCall(Call* expr) {
|
||||
#ifdef DEBUG
|
||||
// We want to verify that RecordJSReturnSite gets called on all paths
|
||||
// through this function. Avoid early returns.
|
||||
expr->return_is_recorded_ = false;
|
||||
#endif
|
||||
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
||||
// to resolve the function we need to call. Then we call the resolved
|
||||
// function using the given arguments.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
Comment cmnt(masm_, "[ Call");
|
||||
Expression* callee = expr->expression();
|
||||
Call::CallType call_type = expr->GetCallType(isolate());
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
|
||||
if (call_type == Call::POSSIBLY_EVAL_CALL) {
|
||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
||||
// to resolve the function we need to call. Then we call the resolved
|
||||
// function using the given arguments.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
|
||||
// Push the arguments.
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Push a copy of the function (found below the arguments) and
|
||||
// resolve eval.
|
||||
__ push(Operand(esp, (arg_count + 1) * kPointerSize));
|
||||
EmitResolvePossiblyDirectEval(arg_count);
|
||||
|
||||
// Touch up the stack with the resolved function.
|
||||
__ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
|
||||
|
||||
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
|
||||
|
||||
SetCallPosition(expr, arg_count);
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
|
||||
context()->DropAndPlug(1, eax);
|
||||
|
||||
} else if (call_type == Call::GLOBAL_CALL) {
|
||||
EmitCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::LOOKUP_SLOT_CALL) {
|
||||
// Call to a lookup slot (dynamically introduced variable).
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
EmitCall(expr);
|
||||
} else if (call_type == Call::NAMED_PROPERTY_CALL) {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::KEYED_PROPERTY_CALL) {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitKeyedCallWithLoadIC(expr, property->key());
|
||||
} else if (call_type == Call::NAMED_SUPER_PROPERTY_CALL) {
|
||||
EmitSuperCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::KEYED_SUPER_PROPERTY_CALL) {
|
||||
EmitKeyedSuperCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::SUPER_CALL) {
|
||||
EmitSuperConstructorCall(expr);
|
||||
} else {
|
||||
DCHECK(call_type == Call::OTHER_CALL);
|
||||
// Call to an arbitrary expression not handled specially above.
|
||||
VisitForStackValue(callee);
|
||||
__ push(Immediate(isolate()->factory()->undefined_value()));
|
||||
// Emit function call.
|
||||
EmitCall(expr);
|
||||
// Push the arguments.
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// RecordJSReturnSite should have been called.
|
||||
DCHECK(expr->return_is_recorded_);
|
||||
#endif
|
||||
// Push a copy of the function (found below the arguments) and
|
||||
// resolve eval.
|
||||
__ push(Operand(esp, (arg_count + 1) * kPointerSize));
|
||||
EmitResolvePossiblyDirectEval(arg_count);
|
||||
|
||||
// Touch up the stack with the resolved function.
|
||||
__ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
|
||||
|
||||
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
|
||||
|
||||
SetCallPosition(expr, arg_count);
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
|
||||
context()->DropAndPlug(1, eax);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3032,83 +3032,38 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitCall(Call* expr) {
|
||||
#ifdef DEBUG
|
||||
// We want to verify that RecordJSReturnSite gets called on all paths
|
||||
// through this function. Avoid early returns.
|
||||
expr->return_is_recorded_ = false;
|
||||
#endif
|
||||
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
||||
// to resolve the function we need to call. Then we call the resolved
|
||||
// function using the given arguments.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
|
||||
Comment cmnt(masm_, "[ Call");
|
||||
Expression* callee = expr->expression();
|
||||
Call::CallType call_type = expr->GetCallType(isolate());
|
||||
|
||||
if (call_type == Call::POSSIBLY_EVAL_CALL) {
|
||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
||||
// to resolve the function we need to call. Then we call the resolved
|
||||
// function using the given arguments.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
|
||||
// Push the arguments.
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Push a copy of the function (found below the arguments) and
|
||||
// resolve eval.
|
||||
__ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
__ push(a1);
|
||||
EmitResolvePossiblyDirectEval(arg_count);
|
||||
|
||||
// Touch up the stack with the resolved function.
|
||||
__ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
|
||||
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
|
||||
// Record source position for debugger.
|
||||
SetCallPosition(expr, arg_count);
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
context()->DropAndPlug(1, v0);
|
||||
} else if (call_type == Call::GLOBAL_CALL) {
|
||||
EmitCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::LOOKUP_SLOT_CALL) {
|
||||
// Call to a lookup slot (dynamically introduced variable).
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
EmitCall(expr);
|
||||
} else if (call_type == Call::NAMED_PROPERTY_CALL) {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::KEYED_PROPERTY_CALL) {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitKeyedCallWithLoadIC(expr, property->key());
|
||||
} else if (call_type == Call::NAMED_SUPER_PROPERTY_CALL) {
|
||||
EmitSuperCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::KEYED_SUPER_PROPERTY_CALL) {
|
||||
EmitKeyedSuperCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::SUPER_CALL) {
|
||||
EmitSuperConstructorCall(expr);
|
||||
} else {
|
||||
DCHECK(call_type == Call::OTHER_CALL);
|
||||
// Call to an arbitrary expression not handled specially above.
|
||||
VisitForStackValue(callee);
|
||||
__ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
|
||||
__ push(a1);
|
||||
// Emit function call.
|
||||
EmitCall(expr);
|
||||
// Push the arguments.
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// RecordJSReturnSite should have been called.
|
||||
DCHECK(expr->return_is_recorded_);
|
||||
#endif
|
||||
// Push a copy of the function (found below the arguments) and
|
||||
// resolve eval.
|
||||
__ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
__ push(a1);
|
||||
EmitResolvePossiblyDirectEval(arg_count);
|
||||
|
||||
// Touch up the stack with the resolved function.
|
||||
__ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
|
||||
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
|
||||
// Record source position for debugger.
|
||||
SetCallPosition(expr, arg_count);
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
context()->DropAndPlug(1, v0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3034,83 +3034,38 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitCall(Call* expr) {
|
||||
#ifdef DEBUG
|
||||
// We want to verify that RecordJSReturnSite gets called on all paths
|
||||
// through this function. Avoid early returns.
|
||||
expr->return_is_recorded_ = false;
|
||||
#endif
|
||||
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
||||
// to resolve the function we need to call. Then we call the resolved
|
||||
// function using the given arguments.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
|
||||
Comment cmnt(masm_, "[ Call");
|
||||
Expression* callee = expr->expression();
|
||||
Call::CallType call_type = expr->GetCallType(isolate());
|
||||
|
||||
if (call_type == Call::POSSIBLY_EVAL_CALL) {
|
||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
||||
// to resolve the function we need to call. Then we call the resolved
|
||||
// function using the given arguments.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
|
||||
// Push the arguments.
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Push a copy of the function (found below the arguments) and
|
||||
// resolve eval.
|
||||
__ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
__ push(a1);
|
||||
EmitResolvePossiblyDirectEval(arg_count);
|
||||
|
||||
// Touch up the stack with the resolved function.
|
||||
__ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
|
||||
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
|
||||
// Record source position for debugger.
|
||||
SetCallPosition(expr, arg_count);
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
__ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
context()->DropAndPlug(1, v0);
|
||||
} else if (call_type == Call::GLOBAL_CALL) {
|
||||
EmitCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::LOOKUP_SLOT_CALL) {
|
||||
// Call to a lookup slot (dynamically introduced variable).
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
EmitCall(expr);
|
||||
} else if (call_type == Call::NAMED_PROPERTY_CALL) {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::KEYED_PROPERTY_CALL) {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitKeyedCallWithLoadIC(expr, property->key());
|
||||
} else if (call_type == Call::NAMED_SUPER_PROPERTY_CALL) {
|
||||
EmitSuperCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::KEYED_SUPER_PROPERTY_CALL) {
|
||||
EmitKeyedSuperCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::SUPER_CALL) {
|
||||
EmitSuperConstructorCall(expr);
|
||||
} else {
|
||||
DCHECK(call_type == Call::OTHER_CALL);
|
||||
// Call to an arbitrary expression not handled specially above.
|
||||
VisitForStackValue(callee);
|
||||
__ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
|
||||
__ push(a1);
|
||||
// Emit function call.
|
||||
EmitCall(expr);
|
||||
// Push the arguments.
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// RecordJSReturnSite should have been called.
|
||||
DCHECK(expr->return_is_recorded_);
|
||||
#endif
|
||||
// Push a copy of the function (found below the arguments) and
|
||||
// resolve eval.
|
||||
__ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
__ push(a1);
|
||||
EmitResolvePossiblyDirectEval(arg_count);
|
||||
|
||||
// Touch up the stack with the resolved function.
|
||||
__ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
|
||||
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
|
||||
// Record source position for debugger.
|
||||
SetCallPosition(expr, arg_count);
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
__ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
context()->DropAndPlug(1, v0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3033,86 +3033,40 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitCall(Call* expr) {
|
||||
#ifdef DEBUG
|
||||
// We want to verify that RecordJSReturnSite gets called on all paths
|
||||
// through this function. Avoid early returns.
|
||||
expr->return_is_recorded_ = false;
|
||||
#endif
|
||||
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
||||
// to resolve the function we need to call. Then we call the resolved
|
||||
// function using the given arguments.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
Comment cmnt(masm_, "[ Call");
|
||||
Expression* callee = expr->expression();
|
||||
Call::CallType call_type = expr->GetCallType(isolate());
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
|
||||
if (call_type == Call::POSSIBLY_EVAL_CALL) {
|
||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
||||
// to resolve the function we need to call. Then we call the resolved
|
||||
// function using the given arguments.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
|
||||
// Push the arguments.
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Push a copy of the function (found below the arguments) and
|
||||
// resolve eval.
|
||||
__ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
||||
__ push(r4);
|
||||
EmitResolvePossiblyDirectEval(arg_count);
|
||||
|
||||
// Touch up the stack with the resolved function.
|
||||
__ StoreP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
||||
|
||||
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
|
||||
|
||||
// Record source position for debugger.
|
||||
SetCallPosition(expr, arg_count);
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
__ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
context()->DropAndPlug(1, r3);
|
||||
} else if (call_type == Call::GLOBAL_CALL) {
|
||||
EmitCallWithLoadIC(expr);
|
||||
|
||||
} else if (call_type == Call::LOOKUP_SLOT_CALL) {
|
||||
// Call to a lookup slot (dynamically introduced variable).
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
EmitCall(expr);
|
||||
} else if (call_type == Call::NAMED_PROPERTY_CALL) {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::KEYED_PROPERTY_CALL) {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitKeyedCallWithLoadIC(expr, property->key());
|
||||
} else if (call_type == Call::NAMED_SUPER_PROPERTY_CALL) {
|
||||
EmitSuperCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::KEYED_SUPER_PROPERTY_CALL) {
|
||||
EmitKeyedSuperCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::SUPER_CALL) {
|
||||
EmitSuperConstructorCall(expr);
|
||||
} else {
|
||||
DCHECK(call_type == Call::OTHER_CALL);
|
||||
// Call to an arbitrary expression not handled specially above.
|
||||
VisitForStackValue(callee);
|
||||
__ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
|
||||
__ push(r4);
|
||||
// Emit function call.
|
||||
EmitCall(expr);
|
||||
// Push the arguments.
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// RecordJSReturnSite should have been called.
|
||||
DCHECK(expr->return_is_recorded_);
|
||||
#endif
|
||||
// Push a copy of the function (found below the arguments) and
|
||||
// resolve eval.
|
||||
__ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
||||
__ push(r4);
|
||||
EmitResolvePossiblyDirectEval(arg_count);
|
||||
|
||||
// Touch up the stack with the resolved function.
|
||||
__ StoreP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
||||
|
||||
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
|
||||
|
||||
// Record source position for debugger.
|
||||
SetCallPosition(expr, arg_count);
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
__ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
context()->DropAndPlug(1, r3);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2921,82 +2921,37 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitCall(Call* expr) {
|
||||
#ifdef DEBUG
|
||||
// We want to verify that RecordJSReturnSite gets called on all paths
|
||||
// through this function. Avoid early returns.
|
||||
expr->return_is_recorded_ = false;
|
||||
#endif
|
||||
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
||||
// to resolve the function we need to call. Then we call the resolved
|
||||
// function using the given arguments.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
|
||||
Comment cmnt(masm_, "[ Call");
|
||||
Expression* callee = expr->expression();
|
||||
Call::CallType call_type = expr->GetCallType(isolate());
|
||||
|
||||
if (call_type == Call::POSSIBLY_EVAL_CALL) {
|
||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
||||
// to resolve the function we need to call. Then we call the resolved
|
||||
// function using the given arguments.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
|
||||
// Push the arguments.
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Push a copy of the function (found below the arguments) and resolve
|
||||
// eval.
|
||||
__ Push(Operand(rsp, (arg_count + 1) * kPointerSize));
|
||||
EmitResolvePossiblyDirectEval(arg_count);
|
||||
|
||||
// Touch up the callee.
|
||||
__ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax);
|
||||
|
||||
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
|
||||
|
||||
SetCallPosition(expr, arg_count);
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
__ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
||||
context()->DropAndPlug(1, rax);
|
||||
} else if (call_type == Call::GLOBAL_CALL) {
|
||||
EmitCallWithLoadIC(expr);
|
||||
|
||||
} else if (call_type == Call::LOOKUP_SLOT_CALL) {
|
||||
// Call to a lookup slot (dynamically introduced variable).
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
EmitCall(expr);
|
||||
} else if (call_type == Call::NAMED_PROPERTY_CALL) {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::KEYED_PROPERTY_CALL) {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitKeyedCallWithLoadIC(expr, property->key());
|
||||
} else if (call_type == Call::NAMED_SUPER_PROPERTY_CALL) {
|
||||
EmitSuperCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::KEYED_SUPER_PROPERTY_CALL) {
|
||||
EmitKeyedSuperCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::SUPER_CALL) {
|
||||
EmitSuperConstructorCall(expr);
|
||||
} else {
|
||||
DCHECK(call_type == Call::OTHER_CALL);
|
||||
// Call to an arbitrary expression not handled specially above.
|
||||
VisitForStackValue(callee);
|
||||
__ PushRoot(Heap::kUndefinedValueRootIndex);
|
||||
// Emit function call.
|
||||
EmitCall(expr);
|
||||
// Push the arguments.
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// RecordJSReturnSite should have been called.
|
||||
DCHECK(expr->return_is_recorded_);
|
||||
#endif
|
||||
// Push a copy of the function (found below the arguments) and resolve
|
||||
// eval.
|
||||
__ Push(Operand(rsp, (arg_count + 1) * kPointerSize));
|
||||
EmitResolvePossiblyDirectEval(arg_count);
|
||||
|
||||
// Touch up the callee.
|
||||
__ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax);
|
||||
|
||||
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
|
||||
|
||||
SetCallPosition(expr, arg_count);
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
__ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
||||
context()->DropAndPlug(1, rax);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2922,83 +2922,38 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitCall(Call* expr) {
|
||||
#ifdef DEBUG
|
||||
// We want to verify that RecordJSReturnSite gets called on all paths
|
||||
// through this function. Avoid early returns.
|
||||
expr->return_is_recorded_ = false;
|
||||
#endif
|
||||
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
||||
// to resolve the function we need to call. Then we call the resolved
|
||||
// function using the given arguments.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
Comment cmnt(masm_, "[ Call");
|
||||
Expression* callee = expr->expression();
|
||||
Call::CallType call_type = expr->GetCallType(isolate());
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
|
||||
if (call_type == Call::POSSIBLY_EVAL_CALL) {
|
||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
||||
// to resolve the function we need to call. Then we call the resolved
|
||||
// function using the given arguments.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
|
||||
// Push the arguments.
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Push a copy of the function (found below the arguments) and
|
||||
// resolve eval.
|
||||
__ push(Operand(esp, (arg_count + 1) * kPointerSize));
|
||||
EmitResolvePossiblyDirectEval(arg_count);
|
||||
|
||||
// Touch up the stack with the resolved function.
|
||||
__ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
|
||||
|
||||
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
|
||||
|
||||
SetCallPosition(expr, arg_count);
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
|
||||
context()->DropAndPlug(1, eax);
|
||||
|
||||
} else if (call_type == Call::GLOBAL_CALL) {
|
||||
EmitCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::LOOKUP_SLOT_CALL) {
|
||||
// Call to a lookup slot (dynamically introduced variable).
|
||||
PushCalleeAndWithBaseObject(expr);
|
||||
EmitCall(expr);
|
||||
} else if (call_type == Call::NAMED_PROPERTY_CALL) {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::KEYED_PROPERTY_CALL) {
|
||||
Property* property = callee->AsProperty();
|
||||
VisitForStackValue(property->obj());
|
||||
EmitKeyedCallWithLoadIC(expr, property->key());
|
||||
} else if (call_type == Call::NAMED_SUPER_PROPERTY_CALL) {
|
||||
EmitSuperCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::KEYED_SUPER_PROPERTY_CALL) {
|
||||
EmitKeyedSuperCallWithLoadIC(expr);
|
||||
} else if (call_type == Call::SUPER_CALL) {
|
||||
EmitSuperConstructorCall(expr);
|
||||
} else {
|
||||
DCHECK(call_type == Call::OTHER_CALL);
|
||||
// Call to an arbitrary expression not handled specially above.
|
||||
VisitForStackValue(callee);
|
||||
__ push(Immediate(isolate()->factory()->undefined_value()));
|
||||
// Emit function call.
|
||||
EmitCall(expr);
|
||||
// Push the arguments.
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// RecordJSReturnSite should have been called.
|
||||
DCHECK(expr->return_is_recorded_);
|
||||
#endif
|
||||
// Push a copy of the function (found below the arguments) and
|
||||
// resolve eval.
|
||||
__ push(Operand(esp, (arg_count + 1) * kPointerSize));
|
||||
EmitResolvePossiblyDirectEval(arg_count);
|
||||
|
||||
// Touch up the stack with the resolved function.
|
||||
__ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
|
||||
|
||||
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
|
||||
|
||||
SetCallPosition(expr, arg_count);
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
|
||||
context()->DropAndPlug(1, eax);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user