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)); |
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 STATIC_ASSERT(HeapObject::kMapOffset == 0); |
| 2056 STATIC_ASSERT(JSObject::kPropertiesOffset == kPointerSize); |
| 2057 STATIC_ASSERT(JSObject::kElementsOffset == 2 * kPointerSize); |
| 2058 STATIC_ASSERT(JSObject::kHeaderSize == 3 * kPointerSize); |
| 2059 STATIC_ASSERT(JSGeneratorObject::kResultValuePropertyIndex == 0); |
| 2060 STATIC_ASSERT(JSGeneratorObject::kResultDonePropertyIndex == 1); |
| 2061 |
| 2062 const int size = 5 * kPointerSize; |
| 2063 __ Allocate(size, rax, rcx, rdx, &gc_required, TAG_OBJECT); |
| 2064 |
| 2065 __ bind(&allocated); |
| 2066 // The object is now in rax. Initialize its map, value, and done fields. |
| 2067 Handle<Map> map(isolate()->native_context()->iterator_result_map()); |
| 2068 __ Move(rbx, map); |
| 2069 __ pop(rcx); |
| 2070 __ Move(rdx, |
| 2071 done |
| 2072 ? isolate()->factory()->true_value() |
| 2073 : isolate()->factory()->false_value()); |
| 2074 __ movq(FieldOperand(rax, 0 * kPointerSize), rbx); // map |
| 2075 __ Move(FieldOperand(rax, 1 * kPointerSize), // properties |
| 2076 isolate()->factory()->empty_fixed_array()); |
| 2077 __ Move(FieldOperand(rax, 2 * kPointerSize), // elements |
| 2078 isolate()->factory()->empty_fixed_array()); |
| 2079 __ movq(FieldOperand(rax, 3 * kPointerSize), rcx); // value |
| 2080 __ movq(FieldOperand(rax, 4 * kPointerSize), rdx); // done? |
| 2081 |
| 2082 // Only the value field needs a write barrier, as the other values are in the |
| 2083 // root set. |
| 2084 __ RecordWriteField(rax, 3 * kPointerSize, rcx, rdx, kDontSaveFPRegs); |
| 2085 |
| 2086 if (done) { |
| 2087 // Exit all nested statements. |
| 2088 NestedStatement* current = nesting_stack_; |
| 2089 int stack_depth = 0; |
| 2090 int context_length = 0; |
| 2091 while (current != NULL) { |
| 2092 current = current->Exit(&stack_depth, &context_length); |
| 2093 } |
| 2094 __ Drop(stack_depth); |
| 2095 } |
| 2096 |
| 2097 EmitReturnSequence(); |
| 2098 |
| 2099 __ bind(&gc_required); |
| 2100 __ Push(Smi::FromInt(size)); |
| 2101 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
| 2102 __ movq(context_register(), |
| 2103 Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 2104 __ jmp(&allocated); |
| 2105 } |
| 2106 |
| 2107 |
2061 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2108 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2062 SetSourcePosition(prop->position()); | 2109 SetSourcePosition(prop->position()); |
2063 Literal* key = prop->key()->AsLiteral(); | 2110 Literal* key = prop->key()->AsLiteral(); |
2064 __ Move(rcx, key->handle()); | 2111 __ Move(rcx, key->handle()); |
2065 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 2112 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
2066 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | 2113 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); |
2067 } | 2114 } |
2068 | 2115 |
2069 | 2116 |
2070 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2117 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
(...skipping 2612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4683 *context_length = 0; | 4730 *context_length = 0; |
4684 return previous_; | 4731 return previous_; |
4685 } | 4732 } |
4686 | 4733 |
4687 | 4734 |
4688 #undef __ | 4735 #undef __ |
4689 | 4736 |
4690 } } // namespace v8::internal | 4737 } } // namespace v8::internal |
4691 | 4738 |
4692 #endif // V8_TARGET_ARCH_X64 | 4739 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |