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