5 #include "src/builtins/builtins-utils-gen.h" 6 #include "src/builtins/builtins.h" 7 #include "src/code-factory.h" 8 #include "src/code-stub-assembler.h" 9 #include "src/isolate.h" 10 #include "src/objects-inl.h" 11 #include "src/objects/js-generator.h" 24 JSGeneratorObject::ResumeMode resume_mode,
25 char const*
const method_name);
28 void GeneratorBuiltinsAssembler::GeneratorPrototypeResume(
30 JSGeneratorObject::ResumeMode resume_mode,
char const*
const method_name) {
32 ThrowIfNotInstanceType(context, receiver, JS_GENERATOR_OBJECT_TYPE,
37 CAST(LoadObjectField(receiver, JSGeneratorObject::kContinuationOffset));
38 Label if_receiverisclosed(
this, Label::kDeferred),
39 if_receiverisrunning(
this, Label::kDeferred);
40 TNode<Smi> closed = SmiConstant(JSGeneratorObject::kGeneratorClosed);
41 GotoIf(SmiEqual(receiver_continuation, closed), &if_receiverisclosed);
42 DCHECK_LT(JSGeneratorObject::kGeneratorExecuting,
43 JSGeneratorObject::kGeneratorClosed);
44 GotoIf(SmiLessThan(receiver_continuation, closed), &if_receiverisrunning);
47 StoreObjectFieldNoWriteBarrier(receiver, JSGeneratorObject::kResumeModeOffset,
48 SmiConstant(resume_mode));
51 VARIABLE(var_exception, MachineRepresentation::kTagged, UndefinedConstant());
52 Label if_exception(
this, Label::kDeferred), if_final_return(
this);
53 Node* result = CallStub(CodeFactory::ResumeGenerator(isolate()), context,
56 GotoIfException(result, &if_exception, &var_exception);
61 CAST(LoadObjectField(receiver, JSGeneratorObject::kContinuationOffset));
65 CSA_ASSERT(
this, SmiNotEqual(result_continuation, closed));
67 TNode<Smi> executing = SmiConstant(JSGeneratorObject::kGeneratorExecuting);
68 GotoIf(SmiEqual(result_continuation, executing), &if_final_return);
70 args->PopAndReturn(result);
72 BIND(&if_final_return);
75 StoreObjectFieldNoWriteBarrier(
76 receiver, JSGeneratorObject::kContinuationOffset, closed);
78 args->PopAndReturn(CallBuiltin(Builtins::kCreateIterResultObject, context,
79 result, TrueConstant()));
82 BIND(&if_receiverisclosed);
85 Node* result =
nullptr;
86 switch (resume_mode) {
87 case JSGeneratorObject::kNext:
88 result = CallBuiltin(Builtins::kCreateIterResultObject, context,
89 UndefinedConstant(), TrueConstant());
91 case JSGeneratorObject::kReturn:
92 result = CallBuiltin(Builtins::kCreateIterResultObject, context, value,
95 case JSGeneratorObject::kThrow:
96 result = CallRuntime(Runtime::kThrow, context, value);
99 args->PopAndReturn(result);
102 BIND(&if_receiverisrunning);
103 { ThrowTypeError(context, MessageTemplate::kGeneratorRunning); }
107 StoreObjectFieldNoWriteBarrier(
108 receiver, JSGeneratorObject::kContinuationOffset, closed);
109 CallRuntime(Runtime::kReThrow, context, var_exception.value());
115 TF_BUILTIN(GeneratorPrototypeNext, GeneratorBuiltinsAssembler) {
116 const int kValueArg = 0;
119 ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
120 CodeStubArguments args(
this, argc);
122 Node* receiver = args.GetReceiver();
123 Node* value = args.GetOptionalArgumentValue(kValueArg);
124 Node* context = Parameter(Descriptor::kContext);
126 GeneratorPrototypeResume(&args, receiver, value, context,
127 JSGeneratorObject::kNext,
128 "[Generator].prototype.next");
132 TF_BUILTIN(GeneratorPrototypeReturn, GeneratorBuiltinsAssembler) {
133 const int kValueArg = 0;
136 ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
137 CodeStubArguments args(
this, argc);
139 Node* receiver = args.GetReceiver();
140 Node* value = args.GetOptionalArgumentValue(kValueArg);
141 Node* context = Parameter(Descriptor::kContext);
143 GeneratorPrototypeResume(&args, receiver, value, context,
144 JSGeneratorObject::kReturn,
145 "[Generator].prototype.return");
149 TF_BUILTIN(GeneratorPrototypeThrow, GeneratorBuiltinsAssembler) {
150 const int kExceptionArg = 0;
153 ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
154 CodeStubArguments args(
this, argc);
156 Node* receiver = args.GetReceiver();
157 Node* exception = args.GetOptionalArgumentValue(kExceptionArg);
158 Node* context = Parameter(Descriptor::kContext);
160 GeneratorPrototypeResume(&args, receiver, exception, context,
161 JSGeneratorObject::kThrow,
162 "[Generator].prototype.throw");