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 #ifndef NAPI_ARK_INTEROP_INTERNAL_H
17 #define NAPI_ARK_INTEROP_INTERNAL_H
18
19 #include <string>
20 #include <native_engine/native_engine.h>
21
22 #include "ark_interop_macro.h"
23 #include "ark_interop_napi.h"
24 #include "ecmascript/napi/include/jsnapi.h"
25
26 using EcmaVM = panda::EcmaVM;
27
28 // below interface shares internal, never export
29 typedef void (*ARKTS_AsyncCallback)(ARKTS_Env env, void*);
30
31 bool ARKTSInner_ReportJSErrors(ARKTS_Env env, bool abortIfUnhandled);
32 void ARKTSInner_ReportNativeError(const char* format, ...) __attribute__((format(printf, 1, 2)));
33 COV_EXPORT std::string ARKTSInner_FormatJSError(ARKTS_Env env, ARKTS_Value jsError);
34 bool ARKTSInner_ThrowJSErrorToCJ(ARKTS_Env env, ARKTS_Value error);
35 bool ARKTSInner_ThrowNativeErrorToCJ(const char* error);
36 void ARKTSInner_CreateAsyncTask(ARKTS_Env env, ARKTS_AsyncCallback callback, void* data);
37 // cangjie callbacks
38 void ARKTSInner_CJArrayBufferDeleter(void*, void* buffer, void* lambdaId);
39 void ARKTSInner_CJExternalDeleter(void*, void* data, void* env);
40 ARKTS_Result ARKTSInner_CJLambdaInvoker(ARKTS_CallInfo callInfo, int64_t lambdaId);
41 void ARKTSInner_CJLambdaDeleter(ARKTS_Env env, int64_t lambdaId);
42 COV_EXPORT void ARKTSInner_CJAsyncCallback(ARKTS_Env env, void* data);
43
44 panda::JSValueRef* ARKTSInner_Escape(ARKTS_Env env, ARKTS_Scope scope, ARKTS_Value ret);
45
46 #ifdef __OHOS__
47 #include <memory>
48 #include "event_handler.h"
49
50 using ARKTS_Loop = std::shared_ptr<OHOS::AppExecFwk::EventHandler>;
51 #else
52 using ARKTS_Loop = void*;
53 #endif
54
55 // @deprecated
56 ARKTS_Loop ARKTS_GetOrCreateEventHandler(ARKTS_Env env);
57 bool ARKTSInner_InitLoop(napi_env env, ARKTS_Env vm, uv_loop_t* loop);
58 void ARKTS_DisposeEventHandler(ARKTS_Env env);
59 void ARKTS_DisposeJSContext(ARKTS_Env env);
60 void ARKTS_InitGlobalManager(ARKTS_Env env);
61 void ARKTS_RemoveGlobalManager(ARKTS_Env env);
62
63 template<typename T>
ARKTS_ToHandle(ARKTS_Value & value)64 ARKTS_INLINE panda::Local<T> ARKTS_ToHandle(ARKTS_Value& value)
65 {
66 auto v = BIT_CAST(value, panda::JSValueRef);
67 void* addr;
68 if (v.IsHeapObject()) {
69 addr = value;
70 } else {
71 addr = &value;
72 }
73 return BIT_CAST(addr, panda::Local<T>);
74 }
75
ARKTS_ToValue(ARKTS_Value value)76 ARKTS_INLINE panda::JSValueRef ARKTS_ToValue(ARKTS_Value value)
77 {
78 auto v = BIT_CAST(value, panda::JSValueRef);
79 if (v.IsHeapObject()) {
80 return *BIT_CAST(value, panda::JSValueRef*);
81 } else {
82 return v;
83 }
84 }
85
86 template<typename T>
ARKTS_FromHandle(panda::Local<T> & value)87 ARKTS_INLINE ARKTS_Value ARKTS_FromHandle(panda::Local<T>& value)
88 {
89 if (value.IsNull()) {
90 return ARKTS_CreateUndefined();
91 } else if (value->IsHeapObject()) {
92 constexpr uint64_t addrMask = 0xFFFF'FFFF'FFFF;
93 auto addr = BIT_CAST(value, uint64_t) & addrMask;
94 return P_CAST(addr, ARKTS_Value);
95 } else {
96 return *BIT_CAST(value, ARKTS_Value*);
97 }
98 }
99
ARKTS_ToResult(panda::EcmaVM * vm,ARKTS_Value value)100 ARKTS_INLINE ARKTS_Result ARKTS_ToResult(panda::EcmaVM* vm, ARKTS_Value value)
101 {
102 auto tag = BIT_CAST(value, panda::JSValueRef);
103 if (!tag.IsHeapObject()) {
104 auto local = panda::JSNApi::CreateLocal(vm, tag);
105 return BIT_CAST(local, ARKTS_Result);
106 } else {
107 return BIT_CAST(value, ARKTS_Result);
108 }
109 }
110
111 #define NATIVE_ERROR(msg) ARKTSInner_ReportNativeError("[%s]: %s", __FUNCTION__, msg)
112 #define ARKTS_ASSERT(condition, error, ret) \
113 if (!(condition)) { \
114 NATIVE_ERROR(error); \
115 return ret; \
116 }
117 #define ARKTS_ASSERT_P(condition, error) ARKTS_ASSERT(condition, error, nullptr)
118 #define ARKTS_ASSERT_F(condition, error) ARKTS_ASSERT(condition, error, false)
119 #define ARKTS_ASSERT_I(condition, error) ARKTS_ASSERT(condition, error, 0)
120 #define ARKTS_ASSERT_V(condition, error) ARKTS_ASSERT(condition, error,)
121
122 #ifdef DEBUG_JS
123 #define ARKTS_CHECK(condition, ret) \
124 if (UNLIKELY(!(condition))) { \
125 return ret; \
126 }
127 #else
128 #define ARKTS_CHECK(condition, ret) condition
129 #endif
130
131 #define ARKTS_CHECK_F(condition) ARKTS_CHECK(condition, false)
132
133 #endif // NAPI_ARK_INTEROP_INTERNAL_H
134