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