}
}
+ // Possibly allocate a local context.
+ if (fun->scope()->num_heap_slots() > 0) {
+ Comment cmnt(masm_, "[ Allocate local context");
+ // Argument to NewContext is the function, still in r1.
+ __ push(r1);
+ __ CallRuntime(Runtime::kNewContext, 1);
+ // Context is returned in both r0 and cp. It replaces the context
+ // passed to us. It's saved in the stack and kept live in cp.
+ __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+#ifdef DEBUG
+ // Assert we do not have to copy any parameters into the context.
+ for (int i = 0, len = fun->scope()->num_parameters(); i < len; i++) {
+ Slot* slot = fun->scope()->parameter(i)->slot();
+ ASSERT(slot != NULL && slot->type() != Slot::CONTEXT);
+ }
+#endif
+ }
+
// Check the stack for overflow or break request.
// Put the lr setup instruction in the delay slot. The kInstrSize is
// added to the implicit 8 byte offset that always applies to operations
CodeGenSelector::CodeGenTag CodeGenSelector::Select(FunctionLiteral* fun) {
Scope* scope = fun->scope();
+
+ if (scope->num_heap_slots() > 0) {
+ // We support functions with a local context if they do not have
+ // parameters that need to be copied into the context.
+ for (int i = 0, len = scope->num_parameters(); i < len; i++) {
+ Slot* slot = scope->parameter(i)->slot();
+ if (slot != NULL && slot->type() == Slot::CONTEXT) {
+ if (FLAG_trace_bailout) {
+ PrintF("function has context-allocated parameters");
+ }
+ return NORMAL;
+ }
+ }
+ }
+
if (scope->num_heap_slots() != 0) {
if (FLAG_trace_bailout) PrintF("function has context slots\n");
return NORMAL;
}
}
+ // Possibly allocate a local context.
+ if (fun->scope()->num_heap_slots() > 0) {
+ Comment cmnt(masm_, "[ Allocate local context");
+ // Argument to NewContext is the function, still in edi.
+ __ push(edi);
+ __ CallRuntime(Runtime::kNewContext, 1);
+ // Context is returned in both eax and esi. It replaces the context
+ // passed to us. It's saved in the stack and kept live in esi.
+ __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi);
+#ifdef DEBUG
+ // Assert we do not have to copy any parameters into the context.
+ for (int i = 0, len = fun->scope()->num_parameters(); i < len; i++) {
+ Slot* slot = fun->scope()->parameter(i)->slot();
+ ASSERT(slot != NULL && slot->type() != Slot::CONTEXT);
+ }
+#endif
+ }
+
{ Comment cmnt(masm_, "[ Declarations");
VisitDeclarations(fun->scope()->declarations());
}
}
}
+ // Possibly allocate a local context.
+ if (fun->scope()->num_heap_slots() > 0) {
+ Comment cmnt(masm_, "[ Allocate local context");
+ // Argument to NewContext is the function, still in rdi.
+ __ push(rdi);
+ __ CallRuntime(Runtime::kNewContext, 1);
+ // 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.
+ __ movq(Operand(rbp, StandardFrameConstants::kContextOffset), rsi);
+#ifdef DEBUG
+ // Assert we do not have to copy any parameters into the context.
+ for (int i = 0, len = fun->scope()->num_parameters(); i < len; i++) {
+ Slot* slot = fun->scope()->parameter(i)->slot();
+ ASSERT(slot != NULL && slot->type() != Slot::CONTEXT);
+ }
+#endif
+ }
+
{ Comment cmnt(masm_, "[ Stack check");
Label ok;
__ CompareRoot(rsp, Heap::kStackLimitRootIndex);