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