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