• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ECMASCRIPT_NAPI_JSNAPI_HELPER_H
17 #define ECMASCRIPT_NAPI_JSNAPI_HELPER_H
18 
19 #include "ecmascript/ecma_runtime_call_info.h"
20 #include "ecmascript/js_handle.h"
21 #include "ecmascript/js_tagged_value.h"
22 #include "ecmascript/napi/include/jsnapi.h"
23 
24 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
25 #define RETURN_VALUE_IF_ABRUPT(thread, value)                 \
26     do {                                                      \
27         if (thread->HasPendingException()) {                  \
28             LOG_FULL(ERROR) << "occur exception need return"; \
29             return value;                                     \
30         }                                                     \
31     } while (false)
32 
33 #if ECMASCRIPT_ENABLE_NAPI_SPECIAL_CHECK
34 #define LOG_IF_SPECIAL(handleValue, level)                                                       \
35     do {                                                                                         \
36         LOG_ECMA(DEBUG) << "Enable napi special check";                                           \
37         if ((handleValue).GetTaggedValue().IsSpecial()) {                                        \
38             LOG_FULL(level) << "Special value " << (handleValue).GetTaggedType() << " checked!"; \
39         }                                                                                        \
40     } while (false)
41 #else
42 #define LOG_IF_SPECIAL(handleValue, level) static_cast<void>(0)
43 #endif
44 
45 #define CROSS_THREAD_CHECK(vm)                                                                  \
46     [[maybe_unused]] JSThread *thread = (vm)->GetAndFastCheckJSThread()
47 
48 #define CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, returnVal)                              \
49     CROSS_THREAD_CHECK(vm);                                                                      \
50     do {                                                                                         \
51         if (thread->HasPendingException()) {                                                     \
52             LOG_ECMA(ERROR) << "Pending exception before " << __FUNCTION__ << " called in line:" \
53                             << __LINE__ << ", exception details as follows:";                    \
54             JSNApi::PrintExceptionInfo(vm);                                                      \
55             return returnVal;                                                                    \
56         }                                                                                        \
57     } while (false)
58 
59 #define CROSS_THREAD_AND_EXCEPTION_CHECK(vm)                                                      \
60     CROSS_THREAD_CHECK(vm);                                                                       \
61     do {                                                                                          \
62         if (thread->HasPendingException()) {                                                      \
63             LOG_ECMA(ERROR) << "Pending exception before " << __FUNCTION__ << " called, in line:" \
64                             << __LINE__ << ", exception details as follows:";                     \
65             JSNApi::PrintExceptionInfo(vm);                                                       \
66             return;                                                                               \
67         }                                                                                         \
68     } while (false)
69 
70 #define DCHECK_SPECIAL_VALUE(jsValueRef)                                                     \
71     do {                                                                                     \
72         auto val = reinterpret_cast<JSTaggedValue *>(jsValueRef);                            \
73         if (UNLIKELY(val->IsSpecial())) {                                                    \
74             LOG_FULL(ERROR) << "JSNApi special value:0x" << val->GetRawData() << " checked"; \
75             return;                                                                          \
76         }                                                                                    \
77     } while (false)
78 
79 #define DCHECK_SPECIAL_VALUE_WITH_RETURN(jsValueRef, retValue)                               \
80     do {                                                                                     \
81         auto val = reinterpret_cast<JSTaggedValue *>(jsValueRef);                            \
82         if (UNLIKELY(val->IsSpecial())) {                                                    \
83             LOG_FULL(ERROR) << "JSNApi special value:0x" << val->GetRawData() << " checked"; \
84             return (retValue);                                                               \
85         }                                                                                    \
86     } while (false)
87 
88 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
89 #define TYPED_ARRAY_ALL(V) \
90     V(Int8Array)           \
91     V(Uint8Array)          \
92     V(Uint8ClampedArray)   \
93     V(Int16Array)          \
94     V(Uint16Array)         \
95     V(Int32Array)          \
96     V(Uint32Array)         \
97     V(Float32Array)        \
98     V(Float64Array)        \
99     V(BigInt64Array)       \
100     V(BigUint64Array)
101 
102 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
103 #define EXCEPTION_ERROR_ALL(V)         \
104     V(Error, ERROR)                    \
105     V(RangeError, RANGE_ERROR)         \
106     V(SyntaxError, SYNTAX_ERROR)       \
107     V(ReferenceError, REFERENCE_ERROR) \
108     V(TypeError, TYPE_ERROR)           \
109     V(AggregateError, AGGREGATE_ERROR) \
110     V(EvalError, EVAL_ERROR)           \
111     V(OOMError, OOM_ERROR)             \
112     V(TerminationError, TERMINATION_ERROR)
113 
114 namespace panda {
115 using NativeFinalize = void (*)(EcmaVM *);
116 class JSNApiHelper {
117 public:
118     template<typename T>
ToLocal(ecmascript::JSHandle<ecmascript::JSTaggedValue> from)119     static inline Local<T> ToLocal(ecmascript::JSHandle<ecmascript::JSTaggedValue> from)
120     {
121         return Local<T>(from.GetAddress());
122     }
123 
ToJSTaggedValue(JSValueRef * from)124     static inline ecmascript::JSTaggedValue ToJSTaggedValue(JSValueRef *from)
125     {
126         ASSERT(from != nullptr);
127         return *reinterpret_cast<ecmascript::JSTaggedValue *>(from);
128     }
129 
ToJSHandle(Local<JSValueRef> from)130     static inline ecmascript::JSHandle<ecmascript::JSTaggedValue> ToJSHandle(Local<JSValueRef> from)
131     {
132         ASSERT(!from.IsEmpty());
133         return ecmascript::JSHandle<ecmascript::JSTaggedValue>(reinterpret_cast<uintptr_t>(*from));
134     }
135 
ToJSHandle(JSValueRef * from)136     static inline ecmascript::JSHandle<ecmascript::JSTaggedValue> ToJSHandle(JSValueRef *from)
137     {
138         ASSERT(from != nullptr);
139         return ecmascript::JSHandle<ecmascript::JSTaggedValue>(reinterpret_cast<uintptr_t>(from));
140     }
141 };
142 
143 class NativeReferenceHelper {
144 public:
NativeReferenceHelper(EcmaVM * vm,Global<ObjectRef> obj,NativeFinalize callback)145     NativeReferenceHelper(EcmaVM *vm, Global<ObjectRef> obj, NativeFinalize callback)
146         :  vm_(vm), obj_(obj), callback_(callback) {}
~NativeReferenceHelper()147     ~NativeReferenceHelper()
148     {
149         obj_.FreeGlobalHandleAddr();
150     }
FreeGlobalCallBack(void * ref)151     static void FreeGlobalCallBack(void* ref)
152     {
153         auto that = reinterpret_cast<NativeReferenceHelper*>(ref);
154         that->obj_.FreeGlobalHandleAddr();
155     }
156 
NativeFinalizeCallBack(void * ref)157     static void NativeFinalizeCallBack(void* ref)
158     {
159         auto that = reinterpret_cast<NativeReferenceHelper*>(ref);
160         if (that->callback_ != nullptr) {
161             that->callback_(that->vm_);
162         }
163         that->callback_ = nullptr;
164     }
165 
SetWeakCallback()166     void SetWeakCallback()
167     {
168         obj_.SetWeakCallback(this, FreeGlobalCallBack, NativeFinalizeCallBack);
169     }
170 
171 private:
172     EcmaVM *vm_;
173     Global<ObjectRef> obj_;
174     NativeFinalize callback_ = nullptr;
175 };
176 
177 class Callback {
178 public:
179     static ecmascript::JSTaggedValue RegisterCallback(ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo);
180 };
181 }  // namespace panda
182 #endif  // ECMASCRIPT_NAPI_JSNAPI_HELPER_H
183