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 #include "napi/native_node_api.h"
17 #include "native_api_internal.h"
18 #include "native_engine/native_engine.h"
19 #include "utils/log.h"
20
21 static constexpr int32_t MAX_THREAD_SAFE_COUNT = 128;
22
napi_module_register(napi_module * mod)23 NAPI_EXTERN void napi_module_register(napi_module* mod)
24 {
25 if (mod == nullptr) {
26 HILOG_ERROR("mod is nullptr");
27 return;
28 }
29
30 NativeModuleManager* moduleManager = NativeModuleManager::GetInstance();
31 NativeModule module;
32
33 module.version = mod->nm_version;
34 module.fileName = mod->nm_filename;
35 module.name = mod->nm_modname;
36 module.registerCallback = (RegisterCallback)mod->nm_register_func;
37
38 moduleManager->Register(&module);
39 }
40
napi_module_with_js_register(napi_module_with_js * mod)41 NAPI_EXTERN void napi_module_with_js_register(napi_module_with_js* mod)
42 {
43 if (mod == nullptr) {
44 HILOG_ERROR("mod is nullptr");
45 return;
46 }
47
48 NativeModuleManager* moduleManager = NativeModuleManager::GetInstance();
49 NativeModule module;
50
51 module.version = mod->nm_version;
52 module.fileName = mod->nm_filename;
53 module.name = mod->nm_modname;
54 module.registerCallback = (RegisterCallback)mod->nm_register_func;
55 module.getJSCode = (GetJSCodeCallback)mod->nm_get_js_code;
56 module.getABCCode = (GetJSCodeCallback)mod->nm_get_abc_code;
57
58 moduleManager->Register(&module);
59 }
60
napi_fatal_error(const char * location,size_t location_len,const char * message,size_t message_len)61 NAPI_EXTERN NAPI_NO_RETURN void napi_fatal_error(const char* location,
62 size_t location_len,
63 const char* message,
64 size_t message_len)
65 {
66 (void)location_len;
67 (void)message_len;
68 HILOG_FATAL("FATAL ERROR: %{public}s %{public}s\n", location, message);
69 abort();
70 }
71
napi_fatal_exception(napi_env env,napi_value err)72 NAPI_INNER_EXTERN napi_status napi_fatal_exception(napi_env env, napi_value err)
73 {
74 HILOG_INFO("%{public}s, start.", __func__);
75 CHECK_ENV(env);
76 CHECK_ARG(env, err);
77
78 auto engine = reinterpret_cast<NativeEngine*>(env);
79 auto jsError = reinterpret_cast<NativeValue*>(err);
80 if (engine->TriggerFatalException(jsError)) {
81 HILOG_INFO("%{public}s, end.", __func__);
82 return napi_status::napi_ok;
83 } else {
84 HILOG_INFO("%{public}s, end.", __func__);
85 exit(1);
86 return napi_status::napi_ok;
87 }
88 }
89
90 // Methods to manage simple async operations
napi_create_async_work(napi_env env,napi_value async_resource,napi_value async_resource_name,napi_async_execute_callback execute,napi_async_complete_callback complete,void * data,napi_async_work * result)91 NAPI_EXTERN napi_status napi_create_async_work(napi_env env,
92 napi_value async_resource,
93 napi_value async_resource_name,
94 napi_async_execute_callback execute,
95 napi_async_complete_callback complete,
96 void* data,
97 napi_async_work* result)
98 {
99 CHECK_ENV(env);
100 CHECK_ARG(env, async_resource_name);
101 CHECK_ARG(env, execute);
102 CHECK_ARG(env, complete);
103 CHECK_ARG(env, result);
104
105 auto engine = reinterpret_cast<NativeEngine*>(env);
106 auto asyncResource = reinterpret_cast<NativeValue*>(async_resource);
107 auto asyncResourceName = reinterpret_cast<NativeValue*>(async_resource_name);
108 auto asyncExecute = reinterpret_cast<NativeAsyncExecuteCallback>(execute);
109 auto asyncComplete = reinterpret_cast<NativeAsyncCompleteCallback>(complete);
110
111 auto asyncWork = engine->CreateAsyncWork(asyncResource, asyncResourceName, asyncExecute, asyncComplete, data);
112
113 *result = reinterpret_cast<napi_async_work>(asyncWork);
114 return napi_status::napi_ok;
115 }
116
napi_delete_async_work(napi_env env,napi_async_work work)117 NAPI_EXTERN napi_status napi_delete_async_work(napi_env env, napi_async_work work)
118 {
119 CHECK_ENV(env);
120 CHECK_ARG(env, work);
121
122 auto asyncWork = reinterpret_cast<NativeAsyncWork*>(work);
123
124 delete asyncWork;
125 asyncWork = nullptr;
126
127 return napi_status::napi_ok;
128 }
129
napi_queue_async_work(napi_env env,napi_async_work work)130 NAPI_EXTERN napi_status napi_queue_async_work(napi_env env, napi_async_work work)
131 {
132 CHECK_ENV(env);
133 CHECK_ARG(env, work);
134
135 auto asyncWork = reinterpret_cast<NativeAsyncWork*>(work);
136
137 asyncWork->Queue();
138 return napi_status::napi_ok;
139 }
140
napi_cancel_async_work(napi_env env,napi_async_work work)141 NAPI_EXTERN napi_status napi_cancel_async_work(napi_env env, napi_async_work work)
142 {
143 CHECK_ENV(env);
144 CHECK_ARG(env, work);
145
146 auto asyncWork = reinterpret_cast<NativeAsyncWork*>(work);
147
148 asyncWork->Cancel();
149 return napi_status::napi_ok;
150 }
151
152 // Version management
napi_get_node_version(napi_env env,const napi_node_version ** version)153 NAPI_EXTERN napi_status napi_get_node_version(napi_env env, const napi_node_version** version)
154 {
155 (void)version;
156 return napi_status::napi_ok;
157 }
158
159 // Return the current libuv event loop for a given environment
napi_get_uv_event_loop(napi_env env,struct uv_loop_s ** loop)160 NAPI_EXTERN napi_status napi_get_uv_event_loop(napi_env env, struct uv_loop_s** loop)
161 {
162 CHECK_ENV(env);
163 CHECK_ARG(env, loop);
164
165 auto engine = reinterpret_cast<NativeEngine*>(env);
166 *loop = engine->GetUVLoop();
167
168 return napi_status::napi_ok;
169 }
170
napi_add_env_cleanup_hook(napi_env env,void (* fun)(void * arg),void * arg)171 NAPI_INNER_EXTERN napi_status napi_add_env_cleanup_hook(napi_env env, void (*fun)(void* arg), void* arg)
172 {
173 CHECK_ENV(env);
174 CHECK_ARG(env, fun);
175
176 auto engine = reinterpret_cast<NativeEngine*>(env);
177 engine->AddCleanupHook(fun, arg);
178
179 return napi_clear_last_error(env);
180 }
181
napi_remove_env_cleanup_hook(napi_env env,void (* fun)(void * arg),void * arg)182 NAPI_INNER_EXTERN napi_status napi_remove_env_cleanup_hook(napi_env env, void (*fun)(void* arg), void* arg)
183 {
184 CHECK_ENV(env);
185 CHECK_ARG(env, fun);
186
187 auto engine = reinterpret_cast<NativeEngine*>(env);
188 engine->RemoveCleanupHook(fun, arg);
189
190 return napi_clear_last_error(env);
191 }
192
193 using CleanupHook = void (*)(void* arg);
194 using AsyncCleanupHook = void (*)(void* arg, void (*)(void*), void*);
195
196 struct AsyncCleanupHookInfo final {
197 napi_env env_;
198 AsyncCleanupHook fun_;
199 void* arg_;
200 bool started_ = false;
201 // Use a self-reference to make sure the storage is kept alive while the
202 // cleanup hook is registered but not yet finished.
203 std::shared_ptr<AsyncCleanupHookInfo> self_;
204 };
205
206 // Opaque type that is basically an alias for `shared_ptr<AsyncCleanupHookInfo>`
207 // (but not publicly so for easier ABI/API changes). In particular,
208 // std::shared_ptr does not generally maintain a consistent ABI even on a
209 // specific platform.
210 struct ACHHandle final {
211 std::shared_ptr<AsyncCleanupHookInfo> info_;
212 };
213
214 struct DeleteACHHandle {
operator ()DeleteACHHandle215 void operator()(ACHHandle* handle) const
216 {
217 delete handle;
218 };
219 };
220 using AsyncCleanupHookHandle = std::unique_ptr<ACHHandle, DeleteACHHandle>;
221
FinishAsyncCleanupHook(void * arg)222 static void FinishAsyncCleanupHook(void* arg)
223 {
224 HILOG_INFO("%{public}s, start.", __func__);
225 AsyncCleanupHookInfo* info = static_cast<AsyncCleanupHookInfo*>(arg);
226 std::shared_ptr<AsyncCleanupHookInfo> keep_alive = info->self_;
227 auto engine = reinterpret_cast<NativeEngine*>(info->env_);
228 engine->DecreaseWaitingRequestCounter();
229 info->self_.reset();
230 HILOG_INFO("%{public}s, end.", __func__);
231 }
232
RunAsyncCleanupHook(void * arg)233 static void RunAsyncCleanupHook(void* arg)
234 {
235 HILOG_INFO("%{public}s, start.", __func__);
236 AsyncCleanupHookInfo* info = static_cast<AsyncCleanupHookInfo*>(arg);
237 auto engine = reinterpret_cast<NativeEngine*>(info->env_);
238 engine->IncreaseWaitingRequestCounter();
239 info->started_ = true;
240 info->fun_(info->arg_, FinishAsyncCleanupHook, info);
241 HILOG_INFO("%{public}s, end.", __func__);
242 }
243
AddEnvironmentCleanupHook(napi_env env,AsyncCleanupHook fun,void * arg)244 static AsyncCleanupHookHandle AddEnvironmentCleanupHook(napi_env env, AsyncCleanupHook fun, void* arg)
245 {
246 HILOG_INFO("%{public}s, start.", __func__);
247 auto info = std::make_shared<AsyncCleanupHookInfo>();
248 info->env_ = env;
249 info->fun_ = fun;
250 info->arg_ = arg;
251 info->self_ = info;
252 auto engine = reinterpret_cast<NativeEngine*>(env);
253 engine->AddCleanupHook(RunAsyncCleanupHook, info.get());
254 HILOG_INFO("%{public}s, end.", __func__);
255 return AsyncCleanupHookHandle(new ACHHandle { info });
256 }
257
RemoveEnvironmentCleanupHook(AsyncCleanupHookHandle handle)258 static void RemoveEnvironmentCleanupHook(AsyncCleanupHookHandle handle)
259 {
260 HILOG_INFO("%{public}s, start.", __func__);
261 if (handle->info_->started_) {
262 return;
263 }
264 handle->info_->self_.reset();
265 auto engine = reinterpret_cast<NativeEngine*>(handle->info_->env_);
266 engine->RemoveCleanupHook(RunAsyncCleanupHook, handle->info_.get());
267 HILOG_INFO("%{public}s, end.", __func__);
268 }
269
270 struct napi_async_cleanup_hook_handle__ {
napi_async_cleanup_hook_handle__napi_async_cleanup_hook_handle__271 napi_async_cleanup_hook_handle__(napi_env env, napi_async_cleanup_hook user_hook, void* user_data)
272 : env_(env), user_hook_(user_hook), user_data_(user_data)
273 {
274 HILOG_INFO("%{public}s, start.", __func__);
275 handle_ = AddEnvironmentCleanupHook(env, Hook, this);
276 HILOG_INFO("%{public}s, end.", __func__);
277 }
278
~napi_async_cleanup_hook_handle__napi_async_cleanup_hook_handle__279 ~napi_async_cleanup_hook_handle__()
280 {
281 HILOG_INFO("%{public}s, start.", __func__);
282 RemoveEnvironmentCleanupHook(std::move(handle_));
283 if (done_cb_ != nullptr) {
284 done_cb_(done_data_);
285 }
286 HILOG_INFO("%{public}s, end.", __func__);
287 }
288
Hooknapi_async_cleanup_hook_handle__289 static void Hook(void* data, void (*done_cb)(void*), void* done_data)
290 {
291 HILOG_INFO("%{public}s, start.", __func__);
292 auto handle = static_cast<napi_async_cleanup_hook_handle__*>(data);
293 handle->done_cb_ = done_cb;
294 handle->done_data_ = done_data;
295 handle->user_hook_(handle, handle->user_data_);
296 HILOG_INFO("%{public}s, end.", __func__);
297 }
298
299 AsyncCleanupHookHandle handle_;
300 napi_env env_ = nullptr;
301 napi_async_cleanup_hook user_hook_ = nullptr;
302 void* user_data_ = nullptr;
303 void (*done_cb_)(void*) = nullptr;
304 void* done_data_ = nullptr;
305 };
306
napi_add_async_cleanup_hook(napi_env env,napi_async_cleanup_hook hook,void * arg,napi_async_cleanup_hook_handle * remove_handle)307 NAPI_INNER_EXTERN napi_status napi_add_async_cleanup_hook(
308 napi_env env, napi_async_cleanup_hook hook, void* arg, napi_async_cleanup_hook_handle* remove_handle)
309 {
310 CHECK_ENV(env);
311 CHECK_ARG(env, hook);
312
313 napi_async_cleanup_hook_handle__* handle = new napi_async_cleanup_hook_handle__(env, hook, arg);
314
315 if (remove_handle != nullptr)
316 *remove_handle = handle;
317
318 return napi_clear_last_error(env);
319 }
320
napi_remove_async_cleanup_hook(napi_async_cleanup_hook_handle remove_handle)321 NAPI_INNER_EXTERN napi_status napi_remove_async_cleanup_hook(napi_async_cleanup_hook_handle remove_handle)
322 {
323 if (remove_handle == nullptr) {
324 return napi_invalid_arg;
325 }
326
327 delete remove_handle;
328 return napi_ok;
329 }
330
331 // Methods to manager threadsafe
napi_create_threadsafe_function(napi_env env,napi_value func,napi_value async_resource,napi_value async_resource_name,size_t max_queue_size,size_t initial_thread_count,void * thread_finalize_data,napi_finalize thread_finalize_cb,void * context,napi_threadsafe_function_call_js call_js_cb,napi_threadsafe_function * result)332 NAPI_EXTERN napi_status napi_create_threadsafe_function(napi_env env, napi_value func, napi_value async_resource,
333 napi_value async_resource_name, size_t max_queue_size, size_t initial_thread_count, void* thread_finalize_data,
334 napi_finalize thread_finalize_cb, void* context, napi_threadsafe_function_call_js call_js_cb,
335 napi_threadsafe_function* result)
336 {
337 CHECK_ENV(env);
338 CHECK_ARG(env, async_resource_name);
339 RETURN_STATUS_IF_FALSE(env, max_queue_size >= 0, napi_invalid_arg);
340 RETURN_STATUS_IF_FALSE(
341 env, initial_thread_count > 0 && initial_thread_count <= MAX_THREAD_SAFE_COUNT, napi_invalid_arg);
342 CHECK_ARG(env, result);
343 if (func == nullptr) {
344 CHECK_ARG(env, call_js_cb);
345 }
346
347 auto engine = reinterpret_cast<NativeEngine*>(env);
348 auto jsFunc = reinterpret_cast<NativeValue*>(func);
349 auto asyncResource = reinterpret_cast<NativeValue*>(async_resource);
350 auto asyncResourceName = reinterpret_cast<NativeValue*>(async_resource_name);
351 auto finalizeCallback = reinterpret_cast<NativeFinalize>(thread_finalize_cb);
352 auto callJsCallback = reinterpret_cast<NativeThreadSafeFunctionCallJs>(call_js_cb);
353 auto safeAsyncWork = engine->CreateSafeAsyncWork(jsFunc, asyncResource, asyncResourceName, max_queue_size,
354 initial_thread_count, thread_finalize_data, finalizeCallback, context, callJsCallback);
355 CHECK_ENV(safeAsyncWork);
356
357 auto ret = safeAsyncWork->Init();
358 if (ret) {
359 *result = reinterpret_cast<napi_threadsafe_function>(safeAsyncWork);
360 } else {
361 return napi_status::napi_generic_failure;
362 }
363
364 return napi_status::napi_ok;
365 }
366
napi_call_threadsafe_function(napi_threadsafe_function func,void * data,napi_threadsafe_function_call_mode is_blocking)367 NAPI_EXTERN napi_status napi_call_threadsafe_function(
368 napi_threadsafe_function func, void* data, napi_threadsafe_function_call_mode is_blocking)
369 {
370 CHECK_ENV(func);
371
372 auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func);
373 auto callMode = static_cast<NativeThreadSafeFunctionCallMode>(is_blocking);
374
375 napi_status status = napi_status::napi_ok;
376 auto code = safeAsyncWork->Send(data, callMode);
377 switch (code) {
378 case SafeAsyncCode::SAFE_ASYNC_QUEUE_FULL:
379 status = napi_status::napi_queue_full;
380 break;
381 case SafeAsyncCode::SAFE_ASYNC_INVALID_ARGS:
382 status = napi_status::napi_invalid_arg;
383 break;
384 case SafeAsyncCode::SAFE_ASYNC_CLOSED:
385 status = napi_status::napi_closing;
386 break;
387 case SafeAsyncCode::SAFE_ASYNC_FAILED:
388 status = napi_status::napi_generic_failure;
389 break;
390 default:
391 status = napi_status::napi_ok;
392 break;
393 }
394
395 return status;
396 }
397
napi_acquire_threadsafe_function(napi_threadsafe_function func)398 NAPI_EXTERN napi_status napi_acquire_threadsafe_function(napi_threadsafe_function func)
399 {
400 CHECK_ENV(func);
401
402 auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func);
403
404 auto ret = safeAsyncWork->Acquire();
405 if (ret != SafeAsyncCode::SAFE_ASYNC_OK) {
406 return napi_status::napi_generic_failure;
407 }
408
409 return napi_status::napi_ok;
410 }
411
napi_release_threadsafe_function(napi_threadsafe_function func,napi_threadsafe_function_release_mode mode)412 NAPI_EXTERN napi_status napi_release_threadsafe_function(
413 napi_threadsafe_function func, napi_threadsafe_function_release_mode mode)
414 {
415 CHECK_ENV(func);
416
417 auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func);
418 auto releaseMode = static_cast<NativeThreadSafeFunctionReleaseMode>(mode);
419
420 auto ret = safeAsyncWork->Release(releaseMode);
421 if (ret != SafeAsyncCode::SAFE_ASYNC_OK) {
422 return napi_status::napi_generic_failure;
423 }
424
425 return napi_status::napi_ok;
426 }
427
napi_get_threadsafe_function_context(napi_threadsafe_function func,void ** result)428 NAPI_EXTERN napi_status napi_get_threadsafe_function_context(napi_threadsafe_function func, void** result)
429 {
430 CHECK_ENV(func);
431 CHECK_ENV(result);
432
433 auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func);
434 *result = safeAsyncWork->GetContext();
435
436 return napi_status::napi_ok;
437 }
438
napi_ref_threadsafe_function(napi_env env,napi_threadsafe_function func)439 NAPI_EXTERN napi_status napi_ref_threadsafe_function(napi_env env, napi_threadsafe_function func)
440 {
441 CHECK_ENV(env);
442 CHECK_ARG(env, func);
443
444 auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func);
445 auto ret = safeAsyncWork->Ref();
446 if (!ret) {
447 return napi_status::napi_generic_failure;
448 }
449
450 return napi_status::napi_ok;
451 }
452
napi_unref_threadsafe_function(napi_env env,napi_threadsafe_function func)453 NAPI_EXTERN napi_status napi_unref_threadsafe_function(napi_env env, napi_threadsafe_function func)
454 {
455 CHECK_ENV(env);
456 CHECK_ARG(env, func);
457
458 auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func);
459 auto ret = safeAsyncWork->Unref();
460 if (!ret) {
461 return napi_status::napi_generic_failure;
462 }
463
464 return napi_status::napi_ok;
465 }
466
napi_async_init(napi_env env,napi_value async_resource,napi_value async_resource_name,napi_async_context * result)467 NAPI_INNER_EXTERN napi_status napi_async_init(
468 napi_env env, napi_value async_resource, napi_value async_resource_name, napi_async_context* result)
469 {
470 CHECK_ENV(env);
471 CHECK_ARG(env, async_resource_name);
472 CHECK_ARG(env, result);
473
474 auto asyncResource = reinterpret_cast<NativeValue*>(async_resource);
475 auto asyncResourceName = reinterpret_cast<NativeValue*>(async_resource_name);
476
477 auto async_context = new NativeAsyncContext();
478 async_context->asyncResource = asyncResource;
479 async_context->asyncResourceName = asyncResourceName;
480
481 *result = reinterpret_cast<napi_async_context>(async_context);
482
483 return napi_clear_last_error(env);
484 }
485
napi_async_destroy(napi_env env,napi_async_context async_context)486 NAPI_INNER_EXTERN napi_status napi_async_destroy(napi_env env, napi_async_context async_context)
487 {
488 CHECK_ENV(env);
489 CHECK_ARG(env, async_context);
490
491 NativeAsyncContext* native_async_context = reinterpret_cast<NativeAsyncContext*>(async_context);
492
493 delete native_async_context;
494
495 return napi_clear_last_error(env);
496 }
497
napi_open_callback_scope(napi_env env,napi_value,napi_async_context async_context_handle,napi_callback_scope * result)498 NAPI_INNER_EXTERN napi_status napi_open_callback_scope(
499 napi_env env, napi_value, napi_async_context async_context_handle, napi_callback_scope* result)
500 {
501 CHECK_ENV(env);
502 CHECK_ARG(env, result);
503
504 auto engine = reinterpret_cast<NativeEngine*>(env);
505 auto callbackScopeManager = engine->GetCallbackScopeManager();
506 CHECK_ARG(env, callbackScopeManager);
507
508 auto callbackScope = callbackScopeManager->Open(engine);
509 callbackScopeManager->IncrementOpenCallbackScopes();
510
511 *result = reinterpret_cast<napi_callback_scope>(callbackScope);
512
513 return napi_clear_last_error(env);
514 }
515
napi_close_callback_scope(napi_env env,napi_callback_scope scope)516 NAPI_INNER_EXTERN napi_status napi_close_callback_scope(napi_env env, napi_callback_scope scope)
517 {
518 CHECK_ENV(env);
519 CHECK_ARG(env, scope);
520
521 auto engine = reinterpret_cast<NativeEngine*>(env);
522 auto callbackScopeManager = engine->GetCallbackScopeManager();
523 CHECK_ARG(env, callbackScopeManager);
524 size_t count = callbackScopeManager->GetOpenCallbackScopes();
525 if (count == 0) {
526 return napi_callback_scope_mismatch;
527 }
528 callbackScopeManager->DecrementOpenCallbackScopes();
529
530 auto callbackScope = reinterpret_cast<NativeCallbackScope*>(scope);
531 callbackScopeManager->Close(callbackScope);
532
533 return napi_clear_last_error(env);
534 }
535
napi_set_instance_data(napi_env env,void * data,napi_finalize finalize_cb,void * finalize_hint)536 NAPI_INNER_EXTERN napi_status napi_set_instance_data(
537 napi_env env, void* data, napi_finalize finalize_cb, void* finalize_hint)
538 {
539 HILOG_INFO("%{public}s", __func__);
540 CHECK_ENV(env);
541 auto engine = reinterpret_cast<NativeEngine*>(env);
542 auto callback = reinterpret_cast<NativeFinalize>(finalize_cb);
543 engine->SetInstanceData(data, callback, finalize_hint);
544 return napi_clear_last_error(env);
545 }
546
napi_get_instance_data(napi_env env,void ** data)547 NAPI_INNER_EXTERN napi_status napi_get_instance_data(napi_env env, void** data)
548 {
549 HILOG_INFO("%{public}s", __func__);
550 CHECK_ENV(env);
551 CHECK_ARG(env, data);
552 auto engine = reinterpret_cast<NativeEngine*>(env);
553 engine->GetInstanceData(data);
554 return napi_clear_last_error(env);
555 }
556
node_api_get_module_file_name(napi_env env,const char ** result)557 NAPI_INNER_EXTERN napi_status node_api_get_module_file_name(napi_env env, const char** result)
558 {
559 HILOG_INFO("%{public}s", __func__);
560 CHECK_ENV(env);
561 CHECK_ARG(env, result);
562 auto engine = reinterpret_cast<NativeEngine*>(env);
563 *result = engine->GetModuleFileName();
564 HILOG_INFO("%{public}s, napi called fileName : %{public}s", __func__, *result);
565 return napi_clear_last_error(env);
566 }