diff options
Diffstat (limited to 'deps/v8/src/ia32/full-codegen-ia32.cc')
-rw-r--r-- | deps/v8/src/ia32/full-codegen-ia32.cc | 71 |
1 files changed, 55 insertions, 16 deletions
diff --git a/deps/v8/src/ia32/full-codegen-ia32.cc b/deps/v8/src/ia32/full-codegen-ia32.cc index f71a76dd09..5a780197c3 100644 --- a/deps/v8/src/ia32/full-codegen-ia32.cc +++ b/deps/v8/src/ia32/full-codegen-ia32.cc @@ -1529,7 +1529,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; int properties_count = constant_properties->length() / 2; - if (expr->depth() > 1) { + if ((FLAG_track_double_fields && expr->may_store_doubles()) || + expr->depth() > 1) { __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); __ push(FieldOperand(edi, JSFunction::kLiteralsOffset)); __ push(Immediate(Smi::FromInt(expr->literal_index()))); @@ -1900,11 +1901,12 @@ void FullCodeGenerator::VisitYield(Yield* expr) { Label resume; __ CompareRoot(result_register(), Heap::kTheHoleValueRootIndex); __ j(not_equal, &resume); - __ pop(result_register()); if (expr->yield_kind() == Yield::SUSPEND) { - // TODO(wingo): Box into { value: VALUE, done: false }. + EmitReturnIteratorResult(false); + } else { + __ pop(result_register()); + EmitReturnSequence(); } - EmitReturnSequence(); __ bind(&resume); context()->Plug(result_register()); @@ -1916,18 +1918,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) { __ mov(FieldOperand(result_register(), JSGeneratorObject::kContinuationOffset), Immediate(Smi::FromInt(JSGeneratorObject::kGeneratorClosed))); - __ pop(result_register()); - // TODO(wingo): Box into { value: VALUE, done: true }. - - // 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(); + EmitReturnIteratorResult(true); break; } @@ -2033,6 +2024,54 @@ void FullCodeGenerator::EmitGeneratorResume(Expression *generator, } +void FullCodeGenerator::EmitReturnIteratorResult(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); + + __ bind(&allocated); + __ mov(ebx, map); + __ pop(ecx); + __ mov(edx, isolate()->factory()->ToBoolean(done)); + ASSERT_EQ(map->instance_size(), 5 * kPointerSize); + __ mov(FieldOperand(eax, HeapObject::kMapOffset), ebx); + __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), + isolate()->factory()->empty_fixed_array()); + __ mov(FieldOperand(eax, JSObject::kElementsOffset), + isolate()->factory()->empty_fixed_array()); + __ mov(FieldOperand(eax, JSGeneratorObject::kResultValuePropertyOffset), ecx); + __ mov(FieldOperand(eax, JSGeneratorObject::kResultDonePropertyOffset), edx); + + // Only the value field needs a write barrier, as the other values are in the + // 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); +} + + void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { SetSourcePosition(prop->position()); Literal* key = prop->key()->AsLiteral(); |