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(JSGeneratorObject::kGeneratorClosed)); |
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 |