OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1917 case Yield::INITIAL: | 1917 case Yield::INITIAL: |
1918 case Yield::SUSPEND: { | 1918 case Yield::SUSPEND: { |
1919 VisitForStackValue(expr->generator_object()); | 1919 VisitForStackValue(expr->generator_object()); |
1920 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 1920 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
1921 __ movq(context_register(), | 1921 __ movq(context_register(), |
1922 Operand(rbp, StandardFrameConstants::kContextOffset)); | 1922 Operand(rbp, StandardFrameConstants::kContextOffset)); |
1923 | 1923 |
1924 Label resume; | 1924 Label resume; |
1925 __ CompareRoot(result_register(), Heap::kTheHoleValueRootIndex); | 1925 __ CompareRoot(result_register(), Heap::kTheHoleValueRootIndex); |
1926 __ j(not_equal, &resume); | 1926 __ j(not_equal, &resume); |
1927 __ pop(result_register()); | |
1928 if (expr->yield_kind() == Yield::SUSPEND) { | 1927 if (expr->yield_kind() == Yield::SUSPEND) { |
1929 // TODO(wingo): Box into { value: VALUE, done: false }. | 1928 EmitReturnIteratorResult(false); |
1929 } else { | |
1930 __ pop(result_register()); | |
1931 EmitReturnSequence(); | |
1930 } | 1932 } |
1931 EmitReturnSequence(); | |
1932 | 1933 |
1933 __ bind(&resume); | 1934 __ bind(&resume); |
1934 context()->Plug(result_register()); | 1935 context()->Plug(result_register()); |
1935 break; | 1936 break; |
1936 } | 1937 } |
1937 | 1938 |
1938 case Yield::FINAL: { | 1939 case Yield::FINAL: { |
1939 VisitForAccumulatorValue(expr->generator_object()); | 1940 VisitForAccumulatorValue(expr->generator_object()); |
1940 __ Move(FieldOperand(result_register(), | 1941 __ Move(FieldOperand(result_register(), |
1941 JSGeneratorObject::kContinuationOffset), | 1942 JSGeneratorObject::kContinuationOffset), |
1942 Smi::FromInt(JSGeneratorObject::kGeneratorClosed)); | 1943 Smi::FromInt(0)); |
Michael Starzinger
2013/05/06 19:34:18
Is there a particular reason you went back to a ha
| |
1943 __ pop(result_register()); | 1944 EmitReturnIteratorResult(true); |
1944 // TODO(wingo): Box into { value: VALUE, done: true }. | |
1945 | |
1946 // Exit all nested statements. | |
1947 NestedStatement* current = nesting_stack_; | |
1948 int stack_depth = 0; | |
1949 int context_length = 0; | |
1950 while (current != NULL) { | |
1951 current = current->Exit(&stack_depth, &context_length); | |
1952 } | |
1953 __ Drop(stack_depth); | |
1954 EmitReturnSequence(); | |
1955 break; | 1945 break; |
1956 } | 1946 } |
1957 | 1947 |
1958 case Yield::DELEGATING: | 1948 case Yield::DELEGATING: |
1959 UNIMPLEMENTED(); | 1949 UNIMPLEMENTED(); |
1960 } | 1950 } |
1961 } | 1951 } |
1962 | 1952 |
1963 | 1953 |
1964 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 1954 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2051 // Throw error if we attempt to operate on a running generator. | 2041 // Throw error if we attempt to operate on a running generator. |
2052 __ bind(&wrong_state); | 2042 __ bind(&wrong_state); |
2053 __ push(rbx); | 2043 __ push(rbx); |
2054 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); | 2044 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); |
2055 | 2045 |
2056 __ bind(&done); | 2046 __ bind(&done); |
2057 context()->Plug(result_register()); | 2047 context()->Plug(result_register()); |
2058 } | 2048 } |
2059 | 2049 |
2060 | 2050 |
2051 void FullCodeGenerator::EmitReturnIteratorResult(bool done) { | |
2052 Label gc_required; | |
2053 Label allocated; | |
2054 | |
2055 Handle<Map> map(isolate()->native_context()->generator_result_map()); | |
2056 | |
2057 __ Allocate(map->instance_size(), rax, rcx, rdx, &gc_required, TAG_OBJECT); | |
2058 | |
2059 __ bind(&allocated); | |
2060 __ Move(rbx, map); | |
2061 __ pop(rcx); | |
2062 __ Move(rdx, isolate()->factory()->ToBoolean(done)); | |
2063 ASSERT_EQ(map->instance_size(), 5 * kPointerSize); | |
2064 __ movq(FieldOperand(rax, HeapObject::kMapOffset), rbx); | |
2065 __ Move(FieldOperand(rax, JSObject::kPropertiesOffset), | |
2066 isolate()->factory()->empty_fixed_array()); | |
2067 __ Move(FieldOperand(rax, JSObject::kElementsOffset), | |
2068 isolate()->factory()->empty_fixed_array()); | |
2069 __ movq(FieldOperand(rax, JSGeneratorObject::kResultValuePropertyOffset), | |
2070 rcx); | |
2071 __ movq(FieldOperand(rax, JSGeneratorObject::kResultDonePropertyOffset), | |
2072 rdx); | |
2073 | |
2074 // Only the value field needs a write barrier, as the other values are in the | |
2075 // root set. | |
2076 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset, | |
2077 rcx, rdx, kDontSaveFPRegs); | |
2078 | |
2079 if (done) { | |
2080 // Exit all nested statements. | |
2081 NestedStatement* current = nesting_stack_; | |
2082 int stack_depth = 0; | |
2083 int context_length = 0; | |
2084 while (current != NULL) { | |
2085 current = current->Exit(&stack_depth, &context_length); | |
2086 } | |
2087 __ Drop(stack_depth); | |
2088 } | |
2089 | |
2090 EmitReturnSequence(); | |
2091 | |
2092 __ bind(&gc_required); | |
2093 __ Push(Smi::FromInt(map->instance_size())); | |
2094 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | |
2095 __ movq(context_register(), | |
2096 Operand(rbp, StandardFrameConstants::kContextOffset)); | |
2097 __ jmp(&allocated); | |
2098 } | |
2099 | |
2100 | |
2061 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2101 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2062 SetSourcePosition(prop->position()); | 2102 SetSourcePosition(prop->position()); |
2063 Literal* key = prop->key()->AsLiteral(); | 2103 Literal* key = prop->key()->AsLiteral(); |
2064 __ Move(rcx, key->handle()); | 2104 __ Move(rcx, key->handle()); |
2065 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 2105 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
2066 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | 2106 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); |
2067 } | 2107 } |
2068 | 2108 |
2069 | 2109 |
2070 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2110 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
(...skipping 2612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4683 *context_length = 0; | 4723 *context_length = 0; |
4684 return previous_; | 4724 return previous_; |
4685 } | 4725 } |
4686 | 4726 |
4687 | 4727 |
4688 #undef __ | 4728 #undef __ |
4689 | 4729 |
4690 } } // namespace v8::internal | 4730 } } // namespace v8::internal |
4691 | 4731 |
4692 #endif // V8_TARGET_ARCH_X64 | 4732 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |