• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2022-2024 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 #ifndef PANDA_PLUGINS_ETS_RUNTIME_ETS_COROUTINE_H
16 #define PANDA_PLUGINS_ETS_RUNTIME_ETS_COROUTINE_H
17 
18 #include "runtime/coroutines/coroutine_context.h"
19 #include "plugins/ets/runtime/ets_napi_env.h"
20 #include "runtime/coroutines/coroutine.h"
21 #include "runtime/coroutines/coroutine_manager.h"
22 #include "runtime/coroutines/coro_callback_queue.h"
23 
24 namespace ark::ets {
25 class PandaEtsVM;
26 
27 /// @brief The eTS coroutine. It is aware of the native interface and reference storage existance.
28 class EtsCoroutine : public Coroutine {
29 public:
30     NO_COPY_SEMANTIC(EtsCoroutine);
31     NO_MOVE_SEMANTIC(EtsCoroutine);
32 
33     /**
34      * @brief EtsCoroutine factory: the preferrable way to create a coroutine. See CoroutineManager::CoroutineFactory
35      * for details.
36      *
37      * Since C++ requires function type to exactly match the formal parameter type, we have to make this factory a
38      * template. The sole purpose for this is to be able to return both Coroutine* and EtsCoroutine*
39      */
40     template <class T>
41     static T *Create(Runtime *runtime, PandaVM *vm, PandaString name, CoroutineContext *context,
42                      std::optional<EntrypointInfo> &&epInfo = std::nullopt)
43     {
44         mem::InternalAllocatorPtr allocator = runtime->GetInternalAllocator();
45         auto *callbackQueue = allocator->New<CoroCallbackQueue>();
46         auto co = allocator->New<EtsCoroutine>(os::thread::GetCurrentThreadId(), allocator, vm, std::move(name),
47                                                context, callbackQueue, std::move(epInfo));
48         co->Initialize();
49         return co;
50     }
51     ~EtsCoroutine() override = default;
52 
CastFromThread(Thread * thread)53     static EtsCoroutine *CastFromThread(Thread *thread)
54     {
55         ASSERT(thread != nullptr);
56         return static_cast<EtsCoroutine *>(thread);
57     }
58 
GetCurrent()59     static EtsCoroutine *GetCurrent()
60     {
61         Coroutine *co = Coroutine::GetCurrent();
62         if ((co != nullptr) && co->GetThreadLang() == ark::panda_file::SourceLang::ETS) {
63             return CastFromThread(co);
64         }
65         return nullptr;
66     }
67 
SetPromiseClass(void * promiseClass)68     void SetPromiseClass(void *promiseClass)
69     {
70         promiseClassPtr_ = promiseClass;
71     }
72 
GetTlsPromiseClassPointerOffset()73     static constexpr uint32_t GetTlsPromiseClassPointerOffset()
74     {
75         return MEMBER_OFFSET(EtsCoroutine, promiseClassPtr_);
76     }
77 
GetUndefinedObject()78     ALWAYS_INLINE ObjectHeader *GetUndefinedObject() const
79     {
80         return undefinedObj_;
81     }
82 
83     // For mainthread initializer
SetUndefinedObject(ObjectHeader * obj)84     void SetUndefinedObject(ObjectHeader *obj)
85     {
86         undefinedObj_ = obj;
87     }
88 
GetTlsUndefinedObjectOffset()89     static constexpr uint32_t GetTlsUndefinedObjectOffset()
90     {
91         return MEMBER_OFFSET(EtsCoroutine, undefinedObj_);
92     }
93 
94     PANDA_PUBLIC_API PandaEtsVM *GetPandaVM() const;
95     PANDA_PUBLIC_API CoroutineManager *GetCoroutineManager() const;
96 
GetEtsNapiEnv()97     PandaEtsNapiEnv *GetEtsNapiEnv() const
98     {
99         return etsNapiEnv_.get();
100     }
101 
102     void Initialize() override;
103     void RequestCompletion(Value returnValue) override;
104     void FreeInternalMemory() override;
105 
106 protected:
107     // we would like everyone to use the factory to create a EtsCoroutine
108     explicit EtsCoroutine(ThreadId id, mem::InternalAllocatorPtr allocator, PandaVM *vm, PandaString name,
109                           CoroutineContext *context, CallbackQueue *queue, std::optional<EntrypointInfo> &&epInfo);
110 
111 private:
112     panda_file::Type GetReturnType();
113     EtsObject *GetReturnValueAsObject(panda_file::Type returnType, Value returnValue);
114     EtsObject *GetValueFromPromiseSync(EtsPromise *promise);
115 
116     std::unique_ptr<PandaEtsNapiEnv> etsNapiEnv_;
117     void *promiseClassPtr_ {nullptr};
118 
119     ObjectHeader *undefinedObj_ {};
120 
121     // Allocator calls our protected ctor
122     friend class mem::Allocator;
123 };
124 }  // namespace ark::ets
125 
126 #endif  // PANDA_PLUGINS_ETS_RUNTIME_ETS_COROUTINE_H
127