2
* Copyright (c) 2022-2023 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
7
* http://www.apache.org/licenses/LICENSE-2.0
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.
16
#include "convertors-node.h"
17
#include "init-exports-cb.h"
20
uint8_t* getUInt8Elements(const Napi::CallbackInfo& info, int index) {
21
return getTypedElements<uint8_t>(info, index);
24
int8_t* getInt8Elements(const Napi::CallbackInfo& info, int index) {
25
return getTypedElements<int8_t>(info, index);
28
uint16_t* getUInt16Elements(const Napi::CallbackInfo& info, int index) {
29
return getTypedElements<uint16_t>(info, index);
32
int16_t* getInt16Elements(const Napi::CallbackInfo& info, int index) {
33
return getTypedElements<int16_t>(info, index);
36
uint32_t* getUInt32Elements(const Napi::CallbackInfo& info, int index) {
37
return getTypedElements<uint32_t>(info, index);
40
uint32_t* getUInt32Elements(const Napi::Env env, Napi::Value value) {
41
return getTypedElements<uint32_t>(env, value);
44
int32_t* getInt32Elements(const Napi::CallbackInfo& info, int index) {
45
return getTypedElements<int32_t>(info, index);
48
float* getFloat32Elements(const Napi::CallbackInfo& info, int index) {
49
return getTypedElements<float>(info, index);
52
KNativePointer* getPointerElements(const Napi::CallbackInfo& info, int index) {
53
return getTypedElements<KNativePointer>(info, index);
56
KBoolean getBoolean(const Napi::Env env, Napi::Value value) {
57
if (value.IsBoolean()) {
58
return static_cast<KBoolean>(value.As<Napi::Boolean>().Value());
60
return static_cast<KBoolean>(getInt32(env, value) != 0);
63
KBoolean getBoolean(const Napi::CallbackInfo& info, int index) {
64
NAPI_ASSERT_INDEX(info, index, false);
65
return getBoolean(info.Env(), info[index]);
68
KInt getInt32(const Napi::Env env, Napi::Value value) {
69
if (!value.IsNumber()) {
70
Napi::Error::New(env, "Expected Number")
71
.ThrowAsJavaScriptException();
75
return value.As<Napi::Number>().Int32Value();
77
KInt getInt32(const Napi::CallbackInfo& info, int index) {
78
NAPI_ASSERT_INDEX(info, index, 0);
79
return getInt32(info.Env(), info[index]);
82
KUInt getUInt32(const Napi::CallbackInfo& info, int index) {
83
NAPI_ASSERT_INDEX(info, index, 0);
85
if (!info[index].IsNumber()) {
86
Napi::Error::New(info.Env(), "Expected Number")
87
.ThrowAsJavaScriptException();
91
return info[index].As<Napi::Number>().Uint32Value();
94
KFloat getFloat32(const Napi::CallbackInfo& info, int index) {
95
NAPI_ASSERT_INDEX(info, index, 0);
97
if (!info[index].IsNumber()) {
98
Napi::Error::New(info.Env(), "Expected Number")
99
.ThrowAsJavaScriptException();
103
return info[index].As<Napi::Number>().FloatValue();
106
KDouble getFloat64(const Napi::CallbackInfo& info, int index) {
107
NAPI_ASSERT_INDEX(info, index, 0);
109
if (!info[index].IsNumber()) {
110
Napi::Error::New(info.Env(), "Expected Number")
111
.ThrowAsJavaScriptException();
115
return info[index].As<Napi::Number>().DoubleValue();
118
KStringPtr getString(const Napi::CallbackInfo& info, int index) {
119
NAPI_ASSERT_INDEX(info, index, KStringPtr());
121
auto arg = info[index];
122
if (arg.IsNull() || arg.IsUndefined()) {
126
if (!info[index].IsString()) {
127
Napi::Error::New(info.Env(), "Expected String")
128
.ThrowAsJavaScriptException();
132
auto string = arg.As<Napi::String>().ToString().Utf8Value();
133
return KStringPtr(string.c_str());
136
KNativePointer getPointer(const Napi::Env env, Napi::Value value) {
137
if (!value.IsBigInt()) {
138
Napi::Error::New(env, "cannot be coerced to pointer")
139
.ThrowAsJavaScriptException();
143
bool isWithinRange = true;
144
uint64_t ptrU64 = value.As<Napi::BigInt>().Uint64Value(&isWithinRange);
145
if (!isWithinRange) {
146
Napi::Error::New(env, "cannot be coerced to pointer, value is too large")
147
.ThrowAsJavaScriptException();
150
return reinterpret_cast<KNativePointer>(ptrU64);
153
KNativePointer getPointer(const Napi::CallbackInfo& info, int index) {
154
NAPI_ASSERT_INDEX(info, index, nullptr);
155
return getPointer(info.Env(), info[index]);
158
Napi::Object getObject(const Napi::CallbackInfo& info, int index) {
159
NAPI_ASSERT_INDEX(info, index, info.Env().Global());
160
if (!info[index].IsObject()) {
161
Napi::Error::New(info.Env(), "Expected Object")
162
.ThrowAsJavaScriptException();
163
return info.Env().Global();
166
return info[index].As<Napi::Object>();
169
Napi::Value makeString(const Napi::CallbackInfo& info, const KStringPtr& value) {
170
return Napi::String::New(info.Env(), value.isNull() ? "" : value.data());
173
Napi::Value makeString(const Napi::CallbackInfo& info, const std::string& value) {
174
return Napi::String::New(info.Env(), value);
177
Napi::Value makeBoolean(const Napi::CallbackInfo& info, int8_t value) {
178
return Napi::Number::New(info.Env(), value);
181
Napi::Value makeInt32(const Napi::CallbackInfo& info, int32_t value) {
182
return Napi::Number::New(info.Env(), value);
185
Napi::Value makeUInt32(const Napi::CallbackInfo& info, uint32_t value) {
186
return Napi::Number::New(info.Env(), value);
189
Napi::Value makeFloat32(const Napi::CallbackInfo& info, float value) {
190
return Napi::Number::New(info.Env(), value);
193
Napi::Value makePointer(const Napi::CallbackInfo& info, void* value) {
194
return makePointer(info.Env(), value);
197
Napi::Value makePointer(Napi::Env env, void* value) {
198
return Napi::BigInt::New(env, static_cast<uint64_t>(reinterpret_cast<uintptr_t>(value)));
201
Napi::Value makeVoid(const Napi::CallbackInfo& info) {
202
return info.Env().Undefined();
205
Napi::Object makeObject(const Napi::CallbackInfo& info, napi_value object) {
206
return Napi::Object(info.Env(), object);
209
#if _MSC_VER >= 1932 // Visual Studio 2022 version 17.2+
210
# pragma comment(linker, "/alternatename:__imp___std_init_once_complete=__imp_InitOnceComplete")
211
# pragma comment(linker, "/alternatename:__imp___std_init_once_begin_initialize=__imp_InitOnceBeginInitialize")
214
Exports* Exports::getInstance() {
215
static Exports *instance = nullptr;
216
if (instance == nullptr) {
217
instance = new Exports();
223
* Sets a new callback and returns its previous value.
225
Napi::ModuleRegisterCallback ProvideModuleRegisterCallback(Napi::ModuleRegisterCallback value = nullptr) {
226
static const Napi::ModuleRegisterCallback DEFAULT_CB = [](Napi::Env env, Napi::Object exports) { return exports; };
227
static Napi::ModuleRegisterCallback curCallback = DEFAULT_CB;
229
Napi::ModuleRegisterCallback prevCallback = curCallback;
230
curCallback = value ? value : DEFAULT_CB;
234
static Napi::Object InitModule(Napi::Env env, Napi::Object exports) {
235
LOG("InitModule: " QUOTE(INTEROP_LIBRARY_NAME) "\n");
236
for (const auto& impl: Exports::getInstance()->getImpls()) {
237
exports.Set(Napi::String::New(env, impl.first.c_str()),
238
Napi::Function::New(env, impl.second, impl.first.c_str()));
240
return ProvideModuleRegisterCallback()(env, exports);
243
NODE_API_MODULE(INTEROP_LIBRARY_NAME, InitModule)