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

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

Issue 2936813002: Move closing of generators upon final return to the generator-resume builtin. (Closed)
Patch Set: Add TODO 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 | « no previous file | 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"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 class GeneratorBuiltinsAssembler : public CodeStubAssembler { 15 class GeneratorBuiltinsAssembler : public CodeStubAssembler {
16 public: 16 public:
17 explicit GeneratorBuiltinsAssembler(compiler::CodeAssemblerState* state) 17 explicit GeneratorBuiltinsAssembler(compiler::CodeAssemblerState* state)
18 : CodeStubAssembler(state) {} 18 : CodeStubAssembler(state) {}
19 19
20 protected: 20 protected:
21 void GeneratorPrototypeResume(Node* receiver, Node* value, Node* context, 21 void GeneratorPrototypeResume(Node* receiver, Node* value, Node* context,
22 JSGeneratorObject::ResumeMode resume_mode, 22 JSGeneratorObject::ResumeMode resume_mode,
23 char const* const method_name); 23 char const* const method_name);
24 }; 24 };
25 25
26 void GeneratorBuiltinsAssembler::GeneratorPrototypeResume( 26 void GeneratorBuiltinsAssembler::GeneratorPrototypeResume(
27 Node* receiver, Node* value, Node* context, 27 Node* receiver, Node* value, Node* context,
28 JSGeneratorObject::ResumeMode resume_mode, char const* const method_name) { 28 JSGeneratorObject::ResumeMode resume_mode, char const* const method_name) {
29 Node* closed = SmiConstant(JSGeneratorObject::kGeneratorClosed);
30
31 // Check if the {receiver} is actually a JSGeneratorObject. 29 // Check if the {receiver} is actually a JSGeneratorObject.
32 Label if_receiverisincompatible(this, Label::kDeferred); 30 Label if_receiverisincompatible(this, Label::kDeferred);
33 GotoIf(TaggedIsSmi(receiver), &if_receiverisincompatible); 31 GotoIf(TaggedIsSmi(receiver), &if_receiverisincompatible);
34 Node* receiver_instance_type = LoadInstanceType(receiver); 32 Node* receiver_instance_type = LoadInstanceType(receiver);
35 GotoIfNot(Word32Equal(receiver_instance_type, 33 GotoIfNot(Word32Equal(receiver_instance_type,
36 Int32Constant(JS_GENERATOR_OBJECT_TYPE)), 34 Int32Constant(JS_GENERATOR_OBJECT_TYPE)),
37 &if_receiverisincompatible); 35 &if_receiverisincompatible);
38 36
39 // Check if the {receiver} is running or already closed. 37 // Check if the {receiver} is running or already closed.
40 Node* receiver_continuation = 38 Node* receiver_continuation =
41 LoadObjectField(receiver, JSGeneratorObject::kContinuationOffset); 39 LoadObjectField(receiver, JSGeneratorObject::kContinuationOffset);
42 Label if_receiverisclosed(this, Label::kDeferred), 40 Label if_receiverisclosed(this, Label::kDeferred),
43 if_receiverisrunning(this, Label::kDeferred); 41 if_receiverisrunning(this, Label::kDeferred);
42 Node* closed = SmiConstant(JSGeneratorObject::kGeneratorClosed);
44 GotoIf(SmiEqual(receiver_continuation, closed), &if_receiverisclosed); 43 GotoIf(SmiEqual(receiver_continuation, closed), &if_receiverisclosed);
45 DCHECK_LT(JSGeneratorObject::kGeneratorExecuting, 44 DCHECK_LT(JSGeneratorObject::kGeneratorExecuting,
46 JSGeneratorObject::kGeneratorClosed); 45 JSGeneratorObject::kGeneratorClosed);
47 GotoIf(SmiLessThan(receiver_continuation, closed), &if_receiverisrunning); 46 GotoIf(SmiLessThan(receiver_continuation, closed), &if_receiverisrunning);
48 47
49 // Resume the {receiver} using our trampoline. 48 // Resume the {receiver} using our trampoline.
50 VARIABLE(var_exception, MachineRepresentation::kTagged, UndefinedConstant()); 49 VARIABLE(var_exception, MachineRepresentation::kTagged, UndefinedConstant());
51 Label if_exception(this, Label::kDeferred), if_final_return(this); 50 Label if_exception(this, Label::kDeferred), if_final_return(this);
52 Node* result = 51 Node* result =
53 CallStub(CodeFactory::ResumeGenerator(isolate()), context, value, 52 CallStub(CodeFactory::ResumeGenerator(isolate()), context, value,
54 receiver, SmiConstant(resume_mode), 53 receiver, SmiConstant(resume_mode),
55 SmiConstant(static_cast<int>(SuspendFlags::kGeneratorYield))); 54 SmiConstant(static_cast<int>(SuspendFlags::kGeneratorYield)));
56 // Make sure we close the generator if there was an exception. 55 // Make sure we close the generator if there was an exception.
57 GotoIfException(result, &if_exception, &var_exception); 56 GotoIfException(result, &if_exception, &var_exception);
58 57
59 // If the generator is not suspended (i.e., it's state is 'closed'), 58 // If the generator is not suspended (i.e., its state is 'executing'),
60 // wrap the return value in IteratorResult. 59 // close it and wrap the return value in IteratorResult.
61 Node* result_continuation = 60 Node* result_continuation =
62 LoadObjectField(receiver, JSGeneratorObject::kContinuationOffset); 61 LoadObjectField(receiver, JSGeneratorObject::kContinuationOffset);
63 GotoIf(SmiEqual(result_continuation, closed), &if_final_return); 62
63 // The generator function should not close the generator by itself, let's
64 // check it is indeed not closed yet.
65 CSA_ASSERT(this, SmiNotEqual(result_continuation, closed));
66
67 Node* executing = SmiConstant(JSGeneratorObject::kGeneratorExecuting);
68 GotoIf(SmiEqual(result_continuation, executing), &if_final_return);
69
64 Return(result); 70 Return(result);
65 71
66 Callable create_iter_result_object = 72 Callable create_iter_result_object =
67 Builtins::CallableFor(isolate(), Builtins::kCreateIterResultObject); 73 Builtins::CallableFor(isolate(), Builtins::kCreateIterResultObject);
68
69 BIND(&if_final_return); 74 BIND(&if_final_return);
70 { 75 {
76 // Close the generator.
77 StoreObjectFieldNoWriteBarrier(
78 receiver, JSGeneratorObject::kContinuationOffset, closed);
71 // Return the wrapped result. 79 // Return the wrapped result.
72 Return( 80 Return(
73 CallStub(create_iter_result_object, context, result, TrueConstant())); 81 CallStub(create_iter_result_object, context, result, TrueConstant()));
74 } 82 }
75 83
76 BIND(&if_receiverisincompatible); 84 BIND(&if_receiverisincompatible);
77 { 85 {
78 // The {receiver} is not a valid JSGeneratorObject. 86 // The {receiver} is not a valid JSGeneratorObject.
79 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context, 87 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context,
80 HeapConstant( 88 HeapConstant(
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 Node* receiver = Parameter(Descriptor::kReceiver); 149 Node* receiver = Parameter(Descriptor::kReceiver);
142 Node* exception = Parameter(Descriptor::kException); 150 Node* exception = Parameter(Descriptor::kException);
143 Node* context = Parameter(Descriptor::kContext); 151 Node* context = Parameter(Descriptor::kContext);
144 GeneratorPrototypeResume(receiver, exception, context, 152 GeneratorPrototypeResume(receiver, exception, context,
145 JSGeneratorObject::kThrow, 153 JSGeneratorObject::kThrow,
146 "[Generator].prototype.throw"); 154 "[Generator].prototype.throw");
147 } 155 }
148 156
149 } // namespace internal 157 } // namespace internal
150 } // namespace v8 158 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/interpreter/bytecode-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698