| Index: src/ia32/full-codegen-ia32.cc
|
| diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
|
| index 1ba409571534ee945cf8a3d16e972c61c5bcb1c4..7e2e21b39a75ae9c55161465a010e934dccadcab 100644
|
| --- a/src/ia32/full-codegen-ia32.cc
|
| +++ b/src/ia32/full-codegen-ia32.cc
|
| @@ -144,40 +144,7 @@ void FullCodeGenerator::Generate() {
|
| int locals_count = info->scope()->num_stack_slots();
|
| // Generators allocate locals, if any, in context slots.
|
| DCHECK(!info->function()->is_generator() || locals_count == 0);
|
| - if (locals_count == 1) {
|
| - __ push(Immediate(isolate()->factory()->undefined_value()));
|
| - } else if (locals_count > 1) {
|
| - if (locals_count >= 128) {
|
| - Label ok;
|
| - __ mov(ecx, esp);
|
| - __ sub(ecx, Immediate(locals_count * kPointerSize));
|
| - ExternalReference stack_limit =
|
| - ExternalReference::address_of_real_stack_limit(isolate());
|
| - __ cmp(ecx, Operand::StaticVariable(stack_limit));
|
| - __ j(above_equal, &ok, Label::kNear);
|
| - __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
| - __ bind(&ok);
|
| - }
|
| - __ mov(eax, Immediate(isolate()->factory()->undefined_value()));
|
| - const int kMaxPushes = 32;
|
| - if (locals_count >= kMaxPushes) {
|
| - int loop_iterations = locals_count / kMaxPushes;
|
| - __ mov(ecx, loop_iterations);
|
| - Label loop_header;
|
| - __ bind(&loop_header);
|
| - // Do pushes.
|
| - for (int i = 0; i < kMaxPushes; i++) {
|
| - __ push(eax);
|
| - }
|
| - __ dec(ecx);
|
| - __ j(not_zero, &loop_header, Label::kNear);
|
| - }
|
| - int remaining = locals_count % kMaxPushes;
|
| - // Emit the remaining pushes.
|
| - for (int i = 0; i < remaining; i++) {
|
| - __ push(eax);
|
| - }
|
| - }
|
| + AllocateLocals(locals_count);
|
| }
|
|
|
| bool function_in_register = true;
|
| @@ -322,6 +289,51 @@ void FullCodeGenerator::Generate() {
|
| }
|
|
|
|
|
| +void FullCodeGenerator::AllocateLocals(int locals_count) {
|
| + if (locals_count == 1) {
|
| + __ push(Immediate(isolate()->factory()->undefined_value()));
|
| + } else if (locals_count > 1) {
|
| + if (locals_count >= 128) {
|
| + Label ok;
|
| + __ mov(ecx, esp);
|
| + __ sub(ecx, Immediate(locals_count * kPointerSize));
|
| + ExternalReference stack_limit =
|
| + ExternalReference::address_of_real_stack_limit(isolate());
|
| + __ cmp(ecx, Operand::StaticVariable(stack_limit));
|
| + __ j(above_equal, &ok, Label::kNear);
|
| + __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
| + __ bind(&ok);
|
| + }
|
| + __ mov(eax, Immediate(isolate()->factory()->undefined_value()));
|
| + const int kMaxPushes = 32;
|
| + if (locals_count >= kMaxPushes) {
|
| + int loop_iterations = locals_count / kMaxPushes;
|
| + __ mov(ecx, loop_iterations);
|
| + Label loop_header;
|
| + __ bind(&loop_header);
|
| + // Do pushes.
|
| + for (int i = 0; i < kMaxPushes; i++) {
|
| + __ push(eax);
|
| + }
|
| + __ dec(ecx);
|
| + __ j(not_zero, &loop_header, Label::kNear);
|
| + }
|
| + int remaining = locals_count % kMaxPushes;
|
| + // Emit the remaining pushes.
|
| + for (int i = 0; i < remaining; i++) {
|
| + __ push(eax);
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +void FullCodeGenerator::DeallocateLocals(int local_count) {
|
| + if (local_count > 0) {
|
| + __ add(esp, Immediate(local_count * kPointerSize));
|
| + }
|
| +}
|
| +
|
| +
|
| void FullCodeGenerator::ClearAccumulator() {
|
| __ Move(eax, Immediate(Smi::FromInt(0)));
|
| }
|
| @@ -665,6 +677,11 @@ MemOperand FullCodeGenerator::StackOperand(Variable* var) {
|
| DCHECK(var->IsStackAllocated());
|
| // Offset is negative because higher indexes are at lower addresses.
|
| int offset = -var->index() * kPointerSize;
|
| + Scope* var_scope = var->scope();
|
| + while (!var_scope->is_function_scope() && !var_scope->is_script_scope()) {
|
| + var_scope = var_scope->outer_scope();
|
| + offset -= var_scope->num_stack_slots() * kPointerSize;
|
| + }
|
| // Adjust by a (parameter or local) base offset.
|
| if (var->IsParameter()) {
|
| offset += (info_->scope()->num_parameters() + 1) * kPointerSize;
|
|
|