• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2023-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 
16 #ifndef PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_CODE_SCOPES_H
17 #define PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_CODE_SCOPES_H
18 
19 #include "plugins/ets/runtime/interop_js/interop_context.h"
20 
21 namespace ark::ets::interop::js {
22 
23 template <bool IN_ETS_MANAGED = false>
24 class InteropCodeScope {
25 public:
coro_(coro)26     explicit InteropCodeScope(EtsCoroutine *coro, char const *descr = nullptr) : coro_(coro)
27     {
28         ASSERT(coro_ == ManagedThread::GetCurrent());
29         auto ctx = InteropCtx::Current(coro_);
30 
31         if constexpr (IN_ETS_MANAGED) {
32             ASSERT(coro_->IsManagedCode());
33         } else if (UNLIKELY(!coro_->IsManagedCode())) {
34             coro_->ManagedCodeBegin();
35             switched_ = true;
36         }
37         ctx->CallStack().AllocRecord(coro_->GetCurrentFrame(), descr);
38     }
39 
~InteropCodeScope()40     ~InteropCodeScope()
41     {
42         auto ctx = InteropCtx::Current(EtsCoroutine::CastFromThread(coro_));
43 
44         ctx->CallStack().PopRecord();
45         if constexpr (IN_ETS_MANAGED) {
46             ASSERT(coro_->IsManagedCode());
47         } else if (UNLIKELY(switched_)) {
48             coro_->ManagedCodeEnd();
49         }
50     }
51 
52 private:
53     EtsCoroutine *coro_;
54     bool switched_ = false;
55 
56     NO_COPY_SEMANTIC(InteropCodeScope);
57     NO_MOVE_SEMANTIC(InteropCodeScope);
58 };
59 
60 using InteropCodeScopeETS = InteropCodeScope<true>;
61 
62 class JSNapiEnvScope {
63 public:
JSNapiEnvScope(InteropCtx * ctx,napi_env newEnv)64     explicit JSNapiEnvScope(InteropCtx *ctx, napi_env newEnv) : ctx_(ctx)
65     {
66         saved_ = ctx_->jsEnv_;
67         ctx_->SetJSEnv(newEnv);
68     }
69 
~JSNapiEnvScope()70     ~JSNapiEnvScope()
71     {
72         ctx_->SetJSEnv(saved_);
73     }
74 
75 private:
76     NO_COPY_SEMANTIC(JSNapiEnvScope);
77     NO_MOVE_SEMANTIC(JSNapiEnvScope);
78 
79     InteropCtx *ctx_ {};
80     napi_env saved_ {};
81 };
82 
83 class InteropCodeScopeJS {
84 public:
85     InteropCodeScopeJS(EtsCoroutine *coro, napi_env env, char const *descr = nullptr)
codeScope_(coro,descr)86         : codeScope_(coro, descr), jsEnvScope_(InteropCtx::Current(coro), env)
87     {
88     }
89 
90     ~InteropCodeScopeJS() = default;
91 
92 private:
93     NO_COPY_SEMANTIC(InteropCodeScopeJS);
94     NO_MOVE_SEMANTIC(InteropCodeScopeJS);
95 
96     InteropCodeScope<false> codeScope_;
97     JSNapiEnvScope jsEnvScope_;
98 };
99 
100 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
101 #define INTEROP_CODE_SCOPE_JS(coro, env) InteropCodeScopeJS codeScope(coro, env, __PRETTY_FUNCTION__)
102 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
103 #define INTEROP_CODE_SCOPE_ETS(coro) InteropCodeScopeETS codeScope(coro, __PRETTY_FUNCTION__)
104 
105 }  // namespace ark::ets::interop::js
106 
107 #endif  // !PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_CODE_SCOPES_H
108