Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: src/x64/full-codegen-x64.cc

Issue 139653003: Throw a TypeError when calling "next" method of a newly created generator with a value (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 1956 matching lines...) Expand 10 before | Expand all | Expand 10 after
1967 __ jmp(&suspend); 1967 __ jmp(&suspend);
1968 1968
1969 __ bind(&continuation); 1969 __ bind(&continuation);
1970 __ jmp(&resume); 1970 __ jmp(&resume);
1971 1971
1972 __ bind(&suspend); 1972 __ bind(&suspend);
1973 VisitForAccumulatorValue(expr->generator_object()); 1973 VisitForAccumulatorValue(expr->generator_object());
1974 ASSERT(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); 1974 ASSERT(continuation.pos() > 0 && Smi::IsValid(continuation.pos()));
1975 __ Move(FieldOperand(rax, JSGeneratorObject::kContinuationOffset), 1975 __ Move(FieldOperand(rax, JSGeneratorObject::kContinuationOffset),
1976 Smi::FromInt(continuation.pos())); 1976 Smi::FromInt(continuation.pos()));
1977 if (expr->yield_kind() == Yield::INITIAL) {
1978 __ Move(FieldOperand(rax, JSGeneratorObject::kSuspendedStartOffset),
1979 Smi::FromInt(continuation.pos()));
1980 }
1977 __ movq(FieldOperand(rax, JSGeneratorObject::kContextOffset), rsi); 1981 __ movq(FieldOperand(rax, JSGeneratorObject::kContextOffset), rsi);
1978 __ movq(rcx, rsi); 1982 __ movq(rcx, rsi);
1979 __ RecordWriteField(rax, JSGeneratorObject::kContextOffset, rcx, rdx, 1983 __ RecordWriteField(rax, JSGeneratorObject::kContextOffset, rcx, rdx,
1980 kDontSaveFPRegs); 1984 kDontSaveFPRegs);
1981 __ lea(rbx, Operand(rbp, StandardFrameConstants::kExpressionsOffset)); 1985 __ lea(rbx, Operand(rbp, StandardFrameConstants::kExpressionsOffset));
1982 __ cmpq(rsp, rbx); 1986 __ cmpq(rsp, rbx);
1983 __ j(equal, &post_runtime); 1987 __ j(equal, &post_runtime);
1984 __ push(rax); // generator object 1988 __ push(rax); // generator object
1985 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1989 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1986 __ movq(context_register(), 1990 __ movq(context_register(),
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
2099 JSGeneratorObject::ResumeMode resume_mode) { 2103 JSGeneratorObject::ResumeMode resume_mode) {
2100 // The value stays in rax, and is ultimately read by the resumed generator, as 2104 // The value stays in rax, and is ultimately read by the resumed generator, as
2101 // if the CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it 2105 // if the CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
2102 // is read to throw the value when the resumed generator is already closed. 2106 // is read to throw the value when the resumed generator is already closed.
2103 // rbx will hold the generator object until the activation has been resumed. 2107 // rbx will hold the generator object until the activation has been resumed.
2104 VisitForStackValue(generator); 2108 VisitForStackValue(generator);
2105 VisitForAccumulatorValue(value); 2109 VisitForAccumulatorValue(value);
2106 __ pop(rbx); 2110 __ pop(rbx);
2107 2111
2108 // Check generator state. 2112 // Check generator state.
2109 Label wrong_state, closed_state, done; 2113 Label wrong_state, closed_state, suspended_start_state, resume_state, done;
2110 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); 2114 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
2111 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0); 2115 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
2112 __ SmiCompare(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset), 2116 __ movq(rcx, FieldOperand(rbx, JSGeneratorObject::kContinuationOffset));
2113 Smi::FromInt(0)); 2117 __ SmiCompare(rcx, Smi::FromInt(0));
2114 __ j(equal, &closed_state); 2118 __ j(equal, &closed_state);
2115 __ j(less, &wrong_state); 2119 __ j(less, &wrong_state);
2120 __ cmpq(rcx, FieldOperand(rbx, JSGeneratorObject::kSuspendedStartOffset));
2121 __ j(equal, &suspended_start_state);
2122
2123 __ bind(&resume_state);
2116 2124
2117 // Load suspended function and context. 2125 // Load suspended function and context.
2118 __ movq(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset)); 2126 __ movq(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset));
2119 __ movq(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset)); 2127 __ movq(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset));
2120 2128
2121 // Push receiver. 2129 // Push receiver.
2122 __ push(FieldOperand(rbx, JSGeneratorObject::kReceiverOffset)); 2130 __ push(FieldOperand(rbx, JSGeneratorObject::kReceiverOffset));
2123 2131
2124 // Push holes for arguments to generator function. 2132 // Push holes for arguments to generator function.
2125 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); 2133 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2176 __ push(rcx); 2184 __ push(rcx);
2177 __ jmp(&push_operand_holes); 2185 __ jmp(&push_operand_holes);
2178 __ bind(&call_resume); 2186 __ bind(&call_resume);
2179 __ push(rbx); 2187 __ push(rbx);
2180 __ push(result_register()); 2188 __ push(result_register());
2181 __ Push(Smi::FromInt(resume_mode)); 2189 __ Push(Smi::FromInt(resume_mode));
2182 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); 2190 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3);
2183 // Not reached: the runtime call returns elsewhere. 2191 // Not reached: the runtime call returns elsewhere.
2184 __ Abort(kGeneratorFailedToResume); 2192 __ Abort(kGeneratorFailedToResume);
2185 2193
2194 // Throw the provided value.
2195 Label throw_provided_value;
2196 __ bind(&throw_provided_value);
2197 if (resume_mode != JSGeneratorObject::NEXT) {
2198 __ push(rax);
2199 __ CallRuntime(Runtime::kThrow, 1);
2200 __ jmp(&done);
2201 }
2202
2203 // Reach here when calling initial resume to a generator.
2204 __ bind(&suspended_start_state);
2205 if (resume_mode == JSGeneratorObject::NEXT) {
2206 // When value is provided and it is not undefined, throw error.
2207 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
2208 __ j(equal, &resume_state);
2209 __ CallRuntime(Runtime::kThrowGeneratorStartError, 0);
2210 __ jmp(&done);
2211 } else {
2212 // Make generator's state to "closed".
2213 __ Move(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset),
2214 Smi::FromInt(JSGeneratorObject::kGeneratorClosed));
2215 __ jmp(&throw_provided_value);
2216 }
2217
2186 // Reach here when generator is closed. 2218 // Reach here when generator is closed.
2187 __ bind(&closed_state); 2219 __ bind(&closed_state);
2188 if (resume_mode == JSGeneratorObject::NEXT) { 2220 if (resume_mode == JSGeneratorObject::NEXT) {
2189 // Return completed iterator result when generator is closed. 2221 // Return completed iterator result when generator is closed.
2190 __ PushRoot(Heap::kUndefinedValueRootIndex); 2222 __ PushRoot(Heap::kUndefinedValueRootIndex);
2191 // Pop value from top-of-stack slot; box result into result register. 2223 // Pop value from top-of-stack slot; box result into result register.
2192 EmitCreateIteratorResult(true); 2224 EmitCreateIteratorResult(true);
2225 __ jmp(&done);
2193 } else { 2226 } else {
2194 // Throw the provided value. 2227 __ jmp(&throw_provided_value);
2195 __ push(rax);
2196 __ CallRuntime(Runtime::kThrow, 1);
2197 } 2228 }
2198 __ jmp(&done);
2199 2229
2200 // Throw error if we attempt to operate on a running generator. 2230 // Throw error if we attempt to operate on a running generator.
2201 __ bind(&wrong_state); 2231 __ bind(&wrong_state);
2202 __ push(rbx); 2232 __ push(rbx);
2203 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); 2233 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
2204 2234
2205 __ bind(&done); 2235 __ bind(&done);
2206 context()->Plug(result_register()); 2236 context()->Plug(result_register());
2207 } 2237 }
2208 2238
(...skipping 2688 matching lines...) Expand 10 before | Expand all | Expand 10 after
4897 4927
4898 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4928 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4899 Assembler::target_address_at(call_target_address)); 4929 Assembler::target_address_at(call_target_address));
4900 return OSR_AFTER_STACK_CHECK; 4930 return OSR_AFTER_STACK_CHECK;
4901 } 4931 }
4902 4932
4903 4933
4904 } } // namespace v8::internal 4934 } } // namespace v8::internal
4905 4935
4906 #endif // V8_TARGET_ARCH_X64 4936 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698