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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: src/x64/full-codegen-x64.cc
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 3b4c07c89c9f9a22a720463119c82834db915352..466976daf1c8f1f7ee105730cb0424a88b49f041 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -1974,6 +1974,10 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
ASSERT(continuation.pos() > 0 && Smi::IsValid(continuation.pos()));
__ Move(FieldOperand(rax, JSGeneratorObject::kContinuationOffset),
Smi::FromInt(continuation.pos()));
+ if (expr->yield_kind() == Yield::INITIAL) {
+ __ Move(FieldOperand(rax, JSGeneratorObject::kSuspendedStartOffset),
+ Smi::FromInt(continuation.pos()));
+ }
__ movq(FieldOperand(rax, JSGeneratorObject::kContextOffset), rsi);
__ movq(rcx, rsi);
__ RecordWriteField(rax, JSGeneratorObject::kContextOffset, rcx, rdx,
@@ -2106,13 +2110,17 @@ void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
__ pop(rbx);
// Check generator state.
- Label wrong_state, closed_state, done;
+ Label wrong_state, closed_state, suspended_start_state, resume_state, done;
STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
- __ SmiCompare(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset),
- Smi::FromInt(0));
+ __ movq(rcx, FieldOperand(rbx, JSGeneratorObject::kContinuationOffset));
+ __ SmiCompare(rcx, Smi::FromInt(0));
__ j(equal, &closed_state);
__ j(less, &wrong_state);
+ __ cmpq(rcx, FieldOperand(rbx, JSGeneratorObject::kSuspendedStartOffset));
+ __ j(equal, &suspended_start_state);
+
+ __ bind(&resume_state);
// Load suspended function and context.
__ movq(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset));
@@ -2183,6 +2191,30 @@ void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
// Not reached: the runtime call returns elsewhere.
__ Abort(kGeneratorFailedToResume);
+ // Throw the provided value.
+ Label throw_provided_value;
+ __ bind(&throw_provided_value);
+ if (resume_mode != JSGeneratorObject::NEXT) {
+ __ push(rax);
+ __ CallRuntime(Runtime::kThrow, 1);
+ __ jmp(&done);
+ }
+
+ // Reach here when calling initial resume to a generator.
+ __ bind(&suspended_start_state);
+ if (resume_mode == JSGeneratorObject::NEXT) {
+ // When value is provided and it is not undefined, throw error.
+ __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
+ __ j(equal, &resume_state);
+ __ CallRuntime(Runtime::kThrowGeneratorStartError, 0);
+ __ jmp(&done);
+ } else {
+ // Make generator's state to "closed".
+ __ Move(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset),
+ Smi::FromInt(JSGeneratorObject::kGeneratorClosed));
+ __ jmp(&throw_provided_value);
+ }
+
// Reach here when generator is closed.
__ bind(&closed_state);
if (resume_mode == JSGeneratorObject::NEXT) {
@@ -2190,12 +2222,10 @@ void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
__ PushRoot(Heap::kUndefinedValueRootIndex);
// Pop value from top-of-stack slot; box result into result register.
EmitCreateIteratorResult(true);
+ __ jmp(&done);
} else {
- // Throw the provided value.
- __ push(rax);
- __ CallRuntime(Runtime::kThrow, 1);
+ __ jmp(&throw_provided_value);
}
- __ jmp(&done);
// Throw error if we attempt to operate on a running generator.
__ bind(&wrong_state);

Powered by Google App Engine
This is Rietveld 408576698