OLD | NEW |
---|---|
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); | 29 Node* closed = SmiConstant(JSGeneratorObject::kGeneratorClosed); |
neis
2017/06/13 10:58:17
Nit: move this down to where it's used.
Jarin
2017/06/13 11:05:56
Done.
| |
30 | 30 |
31 // Check if the {receiver} is actually a JSGeneratorObject. | 31 // Check if the {receiver} is actually a JSGeneratorObject. |
32 Label if_receiverisincompatible(this, Label::kDeferred); | 32 Label if_receiverisincompatible(this, Label::kDeferred); |
33 GotoIf(TaggedIsSmi(receiver), &if_receiverisincompatible); | 33 GotoIf(TaggedIsSmi(receiver), &if_receiverisincompatible); |
34 Node* receiver_instance_type = LoadInstanceType(receiver); | 34 Node* receiver_instance_type = LoadInstanceType(receiver); |
35 GotoIfNot(Word32Equal(receiver_instance_type, | 35 GotoIfNot(Word32Equal(receiver_instance_type, |
36 Int32Constant(JS_GENERATOR_OBJECT_TYPE)), | 36 Int32Constant(JS_GENERATOR_OBJECT_TYPE)), |
37 &if_receiverisincompatible); | 37 &if_receiverisincompatible); |
38 | 38 |
39 // Check if the {receiver} is running or already closed. | 39 // Check if the {receiver} is running or already closed. |
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()); | 50 VARIABLE(var_exception, MachineRepresentation::kTagged, UndefinedConstant()); |
51 Label if_exception(this, Label::kDeferred), if_final_return(this); | 51 Label if_exception(this, Label::kDeferred), if_final_return(this); |
52 Node* result = | 52 Node* result = |
53 CallStub(CodeFactory::ResumeGenerator(isolate()), context, value, | 53 CallStub(CodeFactory::ResumeGenerator(isolate()), context, value, |
54 receiver, SmiConstant(resume_mode), | 54 receiver, SmiConstant(resume_mode), |
55 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. | 56 // Make sure we close the generator if there was an exception. |
57 GotoIfException(result, &if_exception, &var_exception); | 57 GotoIfException(result, &if_exception, &var_exception); |
58 | 58 |
59 // If the generator is not suspended (i.e., it's state is 'closed'), | 59 // If the generator is not suspended (i.e., it's state is 'executing'), |
neis
2017/06/13 10:58:17
s/it's/its/
Jarin
2017/06/13 11:05:56
Done.
| |
60 // wrap the return value in IteratorResult. | 60 // close it and wrap the return value in IteratorResult. |
61 Node* result_continuation = | 61 Node* result_continuation = |
62 LoadObjectField(receiver, JSGeneratorObject::kContinuationOffset); | 62 LoadObjectField(receiver, JSGeneratorObject::kContinuationOffset); |
63 GotoIf(SmiEqual(result_continuation, closed), &if_final_return); | 63 |
64 // The generator function should not close the generator by itself, let's | |
65 // check it is indeed not closed yet. | |
66 CSA_ASSERT(this, SmiNotEqual(result_continuation, closed)); | |
67 | |
68 Node* executing = SmiConstant(JSGeneratorObject::kGeneratorExecuting); | |
69 GotoIf(SmiEqual(result_continuation, executing), &if_final_return); | |
70 | |
64 Return(result); | 71 Return(result); |
neis
2017/06/13 10:58:17
Please add a comment saying that on suspend the ge
Jarin
2017/06/13 11:05:56
Done.
| |
65 | 72 |
66 Callable create_iter_result_object = | 73 Callable create_iter_result_object = |
67 Builtins::CallableFor(isolate(), Builtins::kCreateIterResultObject); | 74 Builtins::CallableFor(isolate(), Builtins::kCreateIterResultObject); |
68 | |
69 BIND(&if_final_return); | 75 BIND(&if_final_return); |
70 { | 76 { |
77 // Close the generator. | |
78 StoreObjectFieldNoWriteBarrier( | |
79 receiver, JSGeneratorObject::kContinuationOffset, closed); | |
71 // Return the wrapped result. | 80 // Return the wrapped result. |
72 Return( | 81 Return( |
73 CallStub(create_iter_result_object, context, result, TrueConstant())); | 82 CallStub(create_iter_result_object, context, result, TrueConstant())); |
74 } | 83 } |
75 | 84 |
76 BIND(&if_receiverisincompatible); | 85 BIND(&if_receiverisincompatible); |
77 { | 86 { |
78 // The {receiver} is not a valid JSGeneratorObject. | 87 // The {receiver} is not a valid JSGeneratorObject. |
79 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context, | 88 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context, |
80 HeapConstant( | 89 HeapConstant( |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
141 Node* receiver = Parameter(Descriptor::kReceiver); | 150 Node* receiver = Parameter(Descriptor::kReceiver); |
142 Node* exception = Parameter(Descriptor::kException); | 151 Node* exception = Parameter(Descriptor::kException); |
143 Node* context = Parameter(Descriptor::kContext); | 152 Node* context = Parameter(Descriptor::kContext); |
144 GeneratorPrototypeResume(receiver, exception, context, | 153 GeneratorPrototypeResume(receiver, exception, context, |
145 JSGeneratorObject::kThrow, | 154 JSGeneratorObject::kThrow, |
146 "[Generator].prototype.throw"); | 155 "[Generator].prototype.throw"); |
147 } | 156 } |
148 | 157 |
149 } // namespace internal | 158 } // namespace internal |
150 } // namespace v8 | 159 } // namespace v8 |
OLD | NEW |