• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 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 #include "plugins/ets/runtime/interop_js/js_refconvert_function.h"
17 #include "plugins/ets/runtime/interop_js/code_scopes.h"
18 
19 namespace ark::ets::interop::js {
20 
EtsLambdaProxyInvoke(napi_env env,napi_callback_info cbinfo)21 napi_value EtsLambdaProxyInvoke(napi_env env, napi_callback_info cbinfo)
22 {
23     auto coro = EtsCoroutine::GetCurrent();
24     auto ctx = InteropCtx::Current(coro);
25     INTEROP_CODE_SCOPE_JS(coro, env);
26 
27     size_t argc;
28     napi_value athis;
29     void *data;
30     NAPI_CHECK_FATAL(napi_get_cb_info(env, cbinfo, &argc, nullptr, &athis, &data));
31     auto jsArgs = ctx->GetTempArgs<napi_value>(argc);
32     NAPI_CHECK_FATAL(napi_get_cb_info(env, cbinfo, &argc, jsArgs->data(), &athis, &data));
33 
34     auto sharedRef = static_cast<ets_proxy::SharedReference *>(data);
35     ASSERT(sharedRef != nullptr);
36 
37     auto etsThis = sharedRef->GetEtsObject(ctx);
38     ASSERT(etsThis != nullptr);
39     auto method = etsThis->GetClass()->GetMethod("invoke");
40     ASSERT(method != nullptr);
41 
42     return CallETSInstance(coro, ctx, method->GetPandaMethod(), *jsArgs, etsThis);
43 }
44 
WrapImpl(InteropCtx * ctx,EtsObject * obj)45 napi_value JSRefConvertFunction::WrapImpl(InteropCtx *ctx, EtsObject *obj)
46 {
47     auto coro = EtsCoroutine::GetCurrent();
48     ASSERT(ctx == InteropCtx::Current(coro));
49     auto env = ctx->GetJSEnv();
50 
51     ASSERT(obj->GetClass() == klass_);
52     ASSERT(klass_->GetMethod("invoke") != nullptr);
53 
54     JSValue *jsValue;
55     {
56         NapiScope jsHandleScope(env);
57 
58         ets_proxy::SharedReferenceStorage *storage = ctx->GetSharedRefStorage();
59         if (LIKELY(storage->HasReference(obj))) {
60             ets_proxy::SharedReference *sharedRef = storage->GetReference(obj);
61             ASSERT(sharedRef != nullptr);
62             jsValue = JSValue::CreateRefValue(coro, ctx, sharedRef->GetJsObject(env), napi_function);
63         } else {
64             napi_value jsFn;
65             ets_proxy::SharedReference *payloadSharedRef = storage->GetNextAlloc();
66             NAPI_CHECK_FATAL(
67                 napi_create_function(env, "invoke", NAPI_AUTO_LENGTH, EtsLambdaProxyInvoke, payloadSharedRef, &jsFn));
68 
69             ets_proxy::SharedReference *sharedRef = storage->CreateETSObjectRef(ctx, obj, jsFn);
70             if (UNLIKELY(sharedRef == nullptr)) {
71                 ASSERT(InteropCtx::SanityJSExceptionPending());
72                 return nullptr;
73             }
74             ASSERT(payloadSharedRef == sharedRef);
75             jsValue = JSValue::CreateRefValue(coro, ctx, jsFn, napi_function);
76         }
77     }
78     return jsValue->GetRefValue(env);
79 }
80 
UnwrapImpl(InteropCtx * ctx,napi_value jsFun)81 EtsObject *JSRefConvertFunction::UnwrapImpl([[maybe_unused]] InteropCtx *ctx, [[maybe_unused]] napi_value jsFun)
82 {
83     UNREACHABLE();
84 }
85 
86 }  // namespace ark::ets::interop::js
87