1 /*
2  * Copyright (c) 2021 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 FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_API_INTERNAL_H
17 #define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_API_INTERNAL_H
18 
19 #include "napi/native_api.h"
20 #include "native_engine.h"
21 #include "utils/log.h"
22 
napi_clear_last_error(napi_env env)23 static inline napi_status napi_clear_last_error(napi_env env)
24 {
25     ((NativeEngine*)env)->ClearLastError();
26     return napi_ok;
27 }
28 
29 static inline napi_status napi_set_last_error(napi_env env,
30                                               napi_status error_code,
31                                               uint32_t engine_error_code = 0,
32                                               void* engine_reserved = nullptr)
33 {
34     ((NativeEngine*)env)->SetLastError(error_code, engine_error_code, engine_reserved);
35     return error_code;
36 }
37 
38 #define RETURN_STATUS_IF_FALSE(env, condition, status) \
39     if (!(condition)) {                                \
40         return napi_set_last_error((env), (status));   \
41     }
42 
43 #define CHECK_ENV(env)           \
44     if ((env) == nullptr) {      \
45         return napi_invalid_arg; \
46     }
47 
48 #define CHECK_ARG(env, arg) RETURN_STATUS_IF_FALSE((env), ((arg) != nullptr), napi_invalid_arg)
49 
50 #define NAPI_PREAMBLE(env)                                                     \
51     CHECK_ENV((env));                                                          \
52     RETURN_STATUS_IF_FALSE(                                                    \
53         (env),                                                                 \
54         (reinterpret_cast<NativeEngine*>(env))->lastException_.IsEmpty(),      \
55         napi_pending_exception);                                               \
56         napi_clear_last_error((env));                                          \
57     TryCatch tryCatch(env)
58 
59 #define GET_RETURN_STATUS(env)                                                 \
60     (!tryCatch.HasCaught()                                                     \
61         ? napi_ok                                                              \
62         : napi_set_last_error((env), napi_pending_exception))
63 
64 #define CHECK_WITH_RETURN(condition, status)   \
65     if (!(condition)) {                        \
66         return status;                         \
67     }
68 
69 #define CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, obj)                 \
70     bool isObj = (nativeValue)->IsObject((vm));                                \
71     bool isFunc = (nativeValue)->IsFunction((vm));                             \
72     RETURN_STATUS_IF_FALSE((env), isObj || isFunc, napi_object_expected);      \
73     Local<ObjectRef> (obj);                                                    \
74     if (LIKELY(isObj)) {                                                       \
75         (obj) = Local<ObjectRef>((nativeValue));                               \
76     } else {                                                                   \
77         (obj) = (nativeValue)->ToObject((vm));                                 \
78     }
79 
80 #define CROSS_THREAD_CHECK(env)                                                     \
81     do {                                                                            \
82         NativeEngine* engine = reinterpret_cast<NativeEngine*>((env));              \
83         if (UNLIKELY(engine->IsCrossThreadCheckEnabled())) {                        \
84             ThreadId tid = NativeEngine::GetCurSysTid();                            \
85             if (tid != engine->GetSysTid()) {                                       \
86                 HILOG_FATAL("current napi interface cannot run in multi-thread, "   \
87                             "thread id: %{public}d, current thread id: %{public}d", \
88                             engine->GetSysTid(), tid);                              \
89             };                                                                      \
90         };                                                                          \
91     } while (0)
92 
93 #define WEAK_CROSS_THREAD_CHECK(env)                                                \
94     do {                                                                            \
95         NativeEngine* engine = reinterpret_cast<NativeEngine*>((env));              \
96         if (UNLIKELY(engine->IsCrossThreadCheckEnabled())) {                        \
97             ThreadId tid = NativeEngine::GetCurSysTid();                            \
98             if (tid != engine->GetSysTid()) {                                       \
99                 HILOG_ERROR("current napi interface cannot run in multi-thread, "   \
100                             "thread id: %{public}d, current thread id: %{public}d", \
101                             engine->GetSysTid(), tid);                              \
102             };                                                                      \
103         };                                                                          \
104     } while (0)
105 
106 #ifndef LIKELY
107 #define LIKELY(exp) (__builtin_expect((exp) != 0, true))  // NOLINT(cppcoreguidelines-macro-usage)
108 #endif
109 
110 #ifndef UNLIKELY
111 #define UNLIKELY(exp) (__builtin_expect((exp) != 0, false))  // NOLINT(cppcoreguidelines-macro-usage)
112 #endif
113 
114 #endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_API_INTERNAL_H */
115