Chromium Code Reviews| Index: src/ia32/full-codegen-ia32.cc |
| diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc |
| index c77faaad80e06a31c8e10b326bcbeff1465e9fbb..0763620b6d4e0e0b52d9737bdee61160fae310f5 100644 |
| --- a/src/ia32/full-codegen-ia32.cc |
| +++ b/src/ia32/full-codegen-ia32.cc |
| @@ -1952,6 +1952,11 @@ void FullCodeGenerator::VisitYield(Yield* expr) { |
| switch (expr->yield_kind()) { |
| case Yield::INITIAL: |
| case Yield::SUSPEND: { |
| + if (expr->yield_kind() == Yield::SUSPEND) { |
|
Michael Starzinger
2013/06/12 10:47:56
This can be modeled by flipping the two cases abov
|
| + // Pop value from top-of-stack slot, box result into result register. |
| + EmitCreateIteratorResult(false); |
| + __ push(result_register()); |
| + } |
| VisitForStackValue(expr->generator_object()); |
| __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
| __ mov(context_register(), |
| @@ -1960,12 +1965,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) { |
| Label resume; |
| __ CompareRoot(result_register(), Heap::kTheHoleValueRootIndex); |
| __ j(not_equal, &resume); |
| - if (expr->yield_kind() == Yield::SUSPEND) { |
| - EmitReturnIteratorResult(false); |
| - } else { |
| - __ pop(result_register()); |
| - EmitReturnSequence(); |
| - } |
| + __ pop(result_register()); |
| + EmitReturnSequence(); |
| __ bind(&resume); |
| context()->Plug(result_register()); |
| @@ -1977,7 +1978,10 @@ void FullCodeGenerator::VisitYield(Yield* expr) { |
| __ mov(FieldOperand(result_register(), |
| JSGeneratorObject::kContinuationOffset), |
| Immediate(Smi::FromInt(JSGeneratorObject::kGeneratorClosed))); |
| - EmitReturnIteratorResult(true); |
| + // Pop value from top-of-stack slot, box result into result register. |
| + EmitCreateIteratorResult(true); |
| + EmitUnwindBeforeReturn(); |
| + EmitReturnSequence(); |
| break; |
| } |
| @@ -2006,17 +2010,18 @@ void FullCodeGenerator::VisitYield(Yield* expr) { |
| // try { received = yield result.value } |
| __ bind(&l_try); |
| - __ pop(eax); // result.value |
| + EmitCreateIteratorResult(false); // pop and box to eax |
| __ PushTryHandler(StackHandler::CATCH, expr->index()); |
| const int handler_size = StackHandlerConstants::kSize; |
| - __ push(eax); // result.value |
| + __ push(eax); // result |
| __ push(Operand(esp, (0 + 1) * kPointerSize + handler_size)); // g |
| __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
| __ mov(context_register(), |
| Operand(ebp, StandardFrameConstants::kContextOffset)); |
| __ CompareRoot(eax, Heap::kTheHoleValueRootIndex); |
| __ j(not_equal, &l_resume); |
| - EmitReturnIteratorResult(false); |
| + __ pop(eax); // result |
| + EmitReturnSequence(); |
| __ bind(&l_resume); // received in eax |
| __ PopTryHandler(); |
| @@ -2169,13 +2174,20 @@ void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
| } |
| -void FullCodeGenerator::EmitReturnIteratorResult(bool done) { |
| +void FullCodeGenerator::EmitCreateIteratorResult(bool done) { |
| Label gc_required; |
| Label allocated; |
| Handle<Map> map(isolate()->native_context()->generator_result_map()); |
| __ Allocate(map->instance_size(), eax, ecx, edx, &gc_required, TAG_OBJECT); |
| + __ jmp(&allocated); |
| + |
| + __ bind(&gc_required); |
| + __ Push(Smi::FromInt(map->instance_size())); |
| + __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
| + __ mov(context_register(), |
| + Operand(ebp, StandardFrameConstants::kContextOffset)); |
| __ bind(&allocated); |
| __ mov(ebx, map); |
| @@ -2194,26 +2206,6 @@ void FullCodeGenerator::EmitReturnIteratorResult(bool done) { |
| // root set. |
| __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, |
| ecx, edx, kDontSaveFPRegs); |
| - |
| - if (done) { |
| - // Exit all nested statements. |
| - NestedStatement* current = nesting_stack_; |
| - int stack_depth = 0; |
| - int context_length = 0; |
| - while (current != NULL) { |
| - current = current->Exit(&stack_depth, &context_length); |
| - } |
| - __ Drop(stack_depth); |
| - } |
| - |
| - EmitReturnSequence(); |
| - |
| - __ bind(&gc_required); |
| - __ Push(Smi::FromInt(map->instance_size())); |
| - __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
| - __ mov(context_register(), |
| - Operand(ebp, StandardFrameConstants::kContextOffset)); |
| - __ jmp(&allocated); |
| } |