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

Side by Side Diff: src/builtins/builtins-generator-gen.cc

Issue 2917263002: Move generator-close on exception from the generator function to the GeneratorResume builtin. (Closed)
Patch Set: Add register allocation scope Created 3 years, 6 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
« no previous file with comments | « src/builtins/builtins-definitions.h ('k') | src/interpreter/bytecode-generator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins/builtins-utils-gen.h" 5 #include "src/builtins/builtins-utils-gen.h"
6 #include "src/builtins/builtins.h" 6 #include "src/builtins/builtins.h"
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/code-stub-assembler.h" 8 #include "src/code-stub-assembler.h"
9 #include "src/isolate.h" 9 #include "src/isolate.h"
10 #include "src/objects-inl.h" 10 #include "src/objects-inl.h"
(...skipping 29 matching lines...) Expand all
40 Node* receiver_continuation = 40 Node* receiver_continuation =
41 LoadObjectField(receiver, JSGeneratorObject::kContinuationOffset); 41 LoadObjectField(receiver, JSGeneratorObject::kContinuationOffset);
42 Label if_receiverisclosed(this, Label::kDeferred), 42 Label if_receiverisclosed(this, Label::kDeferred),
43 if_receiverisrunning(this, Label::kDeferred); 43 if_receiverisrunning(this, Label::kDeferred);
44 GotoIf(SmiEqual(receiver_continuation, closed), &if_receiverisclosed); 44 GotoIf(SmiEqual(receiver_continuation, closed), &if_receiverisclosed);
45 DCHECK_LT(JSGeneratorObject::kGeneratorExecuting, 45 DCHECK_LT(JSGeneratorObject::kGeneratorExecuting,
46 JSGeneratorObject::kGeneratorClosed); 46 JSGeneratorObject::kGeneratorClosed);
47 GotoIf(SmiLessThan(receiver_continuation, closed), &if_receiverisrunning); 47 GotoIf(SmiLessThan(receiver_continuation, closed), &if_receiverisrunning);
48 48
49 // Resume the {receiver} using our trampoline. 49 // Resume the {receiver} using our trampoline.
50 VARIABLE(var_exception, MachineRepresentation::kTagged, UndefinedConstant());
51 Label if_exception(this, Label::kDeferred), if_final_return(this);
50 Node* result = 52 Node* result =
51 CallStub(CodeFactory::ResumeGenerator(isolate()), context, value, 53 CallStub(CodeFactory::ResumeGenerator(isolate()), context, value,
52 receiver, SmiConstant(resume_mode), 54 receiver, SmiConstant(resume_mode),
53 SmiConstant(static_cast<int>(SuspendFlags::kGeneratorYield))); 55 SmiConstant(static_cast<int>(SuspendFlags::kGeneratorYield)));
56 // Make sure we close the generator if there was an exception.
57 GotoIfException(result, &if_exception, &var_exception);
58
59 // If the generator is not suspended (i.e., it's state is 'closed'),
60 // wrap the return value in IteratorResult.
61 Node* result_continuation =
62 LoadObjectField(receiver, JSGeneratorObject::kContinuationOffset);
63 GotoIf(SmiEqual(result_continuation, closed), &if_final_return);
54 Return(result); 64 Return(result);
55 65
66 Callable create_iter_result_object =
67 CodeFactory::CreateIterResultObject(isolate());
68
69 BIND(&if_final_return);
70 {
71 // Return the wrapped result.
72 Return(
73 CallStub(create_iter_result_object, context, result, TrueConstant()));
74 }
75
56 BIND(&if_receiverisincompatible); 76 BIND(&if_receiverisincompatible);
57 { 77 {
58 // The {receiver} is not a valid JSGeneratorObject. 78 // The {receiver} is not a valid JSGeneratorObject.
59 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context, 79 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context,
60 HeapConstant( 80 HeapConstant(
61 factory()->NewStringFromAsciiChecked(method_name, TENURED)), 81 factory()->NewStringFromAsciiChecked(method_name, TENURED)),
62 receiver); 82 receiver);
63 Unreachable(); 83 Unreachable();
64 } 84 }
65 85
66 BIND(&if_receiverisclosed); 86 BIND(&if_receiverisclosed);
67 { 87 {
68 Callable create_iter_result_object =
69 CodeFactory::CreateIterResultObject(isolate());
70
71 // The {receiver} is closed already. 88 // The {receiver} is closed already.
72 Node* result = nullptr; 89 Node* result = nullptr;
73 switch (resume_mode) { 90 switch (resume_mode) {
74 case JSGeneratorObject::kNext: 91 case JSGeneratorObject::kNext:
75 result = CallStub(create_iter_result_object, context, 92 result = CallStub(create_iter_result_object, context,
76 UndefinedConstant(), TrueConstant()); 93 UndefinedConstant(), TrueConstant());
77 break; 94 break;
78 case JSGeneratorObject::kReturn: 95 case JSGeneratorObject::kReturn:
79 result = 96 result =
80 CallStub(create_iter_result_object, context, value, TrueConstant()); 97 CallStub(create_iter_result_object, context, value, TrueConstant());
81 break; 98 break;
82 case JSGeneratorObject::kThrow: 99 case JSGeneratorObject::kThrow:
83 result = CallRuntime(Runtime::kThrow, context, value); 100 result = CallRuntime(Runtime::kThrow, context, value);
84 break; 101 break;
85 } 102 }
86 Return(result); 103 Return(result);
87 } 104 }
88 105
89 BIND(&if_receiverisrunning); 106 BIND(&if_receiverisrunning);
90 { 107 {
91 CallRuntime(Runtime::kThrowGeneratorRunning, context); 108 CallRuntime(Runtime::kThrowGeneratorRunning, context);
92 Unreachable(); 109 Unreachable();
93 } 110 }
111
112 BIND(&if_exception);
113 {
114 StoreObjectFieldNoWriteBarrier(
115 receiver, JSGeneratorObject::kContinuationOffset, closed);
116 CallRuntime(Runtime::kReThrow, context, var_exception.value());
117 Unreachable();
118 }
94 } 119 }
95 120
96 // ES6 #sec-generator.prototype.next 121 // ES6 #sec-generator.prototype.next
97 TF_BUILTIN(GeneratorPrototypeNext, GeneratorBuiltinsAssembler) { 122 TF_BUILTIN(GeneratorPrototypeNext, GeneratorBuiltinsAssembler) {
98 Node* receiver = Parameter(Descriptor::kReceiver); 123 Node* receiver = Parameter(Descriptor::kReceiver);
99 Node* value = Parameter(Descriptor::kValue); 124 Node* value = Parameter(Descriptor::kValue);
100 Node* context = Parameter(Descriptor::kContext); 125 Node* context = Parameter(Descriptor::kContext);
101 GeneratorPrototypeResume(receiver, value, context, JSGeneratorObject::kNext, 126 GeneratorPrototypeResume(receiver, value, context, JSGeneratorObject::kNext,
102 "[Generator].prototype.next"); 127 "[Generator].prototype.next");
103 } 128 }
(...skipping 12 matching lines...) Expand all
116 Node* receiver = Parameter(Descriptor::kReceiver); 141 Node* receiver = Parameter(Descriptor::kReceiver);
117 Node* exception = Parameter(Descriptor::kException); 142 Node* exception = Parameter(Descriptor::kException);
118 Node* context = Parameter(Descriptor::kContext); 143 Node* context = Parameter(Descriptor::kContext);
119 GeneratorPrototypeResume(receiver, exception, context, 144 GeneratorPrototypeResume(receiver, exception, context,
120 JSGeneratorObject::kThrow, 145 JSGeneratorObject::kThrow,
121 "[Generator].prototype.throw"); 146 "[Generator].prototype.throw");
122 } 147 }
123 148
124 } // namespace internal 149 } // namespace internal
125 } // namespace v8 150 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins-definitions.h ('k') | src/interpreter/bytecode-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698