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; |
} |