| Index: src/x64/full-codegen-x64.cc
|
| ===================================================================
|
| --- src/x64/full-codegen-x64.cc (revision 3911)
|
| +++ src/x64/full-codegen-x64.cc (working copy)
|
| @@ -81,7 +81,7 @@
|
| Comment cmnt(masm_, "[ Allocate local context");
|
| // Argument to NewContext is the function, which is still in rdi.
|
| __ push(rdi);
|
| - __ CallRuntime(Runtime::kNewContext, 1);
|
| + EmitCallRuntime(Runtime::kNewContext, 1);
|
| function_in_register = false;
|
| // Context is returned in both rax and rsi. It replaces the context
|
| // passed to us. It's saved in the stack and kept live in rsi.
|
| @@ -154,7 +154,7 @@
|
| }
|
|
|
| if (FLAG_trace) {
|
| - __ CallRuntime(Runtime::kTraceEnter, 0);
|
| + EmitCallRuntime(Runtime::kTraceEnter, 0);
|
| }
|
|
|
| { Comment cmnt(masm_, "[ Body");
|
| @@ -179,7 +179,7 @@
|
| __ bind(&return_label_);
|
| if (FLAG_trace) {
|
| __ push(rax);
|
| - __ CallRuntime(Runtime::kTraceExit, 1);
|
| + EmitCallRuntime(Runtime::kTraceExit, 1);
|
| }
|
| #ifdef DEBUG
|
| // Add a label for checking the size of the code used for returning.
|
| @@ -733,7 +733,7 @@
|
| } else {
|
| __ Push(Smi::FromInt(0)); // no initial value!
|
| }
|
| - __ CallRuntime(Runtime::kDeclareContextSlot, 4);
|
| + EmitCallRuntime(Runtime::kDeclareContextSlot, 4);
|
| break;
|
| }
|
| }
|
| @@ -770,7 +770,7 @@
|
| __ push(rsi); // The context is the first argument.
|
| __ Push(pairs);
|
| __ Push(Smi::FromInt(is_eval() ? 1 : 0));
|
| - __ CallRuntime(Runtime::kDeclareGlobals, 3);
|
| + EmitCallRuntime(Runtime::kDeclareGlobals, 3);
|
| // Return value is ignored.
|
| }
|
|
|
| @@ -788,7 +788,7 @@
|
| // Create a new closure.
|
| __ push(rsi);
|
| __ Push(boilerplate);
|
| - __ CallRuntime(Runtime::kNewClosure, 2);
|
| + EmitCallRuntime(Runtime::kNewClosure, 2);
|
| Apply(context_, rax);
|
| }
|
|
|
| @@ -825,7 +825,7 @@
|
| Comment cmnt(masm_, "Lookup slot");
|
| __ push(rsi); // Context.
|
| __ Push(var->name());
|
| - __ CallRuntime(Runtime::kLoadContextSlot, 2);
|
| + EmitCallRuntime(Runtime::kLoadContextSlot, 2);
|
| Apply(context, rax);
|
|
|
| } else if (slot != NULL) {
|
| @@ -889,7 +889,7 @@
|
| __ Push(Smi::FromInt(expr->literal_index()));
|
| __ Push(expr->pattern());
|
| __ Push(expr->flags());
|
| - __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
|
| + EmitCallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
|
| __ bind(&done);
|
| Apply(context_, rax);
|
| }
|
| @@ -902,9 +902,9 @@
|
| __ Push(Smi::FromInt(expr->literal_index()));
|
| __ Push(expr->constant_properties());
|
| if (expr->depth() > 1) {
|
| - __ CallRuntime(Runtime::kCreateObjectLiteral, 3);
|
| + EmitCallRuntime(Runtime::kCreateObjectLiteral, 3);
|
| } else {
|
| - __ CallRuntime(Runtime::kCreateObjectLiteralShallow, 3);
|
| + EmitCallRuntime(Runtime::kCreateObjectLiteralShallow, 3);
|
| }
|
|
|
| // If result_saved is true the result is on top of the stack. If
|
| @@ -942,7 +942,7 @@
|
| __ push(Operand(rsp, 0)); // Duplicate receiver.
|
| VisitForValue(key, kStack);
|
| VisitForValue(value, kStack);
|
| - __ CallRuntime(Runtime::kSetProperty, 3);
|
| + EmitCallRuntime(Runtime::kSetProperty, 3);
|
| break;
|
| case ObjectLiteral::Property::SETTER:
|
| case ObjectLiteral::Property::GETTER:
|
| @@ -952,7 +952,7 @@
|
| Smi::FromInt(1) :
|
| Smi::FromInt(0));
|
| VisitForValue(value, kStack);
|
| - __ CallRuntime(Runtime::kDefineAccessor, 4);
|
| + EmitCallRuntime(Runtime::kDefineAccessor, 4);
|
| break;
|
| }
|
| }
|
| @@ -972,9 +972,9 @@
|
| __ Push(Smi::FromInt(expr->literal_index()));
|
| __ Push(expr->constant_elements());
|
| if (expr->depth() > 1) {
|
| - __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
|
| + EmitCallRuntime(Runtime::kCreateArrayLiteral, 3);
|
| } else {
|
| - __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
|
| + EmitCallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
|
| }
|
|
|
| bool result_saved = false; // Is the result saved to the stack?
|
| @@ -1153,7 +1153,7 @@
|
| __ push(result_register()); // Value.
|
| __ push(rsi); // Context.
|
| __ Push(var->name());
|
| - __ CallRuntime(Runtime::kStoreContextSlot, 3);
|
| + EmitCallRuntime(Runtime::kStoreContextSlot, 3);
|
| Apply(context, rax);
|
|
|
| } else if (var->slot() != NULL) {
|
| @@ -1200,7 +1200,7 @@
|
| if (expr->starts_initialization_block()) {
|
| __ push(result_register());
|
| __ push(Operand(rsp, kPointerSize)); // Receiver is now under value.
|
| - __ CallRuntime(Runtime::kToSlowProperties, 1);
|
| + EmitCallRuntime(Runtime::kToSlowProperties, 1);
|
| __ pop(result_register());
|
| }
|
|
|
| @@ -1220,7 +1220,7 @@
|
| if (expr->ends_initialization_block()) {
|
| __ push(rax); // Result of assignment, saved even if not needed.
|
| __ push(Operand(rsp, kPointerSize)); // Receiver is under value.
|
| - __ CallRuntime(Runtime::kToFastProperties, 1);
|
| + EmitCallRuntime(Runtime::kToFastProperties, 1);
|
| __ pop(rax);
|
| DropAndApply(1, context_, rax);
|
| } else {
|
| @@ -1239,7 +1239,7 @@
|
| __ push(result_register());
|
| // Receiver is now under the key and value.
|
| __ push(Operand(rsp, 2 * kPointerSize));
|
| - __ CallRuntime(Runtime::kToSlowProperties, 1);
|
| + EmitCallRuntime(Runtime::kToSlowProperties, 1);
|
| __ pop(result_register());
|
| }
|
|
|
| @@ -1256,7 +1256,7 @@
|
| __ push(rax); // Result of assignment, saved even if not needed.
|
| // Receiver is under the key and value.
|
| __ push(Operand(rsp, 2 * kPointerSize));
|
| - __ CallRuntime(Runtime::kToFastProperties, 1);
|
| + EmitCallRuntime(Runtime::kToFastProperties, 1);
|
| __ pop(rax);
|
| }
|
|
|
| @@ -1458,12 +1458,38 @@
|
| // Restore context register.
|
| __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
| } else {
|
| - __ CallRuntime(expr->function(), arg_count);
|
| + EmitCallRuntime(expr->function(), arg_count);
|
| }
|
| Apply(context_, rax);
|
| }
|
|
|
|
|
| +void FullCodeGenerator::EmitCallRuntime(Runtime::FunctionId id, int arg_count) {
|
| + EmitCallRuntime(Runtime::FunctionForId(id), arg_count);
|
| +}
|
| +
|
| +
|
| +void FullCodeGenerator::EmitCallRuntime(Runtime::Function* f, int arg_count) {
|
| + if (Runtime::DIRECT_CALL_NOT_FAILS == f->calling_convention) {
|
| + if (arg_count > kCArgRegsCount) {
|
| + __ IllegalOperation(arg_count);
|
| + __ Drop(arg_count);
|
| + return;
|
| + }
|
| + for (int i = arg_count - 1; i >= 0; i--) {
|
| + __ pop(kCArgRegs[i]);
|
| + }
|
| + }
|
| +
|
| + __ CallRuntime(f, arg_count);
|
| +
|
| + if (Runtime::DIRECT_CALL_NOT_FAILS == f->calling_convention) {
|
| + // Restore context register.
|
| + __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
| + }
|
| +}
|
| +
|
| +
|
| void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
| switch (expr->op()) {
|
| case Token::VOID: {
|
| @@ -1556,14 +1582,14 @@
|
| proxy->var()->slot()->type() == Slot::LOOKUP) {
|
| __ push(rsi);
|
| __ Push(proxy->name());
|
| - __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
|
| + EmitCallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
|
| __ push(rax);
|
| } else {
|
| // This expression cannot throw a reference error at the top level.
|
| VisitForValue(expr->expression(), kStack);
|
| }
|
|
|
| - __ CallRuntime(Runtime::kTypeof, 1);
|
| + EmitCallRuntime(Runtime::kTypeof, 1);
|
| Apply(context_, rax);
|
| break;
|
| }
|
|
|