1 /* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ECMASCRIPT_JS_ASYNC_GENERATOR_OBJECT_H 17 #define ECMASCRIPT_JS_ASYNC_GENERATOR_OBJECT_H 18 19 #include "ecmascript/js_object-inl.h" 20 #include "ecmascript/js_tagged_value.h" 21 #include "ecmascript/js_tagged_value-inl.h" 22 #include "ecmascript/record.h" 23 #include "ecmascript/js_function.h" 24 #include "ecmascript/js_generator_object.h" 25 26 namespace panda { 27 namespace ecmascript { 28 enum class JSAsyncGeneratorState : uint8_t { 29 UNDEFINED = 0, 30 SUSPENDED_START, 31 SUSPENDED_YIELD, 32 EXECUTING, 33 COMPLETED, 34 AWAITING_RETURN, 35 }; 36 37 enum class AsyncGeneratorResumeMode : uint8_t { 38 RETURN = 0, 39 THROW, 40 NEXT, 41 UNDEFINED 42 }; 43 44 class AsyncGeneratorRequest final : public Record { 45 public: 46 CAST_CHECK(AsyncGeneratorRequest, IsAsyncGeneratorRequest); 47 48 static constexpr size_t COMPLETION_OFFSET = Record::SIZE; 49 ACCESSORS(Completion, COMPLETION_OFFSET, CAPABILITY_OFFSET); 50 ACCESSORS(Capability, CAPABILITY_OFFSET, SIZE); 51 52 DECL_DUMP() 53 54 DECL_VISIT_OBJECT(COMPLETION_OFFSET, SIZE) 55 }; 56 57 class JSAsyncGeneratorObject : public JSObject { 58 public: 59 CAST_CHECK(JSAsyncGeneratorObject, IsAsyncGeneratorObject); 60 61 static constexpr size_t GENERATOR_CONTEXT_OFFSET = JSObject::SIZE; 62 ACCESSORS(GeneratorContext, GENERATOR_CONTEXT_OFFSET, ASYNC_GENERATOR_QUEUE_OFFSET) 63 ACCESSORS(AsyncGeneratorQueue, ASYNC_GENERATOR_QUEUE_OFFSET, GENERATOR_OFFSET) 64 ACCESSORS(GeneratorBrand, GENERATOR_OFFSET, GENERATOR_RESUME_RESULT_OFFSET) 65 ACCESSORS(ResumeResult, GENERATOR_RESUME_RESULT_OFFSET, BIT_FIELD_OFFSET) 66 ACCESSORS_BIT_FIELD(BitField, BIT_FIELD_OFFSET, LAST_OFFSET) 67 DEFINE_ALIGN_SIZE(LAST_OFFSET); 68 69 // define Bitfield 70 static constexpr size_t ASYNC_GENERATOE_STATE_BITS = 4; 71 static constexpr size_t RESUME_MODE_BITS = 3; 72 FIRST_BIT_FIELD(BitField, AsyncGeneratorState, JSAsyncGeneratorState, ASYNC_GENERATOE_STATE_BITS) 73 NEXT_BIT_FIELD(BitField, ResumeMode, AsyncGeneratorResumeMode, RESUME_MODE_BITS, AsyncGeneratorState) 74 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, GENERATOR_CONTEXT_OFFSET, BIT_FIELD_OFFSET) 75 DECL_DUMP() 76 77 // AsyncGeneratorValidate ( generator, generatorBrand ) 78 static void AsyncGeneratorValidate(JSThread *thread, const JSHandle<JSTaggedValue> &gen, const JSTaggedValue &val); 79 80 // AsyncGeneratorResolve ( generator, value, done ) 81 static JSTaggedValue AsyncGeneratorResolve(JSThread *thread, const JSHandle<JSAsyncGeneratorObject> &generator, 82 const JSHandle<JSTaggedValue> value, bool done); 83 84 static JSTaggedValue AsyncGeneratorReject(JSThread *thread, const JSHandle<JSAsyncGeneratorObject> &generator, 85 const JSHandle<JSTaggedValue> value); 86 87 // AsyncGeneratorResumeNext ( generator ) 88 static JSTaggedValue AsyncGeneratorResumeNext(JSThread *thread, const JSHandle<JSAsyncGeneratorObject> &generator); 89 90 // 27.6.3.7 AsyncGeneratorEnqueue ( generator, completion, generatorBrand ) 91 static JSTaggedValue AsyncGeneratorEnqueue(JSThread *thread, const JSHandle<JSTaggedValue> &generator, 92 const JSHandle<CompletionRecord> completionRecord); 93 94 static JSTaggedValue PromiseResolve(JSThread *thread, const JSHandle<JSTaggedValue> promise, 95 const JSHandle<JSTaggedValue> value); 96 97 static JSTaggedValue ProcessorFulfilledFunc(EcmaRuntimeCallInfo *argv); 98 99 static JSTaggedValue ProcessorRejectedFunc(EcmaRuntimeCallInfo *argv); 100 IsSuspendYield()101 inline bool IsSuspendYield() const 102 { 103 return GetAsyncGeneratorState() == JSAsyncGeneratorState::SUSPENDED_YIELD; 104 } 105 IsExecuting()106 inline bool IsExecuting() const 107 { 108 return GetAsyncGeneratorState() == JSAsyncGeneratorState::EXECUTING; 109 } 110 }; 111 112 class JSAsyncGeneratorResNextRetProRstFtn : public JSFunction { 113 public: 114 CAST_CHECK(JSAsyncGeneratorResNextRetProRstFtn, IsJSAsyncGeneratorResNextRetProRstFtn); 115 static constexpr size_t ASYNC_GENERATOR_OBJECT_OFFSET = JSFunction::SIZE; 116 ACCESSORS(AsyncGeneratorObject, ASYNC_GENERATOR_OBJECT_OFFSET, SIZE); 117 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, ASYNC_GENERATOR_OBJECT_OFFSET, SIZE) 118 119 DECL_DUMP() 120 }; 121 } // namespace ecmascript 122 } // namespace panda 123 124 #endif // ECMASCRIPT_JS_ASYNC_GENERATOR_OBJECT_H 125