• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 CONVERTORS_NAPI_H_
17 #define CONVERTORS_NAPI_H_
18 
19 #include <unordered_map>
20 #include <vector>
21 #include <string>
22 
23 #ifndef TS_NAPI_OHOS
24 #include <node_api.h>
25 #else
26 #include <native_api.h>
27 #include <native_node_api.h>
28 #endif
29 #include "panda_types.h"
30 
31 // NOLINTBEGIN
32 template <class T>
33 struct InteropTypeConverter {
34     using InteropType = T;
convertFromInteropTypeConverter35     static T convertFrom([[maybe_unused]] napi_env env, InteropType value)
36     {
37         return value;
38     }
convertToInteropTypeConverter39     static InteropType convertTo([[maybe_unused]] napi_env env, T value)
40     {
41         return value;
42     }
releaseInteropTypeConverter43     static void release([[maybe_unused]] napi_env env, [[maybe_unused]] InteropType value, [[maybe_unused]] T converted)
44     {
45     }
46 };
47 
48 template <typename Type>
makeResult(napi_env env,Type value)49 inline typename InteropTypeConverter<Type>::InteropType makeResult(napi_env env, Type value)
50 {
51     return InteropTypeConverter<Type>::convertTo(env, value);
52 }
53 
54 template <typename Type>
getArgument(napi_env env,typename InteropTypeConverter<Type>::InteropType arg)55 inline Type getArgument(napi_env env, typename InteropTypeConverter<Type>::InteropType arg)
56 {
57     return InteropTypeConverter<Type>::convertFrom(env, arg);
58 }
59 
60 template <typename Type>
releaseArgument(napi_env env,typename InteropTypeConverter<Type>::InteropType arg,Type data)61 inline void releaseArgument(napi_env env, typename InteropTypeConverter<Type>::InteropType arg, Type data)
62 {
63     InteropTypeConverter<Type>::release(env, arg, data);
64 }
65 
66 template <>
67 struct InteropTypeConverter<KInteropBuffer> {
68     using InteropType = napi_value;
69     static KInteropBuffer convertFrom(napi_env env, InteropType value)
70     {
71         auto placeholder = 0;
72         KInteropBuffer result = {placeholder, nullptr, 0, nullptr};
73         bool isArrayBuffer = false;
74         napi_is_arraybuffer(env, value, &isArrayBuffer);
75         if (isArrayBuffer) {
76             napi_get_arraybuffer_info(env, value, &result.data, (size_t *)&result.length);
77         } else {
78             bool isDataView = false;
79             napi_is_dataview(env, value, &isDataView);
80             if (isDataView) {
81                 napi_get_dataview_info(env, value, (size_t *)&result.length, &result.data, nullptr, nullptr);
82             }
83         }
84         return result;
85     }
86     static InteropType convertTo(napi_env env, KInteropBuffer value)
87     {
88         KInteropBuffer *copy = new KInteropBuffer(value);
89         napi_value result;
90         napi_status status = napi_create_external_arraybuffer(
91             env, value.data, value.length,
92             []([[maybe_unused]] napi_env env_, [[maybe_unused]] void *finalize_data, void *finalize_hint) {
93                 KInteropBuffer *buffer = reinterpret_cast<KInteropBuffer *>(finalize_hint);
94                 buffer->dispose(buffer->resourceId);
95                 delete buffer;
96             },
97             (void *)copy, &result);
98         if (status != napi_ok) {
99             // do smth here
100         }
101         return result;
102     };
103     static void release([[maybe_unused]] napi_env env, [[maybe_unused]] InteropType value,
104                         [[maybe_unused]] KInteropBuffer converted)
105     {
106     }
107 };
108 
109 template <>
110 struct InteropTypeConverter<KStringPtr> {
111     using InteropType = napi_value;
112     static KStringPtr convertFrom(napi_env env, InteropType value)
113     {
114         if (value == nullptr)
115             return KStringPtr();
116         KStringPtr result;
117         size_t length = 0;
118         napi_status status = napi_get_value_string_utf8(env, value, nullptr, 0, &length);
119         if (status != 0)
120             return result;
121         result.resize(length);
122         napi_get_value_string_utf8(env, value, result.data(), length + 1, nullptr);
123         return result;
124     }
125     static InteropType convertTo(napi_env env, const KStringPtr &value)
126     {
127         napi_value result;
128         napi_create_string_utf8(env, value.c_str(), value.length(), &result);
129         return result;
130     }
131     static void release([[maybe_unused]] napi_env env, [[maybe_unused]] InteropType value,
132                         [[maybe_unused]] const KStringPtr &converted)
133     {
134     }
135 };
136 
137 template <>
138 struct InteropTypeConverter<KInteropNumber> {
139     using InteropType = napi_value;
140     static KInteropNumber convertFrom(napi_env env, InteropType interopValue)
141     {
142         double value = 0.0;
143         napi_get_value_double(env, interopValue, &value);
144         return KInteropNumber::fromDouble(value);
145     }
146     static InteropType convertTo(napi_env env, KInteropNumber value)
147     {
148         napi_value result;
149         napi_create_double(env, value.asDouble(), &result);
150         return result;
151     }
152     static void release([[maybe_unused]] napi_env env, [[maybe_unused]] InteropType value,
153                         [[maybe_unused]] KInteropNumber converted)
154     {
155     }
156 };
157 
158 template <>
159 struct InteropTypeConverter<KVMObjectHandle> {
160     using InteropType = napi_value;
161     static inline KVMObjectHandle convertFrom([[maybe_unused]] napi_env env, InteropType value)
162     {
163         return reinterpret_cast<KVMObjectHandle>(value);
164     }
165     static InteropType convertTo([[maybe_unused]] napi_env env, KVMObjectHandle value)
166     {
167         return reinterpret_cast<napi_value>(value);
168     }
169     static inline void release([[maybe_unused]] napi_env env, [[maybe_unused]] InteropType value,
170                                [[maybe_unused]] KVMObjectHandle converted)
171     {
172     }
173 };
174 
175 template <>
176 struct InteropTypeConverter<KInteropReturnBuffer> {
177     using InteropType = napi_value;
178     static inline KInteropReturnBuffer convertFrom(napi_env env, InteropType value) = delete;
179     static void disposer([[maybe_unused]] napi_env env, [[maybe_unused]] void *data, void *hint)
180     {
181         KInteropReturnBuffer *bufferCopy = (KInteropReturnBuffer *)hint;
182         bufferCopy->dispose(bufferCopy->data, bufferCopy->length);
183         delete bufferCopy;
184     }
185     static InteropType convertTo(napi_env env, KInteropReturnBuffer value)
186     {
187         napi_value result = nullptr;
188         napi_value arrayBuffer = nullptr;
189         auto clone = new KInteropReturnBuffer();
190         *clone = value;
191         napi_create_external_arraybuffer(env, value.data, value.length, disposer, clone, &arrayBuffer);
192         napi_create_typedarray(env, napi_uint8_array, value.length, arrayBuffer, 0, &result);
193         return result;
194     }
195     static inline void release(napi_env env, InteropType value, const KInteropReturnBuffer &converted) = delete;
196 };
197 
198 #define TS_INTEROP_THROW(vmcontext, object, ...)                                   \
199     do {                                                                           \
200         napi_env env = (napi_env)vmcontext;                                        \
201         napi_handle_scope scope = nullptr;                                         \
202         [[maybe_unused]] napi_status status = napi_open_handle_scope(env, &scope); \
203         napi_throw((napi_env)vmcontext, object);                                   \
204         napi_close_handle_scope(env, scope);                                       \
205         /* CC-OFFNXT(G.PRE.05) function gen */                                     \
206         return __VA_ARGS__;                                                        \
207     } while (0)
208 
209 #define TS_INTEROP_THROW_STRING(vmContext, message, ...)                                \
210     do {                                                                                \
211         napi_value value;                                                               \
212         napi_create_string_utf8((napi_env)vmContext, message, strlen(message), &value); \
213         TS_INTEROP_THROW(vmContext, value, __VA_ARGS__);                                \
214     } while (0)
215 
216 // CC-OFFNXT(G.PRE.02-CPP) code generation
217 #define NAPI_ASSERT_INDEX(info, index, result)                        \
218     do {                                                              \
219         /* CC-OFFNXT(G.PRE.02) name part*/                            \
220         if (static_cast<size_t>(index) >= info.Length()) {            \
221             /* CC-OFFNXT(G.PRE.02) name part*/                        \
222             napi_throw_error(info.Env(), nullptr, "No such element"); \
223             /* CC-OFFNXT(G.PRE.05) function gen */                    \
224             return result;                                            \
225         }                                                             \
226     } while (0)
227 
228 // Helpers from node-addon-api
229 // CC-OFFNXT(G.PRE.02-CPP) code generation
230 #define TS_NAPI_THROW_IF_FAILED(env, status, ...)                 \
231     if ((status) != napi_ok) {                                    \
232         const napi_extended_error_info *errorInfo;                \
233         napi_get_last_error_info(env, &errorInfo);                \
234         napi_throw_error(env, nullptr, errorInfo->error_message); \
235         /* CC-OFFNXT(G.PRE.05) function gen */                    \
236         return __VA_ARGS__;                                       \
237     }
238 // CC-OFFNXT(G.PRE.02-CPP) code generation
239 #define TS_NAPI_THROW_IF_FAILED_VOID(env, status)                 \
240     if ((status) != napi_ok) {                                    \
241         const napi_extended_error_info *errorInfo;                \
242         napi_get_last_error_info(env, &errorInfo);                \
243         napi_throw_error(env, nullptr, errorInfo->error_message); \
244         /* CC-OFFNXT(G.PRE.05) function gen */                    \
245         return;                                                   \
246     }
247 
248 class CallbackInfo {
249 public:
250     CallbackInfo(napi_env env, napi_callback_info info) : _env(env)
251     {
252         size_t size = 0;
253         napi_status status = napi_get_cb_info(env, info, &size, nullptr, nullptr, nullptr);
254         TS_NAPI_THROW_IF_FAILED_VOID(env, status);
255         if (size > 0) {
256             args.resize(size);  // NOTE(khil): statically allocate small array for common case with few arguments passed
257             status = napi_get_cb_info(env, info, &size, args.data(), nullptr, nullptr);
258             TS_NAPI_THROW_IF_FAILED_VOID(env, status);
259         }
260     }
261 
262     napi_value operator[](size_t idx) const
263     {
264         if (idx >= Length()) {
265             napi_value result;
266             napi_get_undefined(_env, &result);
267             return result;
268         }
269         return args[idx];
270     }
271 
272     napi_env Env() const
273     {
274         return _env;
275     }
276 
277     size_t Length() const
278     {
279         return args.size();
280     }
281 
282 private:
283     napi_env _env;
284     // napi_callback_info _info;
285     std::vector<napi_value> args;
286 };
287 
288 template <typename ElemType>
289 inline napi_typedarray_type getNapiType() = delete;
290 
291 template <>
292 inline napi_typedarray_type getNapiType<float>()
293 {
294     return napi_float32_array;
295 }
296 
297 template <>
298 inline napi_typedarray_type getNapiType<int8_t>()
299 {
300     return napi_int8_array;
301 }
302 
303 template <>
304 inline napi_typedarray_type getNapiType<uint8_t>()
305 {
306     return napi_uint8_array;
307 }
308 
309 template <>
310 inline napi_typedarray_type getNapiType<int16_t>()
311 {
312     return napi_int16_array;
313 }
314 
315 template <>
316 inline napi_typedarray_type getNapiType<uint16_t>()
317 {
318     return napi_uint16_array;
319 }
320 
321 template <>
322 inline napi_typedarray_type getNapiType<int32_t>()
323 {
324     return napi_int32_array;
325 }
326 
327 template <>
328 inline napi_typedarray_type getNapiType<uint32_t>()
329 {
330     return napi_uint32_array;
331 }
332 
333 template <>
334 inline napi_typedarray_type getNapiType<KNativePointer>()
335 {
336     return napi_biguint64_array;
337 }
338 
339 napi_valuetype getValueTypeChecked(napi_env env, napi_value value);
340 bool isTypedArray(napi_env env, napi_value value);
341 
342 template <typename ElemType>
343 // CC-OFFNXT(G.FUD.06) solid logic, ODR
344 inline ElemType *getTypedElements(napi_env env, napi_value value)
345 {
346     napi_valuetype valueType = getValueTypeChecked(env, value);
347     if (valueType == napi_null) {
348         return nullptr;
349     }
350     if (!isTypedArray(env, value)) {
351         napi_throw_error(env, nullptr, "Expected TypedArray");
352         return nullptr;
353     }
354     napi_value arrayBuffer;
355     void *data = nullptr;
356     size_t byteLength;
357     size_t byteOffset;
358     napi_typedarray_type type;
359     napi_status status = napi_get_typedarray_info(env, value, &type, &byteLength, &data, &arrayBuffer, &byteOffset);
360     TS_NAPI_THROW_IF_FAILED(env, status, nullptr);
361     if (type != getNapiType<ElemType>()) {
362         printf("Array type mismatch. Expected %d got %d\n", getNapiType<ElemType>(), type);
363         napi_throw_error(env, nullptr, "Array type mismatch");
364         return nullptr;
365     }
366     return reinterpret_cast<ElemType *>(data);
367 }
368 
369 template <typename ElemType>
370 inline ElemType *getTypedElements(const CallbackInfo &info, int index)
371 {
372     NAPI_ASSERT_INDEX(info, index, nullptr);
373     return getTypedElements<ElemType>(info.Env(), info[index]);
374 }
375 
376 inline uint8_t *getUInt8Elements(const CallbackInfo &info, int index)
377 {
378     return getTypedElements<uint8_t>(info, index);
379 }
380 
381 inline int8_t *getInt8Elements(const CallbackInfo &info, int index)
382 {
383     return getTypedElements<int8_t>(info, index);
384 }
385 
386 inline uint16_t *getUInt16Elements(const CallbackInfo &info, int index)
387 {
388     return getTypedElements<uint16_t>(info, index);
389 }
390 
391 inline int16_t *getInt16Elements(const CallbackInfo &info, int index)
392 {
393     return getTypedElements<int16_t>(info, index);
394 }
395 
396 inline uint32_t *getUInt32Elements(const CallbackInfo &info, int index)
397 {
398     return getTypedElements<uint32_t>(info, index);
399 }
400 
401 inline uint32_t *getUInt32Elements(napi_env env, napi_value value)
402 {
403     return getTypedElements<uint32_t>(env, value);
404 }
405 
406 inline int32_t *getInt32Elements(const CallbackInfo &info, int index)
407 {
408     return getTypedElements<int32_t>(info, index);
409 }
410 
411 inline float *getFloat32Elements(const CallbackInfo &info, int index)
412 {
413     return getTypedElements<float>(info, index);
414 }
415 
416 inline KNativePointer *getPointerElements(const CallbackInfo &info, int index)
417 {
418     return getTypedElements<KNativePointer>(info, index);
419 }
420 
421 KInt getInt32(napi_env env, napi_value value);
422 inline int32_t getInt32(const CallbackInfo &info, int index)
423 {
424     NAPI_ASSERT_INDEX(info, index, 0);
425     return getInt32(info.Env(), info[index]);
426 }
427 KUInt getUInt32(napi_env env, napi_value value);
428 inline uint32_t getUInt32(const CallbackInfo &info, int index)
429 {
430     NAPI_ASSERT_INDEX(info, index, 0);
431     return getUInt32(info.Env(), info[index]);
432 }
433 KFloat getFloat32(napi_env env, napi_value value);
434 inline float getFloat32(const CallbackInfo &info, int index)
435 {
436     NAPI_ASSERT_INDEX(info, index, 0.0f);
437     return getFloat32(info.Env(), info[index]);
438 }
439 KDouble getFloat64(napi_env env, napi_value value);
440 inline KDouble getFloat64(const CallbackInfo &info, int index)
441 {
442     NAPI_ASSERT_INDEX(info, index, 0.0);
443     return getFloat64(info.Env(), info[index]);
444 }
445 KStringPtr getString(napi_env env, napi_value value);
446 inline KStringPtr getString(const CallbackInfo &info, int index)
447 {
448     NAPI_ASSERT_INDEX(info, index, KStringPtr());
449     return getString(info.Env(), info[index]);
450 }
451 void *getPointer(napi_env env, napi_value value);
452 inline void *getPointer(const CallbackInfo &info, int index)
453 {
454     NAPI_ASSERT_INDEX(info, index, nullptr);
455     return getPointer(info.Env(), info[index]);
456 }
457 KLong getInt64(napi_env env, napi_value value);
458 inline KLong getInt64(const CallbackInfo &info, int index)
459 {
460     NAPI_ASSERT_INDEX(info, index, 0);
461     return getInt64(info.Env(), info[index]);
462 }
463 KBoolean getBoolean(napi_env env, napi_value value);
464 inline KBoolean getBoolean(const CallbackInfo &info, int index)
465 {
466     NAPI_ASSERT_INDEX(info, index, false);
467     return getBoolean(info.Env(), info[index]);
468 }
469 
470 template <typename Type>
471 inline Type getArgument(const CallbackInfo &info, int index) = delete;
472 
473 template <>
474 inline KBoolean getArgument<KBoolean>(const CallbackInfo &info, int index)
475 {
476     return getBoolean(info, index);
477 }
478 
479 template <>
480 inline KUInt getArgument<uint32_t>(const CallbackInfo &info, int index)
481 {
482     return getUInt32(info, index);
483 }
484 
485 template <>
486 inline KInt getArgument<int32_t>(const CallbackInfo &info, int index)
487 {
488     return getInt32(info, index);
489 }
490 
491 template <>
492 inline KInteropNumber getArgument<KInteropNumber>(const CallbackInfo &info, int index)
493 {
494     KInteropNumber res = {0, {0}};
495     NAPI_ASSERT_INDEX(info, index, res);
496     return getArgument<KInteropNumber>(info.Env(), info[index]);
497 }
498 
499 template <>
500 // CC-OFFNXT(G.FUD.06) solid logic, ODR
501 inline KLength getArgument<KLength>(const CallbackInfo &info, int index)
502 {
503     KLength result = {0, 0.0f, 0, 0};
504     NAPI_ASSERT_INDEX(info, index, result);
505     auto value = info[index];
506     napi_valuetype type;
507     auto type_status = napi_typeof(info.Env(), value, &type);
508     if (type_status != 0)
509         return result;
510     switch (type) {
511         case napi_number: {
512             result.value = getFloat32(info.Env(), value);
513             result.unit = 1;
514             result.type = 0;
515             break;
516         }
517         case napi_string: {
518             KStringPtr string = getString(info.Env(), value);
519             ParseKLength(string, &result);
520             result.type = 1;
521             result.resource = 0;
522             break;
523         }
524         case napi_object: {
525             result.value = 0;
526             result.unit = 1;
527             result.type = 2U;
528             napi_value field;
529             napi_status status = napi_get_named_property(info.Env(), value, "id", &field);
530             if (status == 0) {
531                 status = napi_get_value_int32(info.Env(), field, &result.resource);
532                 if (status != 0)
533                     result.resource = 0;
534             } else {
535                 result.resource = 0;
536             }
537             break;
538         }
539         default:
540             throw "Error, unexpected KLength type";
541     }
542     return result;
543 }
544 
545 template <>
546 inline KInteropBuffer getArgument<KInteropBuffer>(const CallbackInfo &info, int index)
547 {
548     KInteropBuffer res = {0, nullptr, 0, nullptr};
549     NAPI_ASSERT_INDEX(info, index, res);
550     return getArgument<KInteropBuffer>((napi_env)info.Env(), (napi_value)info[index]);
551 }
552 
553 template <>
554 inline KFloat getArgument<KFloat>(const CallbackInfo &info, int index)
555 {
556     return getFloat32(info, index);
557 }
558 
559 template <>
560 inline KDouble getArgument<KDouble>(const CallbackInfo &info, int index)
561 {
562     return getFloat64(info, index);
563 }
564 
565 template <>
566 inline KNativePointer getArgument<KNativePointer>(const CallbackInfo &info, int index)
567 {
568     return getPointer(info, index);
569 }
570 
571 template <>
572 inline KLong getArgument<KLong>(const CallbackInfo &info, int index)
573 {
574     return getInt64(info, index);
575 }
576 
577 template <>
578 inline KNativePointerArray getArgument<KNativePointerArray>(const CallbackInfo &info, int index)
579 {
580     return getPointerElements(info, index);
581 }
582 
583 template <>
584 inline uint8_t *getArgument<uint8_t *>(const CallbackInfo &info, int index)
585 {
586     return getUInt8Elements(info, index);
587 }
588 
589 template <>
590 inline const uint8_t *getArgument<const uint8_t *>(const CallbackInfo &info, int index)
591 {
592     return getUInt8Elements(info, index);
593 }
594 
595 template <>
596 inline int8_t *getArgument<int8_t *>(const CallbackInfo &info, int index)
597 {
598     return getInt8Elements(info, index);
599 }
600 
601 template <>
602 inline int16_t *getArgument<int16_t *>(const CallbackInfo &info, int index)
603 {
604     return getInt16Elements(info, index);
605 }
606 
607 template <>
608 inline uint16_t *getArgument<uint16_t *>(const CallbackInfo &info, int index)
609 {
610     return getUInt16Elements(info, index);
611 }
612 
613 template <>
614 inline int32_t *getArgument<int32_t *>(const CallbackInfo &info, int index)
615 {
616     return getInt32Elements(info, index);
617 }
618 
619 template <>
620 inline uint32_t *getArgument<uint32_t *>(const CallbackInfo &info, int index)
621 {
622     return getUInt32Elements(info, index);
623 }
624 
625 template <>
626 inline float *getArgument<float *>(const CallbackInfo &info, int index)
627 {
628     return getFloat32Elements(info, index);
629 }
630 
631 template <>
632 inline KStringPtr getArgument<KStringPtr>(const CallbackInfo &info, int index)
633 {
634     return getString(info, index);
635 }
636 
637 napi_value makeString(napi_env env, KStringPtr value);
638 napi_value makeString(napi_env env, const std::string &value);
639 napi_value makeBoolean(napi_env env, KBoolean value);
640 napi_value makeInt32(napi_env env, int32_t value);
641 napi_value makeUInt32(napi_env env, uint32_t value);
642 napi_value makeFloat32(napi_env env, float value);
643 napi_value makePointer(napi_env env, void *value);
644 napi_value makeVoid(napi_env env);
645 
646 inline napi_value makeVoid(const CallbackInfo &info)
647 {
648     return makeVoid(info.Env());
649 }
650 
651 template <typename Type>
652 inline napi_value makeResult(const CallbackInfo &info, Type value) = delete;
653 
654 template <>
655 inline napi_value makeResult<KBoolean>(const CallbackInfo &info, KBoolean value)
656 {
657     return makeBoolean(info.Env(), value);
658 }
659 
660 template <>
661 inline napi_value makeResult<int32_t>(const CallbackInfo &info, int32_t value)
662 {
663     return makeInt32(info.Env(), value);
664 }
665 
666 template <>
667 inline napi_value makeResult<uint32_t>(const CallbackInfo &info, uint32_t value)
668 {
669     return makeUInt32(info.Env(), value);
670 }
671 
672 template <>
673 inline napi_value makeResult<float>(const CallbackInfo &info, float value)
674 {
675     return makeFloat32(info.Env(), value);
676 }
677 
678 template <>
679 inline napi_value makeResult<KNativePointer>(const CallbackInfo &info, KNativePointer value)
680 {
681     return makePointer(info.Env(), value);
682 }
683 
684 template <>
685 inline napi_value makeResult<KVMObjectHandle>(const CallbackInfo &info, KVMObjectHandle value)
686 {
687     return InteropTypeConverter<KVMObjectHandle>::convertTo(info.Env(), value);
688 }
689 
690 template <>
691 inline napi_value makeResult<KStringPtr>(const CallbackInfo &info, KStringPtr value)
692 {
693     return InteropTypeConverter<KStringPtr>::convertTo(info.Env(), value);
694 }
695 
696 template <>
697 inline napi_value makeResult<KInteropBuffer>(const CallbackInfo &info, KInteropBuffer value)
698 {
699     return InteropTypeConverter<KInteropBuffer>::convertTo(info.Env(), value);
700 }
701 
702 template <>
703 inline napi_value makeResult<KInteropReturnBuffer>(const CallbackInfo &info, KInteropReturnBuffer value)
704 {
705     return InteropTypeConverter<KInteropReturnBuffer>::convertTo(info.Env(), value);
706 }
707 
708 template <>
709 inline napi_value makeResult<KInteropNumber>(const CallbackInfo &info, KInteropNumber value)
710 {
711     return InteropTypeConverter<KInteropNumber>::convertTo(info.Env(), value);
712 }
713 
714 typedef napi_value (*napi_type_t)(napi_env, napi_callback_info);
715 
716 class Exports {
717     std::unordered_map<std::string, std::vector<std::pair<std::string, napi_type_t>>> implementations;
718 
719 public:
720     static Exports *getInstance();
721 
722     std::vector<std::string> getModules();
723     void addMethod(const char *module, const char *name, napi_type_t impl);
724     const std::vector<std::pair<std::string, napi_type_t>> &getMethods(const std::string &module);
725 };
726 
727 // CC-OFFNXT(G.DCL.01) false positive
728 // CC-OFFNXT(G.NAM.01) false positive
729 #define __QUOTE(x) #x
730 #define QUOTE(x) __QUOTE(x)
731 
732 #define MAKE_NODE_EXPORT(module, name)                                            \
733     __attribute__((constructor)) static void __init_##name()                      \
734     {                                                                             \
735         Exports::getInstance()->addMethod(QUOTE(module), "_" #name, Node_##name); \
736     }
737 
738 #ifndef TS_INTEROP_MODULE
739 #error TS_INTEROP_MODULE is undefined
740 #endif
741 
742 #define MAKE_INTEROP_NODE_EXPORT(name) MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
743 
744 #define TS_INTEROP_0(name, Ret)                                     \
745     napi_value Node_##name(napi_env env, napi_callback_info cbinfo) \
746     {                                                               \
747         TS_MAYBE_LOG(name)                                          \
748         CallbackInfo info(env, cbinfo);                             \
749         /* CC-OFFNXT(G.PRE.05) function gen */                      \
750         return makeResult<Ret>(info, impl_##name());                \
751     }                                                               \
752     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
753 
754 #define TS_INTEROP_1(name, Ret, P0)                                 \
755     napi_value Node_##name(napi_env env, napi_callback_info cbinfo) \
756     {                                                               \
757         TS_MAYBE_LOG(name)                                          \
758         CallbackInfo info(env, cbinfo);                             \
759         P0 p0 = getArgument<P0>(info, 0);                           \
760         /* CC-OFFNXT(G.PRE.05) function gen */                      \
761         return makeResult<Ret>(info, impl_##name(p0));              \
762     }                                                               \
763     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
764 
765 #define TS_INTEROP_2(name, Ret, P0, P1)                             \
766     napi_value Node_##name(napi_env env, napi_callback_info cbinfo) \
767     {                                                               \
768         TS_MAYBE_LOG(name)                                          \
769         CallbackInfo info(env, cbinfo);                             \
770         P0 p0 = getArgument<P0>(info, 0);                           \
771         P1 p1 = getArgument<P1>(info, 1);                           \
772         /* CC-OFFNXT(G.PRE.05) function gen */                      \
773         return makeResult<Ret>(info, impl_##name(p0, p1));          \
774     }                                                               \
775     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
776 
777 // CC-OFFNXT(G.PRE.06) solid logic
778 #define TS_INTEROP_3(name, Ret, P0, P1, P2)                         \
779     napi_value Node_##name(napi_env env, napi_callback_info cbinfo) \
780     {                                                               \
781         TS_MAYBE_LOG(name)                                          \
782         CallbackInfo info(env, cbinfo);                             \
783         P0 p0 = getArgument<P0>(info, 0);                           \
784         P1 p1 = getArgument<P1>(info, 1);                           \
785         P2 p2 = getArgument<P2>(info, 2);                           \
786         /* CC-OFFNXT(G.PRE.05) function gen */                      \
787         return makeResult<Ret>(info, impl_##name(p0, p1, p2));      \
788     }                                                               \
789     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
790 
791 // CC-OFFNXT(G.PRE.06) solid logic
792 #define TS_INTEROP_4(name, Ret, P0, P1, P2, P3)                     \
793     napi_value Node_##name(napi_env env, napi_callback_info cbinfo) \
794     {                                                               \
795         TS_MAYBE_LOG(name)                                          \
796         CallbackInfo info(env, cbinfo);                             \
797         P0 p0 = getArgument<P0>(info, 0);                           \
798         P1 p1 = getArgument<P1>(info, 1);                           \
799         P2 p2 = getArgument<P2>(info, 2);                           \
800         P3 p3 = getArgument<P3>(info, 3);                           \
801         /* CC-OFFNXT(G.PRE.05) function gen */                      \
802         return makeResult<Ret>(info, impl_##name(p0, p1, p2, p3));  \
803     }                                                               \
804     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
805 
806 // CC-OFFNXT(G.PRE.06) solid logic
807 #define TS_INTEROP_5(name, Ret, P0, P1, P2, P3, P4)                    \
808     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)    \
809     {                                                                  \
810         TS_MAYBE_LOG(name)                                             \
811         CallbackInfo info(env, cbinfo);                                \
812         P0 p0 = getArgument<P0>(info, 0);                              \
813         P1 p1 = getArgument<P1>(info, 1);                              \
814         P2 p2 = getArgument<P2>(info, 2);                              \
815         P3 p3 = getArgument<P3>(info, 3);                              \
816         P4 p4 = getArgument<P4>(info, 4);                              \
817         /* CC-OFFNXT(G.PRE.05) function gen */                         \
818         return makeResult<Ret>(info, impl_##name(p0, p1, p2, p3, p4)); \
819     }                                                                  \
820     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
821 
822 // CC-OFFNXT(G.PRE.06) solid logic
823 #define TS_INTEROP_6(name, Ret, P0, P1, P2, P3, P4, P5)                    \
824     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)        \
825     {                                                                      \
826         TS_MAYBE_LOG(name)                                                 \
827         CallbackInfo info(env, cbinfo);                                    \
828         P0 p0 = getArgument<P0>(info, 0);                                  \
829         P1 p1 = getArgument<P1>(info, 1);                                  \
830         P2 p2 = getArgument<P2>(info, 2);                                  \
831         P3 p3 = getArgument<P3>(info, 3);                                  \
832         P4 p4 = getArgument<P4>(info, 4);                                  \
833         P5 p5 = getArgument<P5>(info, 5);                                  \
834         /* CC-OFFNXT(G.PRE.05) function gen */                             \
835         return makeResult<Ret>(info, impl_##name(p0, p1, p2, p3, p4, p5)); \
836     }                                                                      \
837     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
838 
839 // CC-OFFNXT(G.PRE.06) solid logic
840 #define TS_INTEROP_7(name, Ret, P0, P1, P2, P3, P4, P5, P6)                    \
841     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)            \
842     {                                                                          \
843         TS_MAYBE_LOG(name)                                                     \
844         CallbackInfo info(env, cbinfo);                                        \
845         P0 p0 = getArgument<P0>(info, 0);                                      \
846         P1 p1 = getArgument<P1>(info, 1);                                      \
847         P2 p2 = getArgument<P2>(info, 2);                                      \
848         P3 p3 = getArgument<P3>(info, 3);                                      \
849         P4 p4 = getArgument<P4>(info, 4);                                      \
850         P5 p5 = getArgument<P5>(info, 5);                                      \
851         P6 p6 = getArgument<P6>(info, 6);                                      \
852         /* CC-OFFNXT(G.PRE.05) function gen */                                 \
853         return makeResult<Ret>(info, impl_##name(p0, p1, p2, p3, p4, p5, p6)); \
854     }                                                                          \
855     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
856 
857 // CC-OFFNXT(G.PRE.06) solid logic
858 #define TS_INTEROP_8(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7)                    \
859     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)                \
860     {                                                                              \
861         TS_MAYBE_LOG(name)                                                         \
862         CallbackInfo info(env, cbinfo);                                            \
863         P0 p0 = getArgument<P0>(info, 0);                                          \
864         P1 p1 = getArgument<P1>(info, 1);                                          \
865         P2 p2 = getArgument<P2>(info, 2);                                          \
866         P3 p3 = getArgument<P3>(info, 3);                                          \
867         P4 p4 = getArgument<P4>(info, 4);                                          \
868         P5 p5 = getArgument<P5>(info, 5);                                          \
869         P6 p6 = getArgument<P6>(info, 6);                                          \
870         P7 p7 = getArgument<P7>(info, 7);                                          \
871         /* CC-OFFNXT(G.PRE.05) function gen */                                     \
872         return makeResult<Ret>(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7)); \
873     }                                                                              \
874     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
875 
876 // CC-OFFNXT(G.PRE.06) solid logic
877 #define TS_INTEROP_9(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8)                    \
878     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)                    \
879     {                                                                                  \
880         TS_MAYBE_LOG(name)                                                             \
881         CallbackInfo info(env, cbinfo);                                                \
882         P0 p0 = getArgument<P0>(info, 0);                                              \
883         P1 p1 = getArgument<P1>(info, 1);                                              \
884         P2 p2 = getArgument<P2>(info, 2);                                              \
885         P3 p3 = getArgument<P3>(info, 3);                                              \
886         P4 p4 = getArgument<P4>(info, 4);                                              \
887         P5 p5 = getArgument<P5>(info, 5);                                              \
888         P6 p6 = getArgument<P6>(info, 6);                                              \
889         P7 p7 = getArgument<P7>(info, 7);                                              \
890         P8 p8 = getArgument<P8>(info, 8);                                              \
891         /* CC-OFFNXT(G.PRE.05) function gen */                                         \
892         return makeResult<Ret>(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8)); \
893     }                                                                                  \
894     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
895 
896 // CC-OFFNXT(G.PRE.06) solid logic
897 #define TS_INTEROP_10(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9)                   \
898     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)                        \
899     {                                                                                      \
900         TS_MAYBE_LOG(name)                                                                 \
901         CallbackInfo info(env, cbinfo);                                                    \
902         P0 p0 = getArgument<P0>(info, 0);                                                  \
903         P1 p1 = getArgument<P1>(info, 1);                                                  \
904         P2 p2 = getArgument<P2>(info, 2);                                                  \
905         P3 p3 = getArgument<P3>(info, 3);                                                  \
906         P4 p4 = getArgument<P4>(info, 4);                                                  \
907         P5 p5 = getArgument<P5>(info, 5);                                                  \
908         P6 p6 = getArgument<P6>(info, 6);                                                  \
909         P7 p7 = getArgument<P7>(info, 7);                                                  \
910         P8 p8 = getArgument<P8>(info, 8);                                                  \
911         P9 p9 = getArgument<P9>(info, 9);                                                  \
912         /* CC-OFFNXT(G.PRE.05) function gen */                                             \
913         return makeResult<Ret>(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)); \
914     }                                                                                      \
915     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
916 
917 // CC-OFFNXT(G.PRE.06) solid logic
918 #define TS_INTEROP_11(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)                   \
919     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)                             \
920     {                                                                                           \
921         TS_MAYBE_LOG(name)                                                                      \
922         CallbackInfo info(env, cbinfo);                                                         \
923         P0 p0 = getArgument<P0>(info, 0);                                                       \
924         P1 p1 = getArgument<P1>(info, 1);                                                       \
925         P2 p2 = getArgument<P2>(info, 2);                                                       \
926         P3 p3 = getArgument<P3>(info, 3);                                                       \
927         P4 p4 = getArgument<P4>(info, 4);                                                       \
928         P5 p5 = getArgument<P5>(info, 5);                                                       \
929         P6 p6 = getArgument<P6>(info, 6);                                                       \
930         P7 p7 = getArgument<P7>(info, 7);                                                       \
931         P8 p8 = getArgument<P8>(info, 8);                                                       \
932         P9 p9 = getArgument<P9>(info, 9);                                                       \
933         P10 p10 = getArgument<P10>(info, 10);                                                   \
934         /* CC-OFFNXT(G.PRE.05) function gen */                                                  \
935         return makeResult<Ret>(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); \
936     }                                                                                           \
937     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
938 
939 // CC-OFFNXT(G.PRE.06) solid logic
940 #define TS_INTEROP_12(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11)                   \
941     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)                                  \
942     {                                                                                                \
943         TS_MAYBE_LOG(name)                                                                           \
944         CallbackInfo info(env, cbinfo);                                                              \
945         P0 p0 = getArgument<P0>(info, 0);                                                            \
946         P1 p1 = getArgument<P1>(info, 1);                                                            \
947         P2 p2 = getArgument<P2>(info, 2);                                                            \
948         P3 p3 = getArgument<P3>(info, 3);                                                            \
949         P4 p4 = getArgument<P4>(info, 4);                                                            \
950         P5 p5 = getArgument<P5>(info, 5);                                                            \
951         P6 p6 = getArgument<P6>(info, 6);                                                            \
952         P7 p7 = getArgument<P7>(info, 7);                                                            \
953         P8 p8 = getArgument<P8>(info, 8);                                                            \
954         P9 p9 = getArgument<P9>(info, 9);                                                            \
955         P10 p10 = getArgument<P10>(info, 10);                                                        \
956         P11 p11 = getArgument<P11>(info, 11);                                                        \
957         /* CC-OFFNXT(G.PRE.05) function gen */                                                       \
958         return makeResult<Ret>(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)); \
959     }                                                                                                \
960     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
961 
962 // CC-OFFNXT(G.PRE.06) solid logic
963 #define TS_INTEROP_13(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)                   \
964     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)                                       \
965     {                                                                                                     \
966         TS_MAYBE_LOG(name)                                                                                \
967         CallbackInfo info(env, cbinfo);                                                                   \
968         P0 p0 = getArgument<P0>(info, 0);                                                                 \
969         P1 p1 = getArgument<P1>(info, 1);                                                                 \
970         P2 p2 = getArgument<P2>(info, 2);                                                                 \
971         P3 p3 = getArgument<P3>(info, 3);                                                                 \
972         P4 p4 = getArgument<P4>(info, 4);                                                                 \
973         P5 p5 = getArgument<P5>(info, 5);                                                                 \
974         P6 p6 = getArgument<P6>(info, 6);                                                                 \
975         P7 p7 = getArgument<P7>(info, 7);                                                                 \
976         P8 p8 = getArgument<P8>(info, 8);                                                                 \
977         P9 p9 = getArgument<P9>(info, 9);                                                                 \
978         P10 p10 = getArgument<P10>(info, 10);                                                             \
979         P11 p11 = getArgument<P11>(info, 11);                                                             \
980         P12 p12 = getArgument<P12>(info, 12);                                                             \
981         /* CC-OFFNXT(G.PRE.05) function gen */                                                            \
982         return makeResult<Ret>(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)); \
983     }                                                                                                     \
984     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
985 
986 // CC-OFFNXT(G.PRE.06) solid logic
987 #define TS_INTEROP_14(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13)                   \
988     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)                                            \
989     {                                                                                                          \
990         TS_MAYBE_LOG(name)                                                                                     \
991         CallbackInfo info(env, cbinfo);                                                                        \
992         P0 p0 = getArgument<P0>(info, 0);                                                                      \
993         P1 p1 = getArgument<P1>(info, 1);                                                                      \
994         P2 p2 = getArgument<P2>(info, 2);                                                                      \
995         P3 p3 = getArgument<P3>(info, 3);                                                                      \
996         P4 p4 = getArgument<P4>(info, 4);                                                                      \
997         P5 p5 = getArgument<P5>(info, 5);                                                                      \
998         P6 p6 = getArgument<P6>(info, 6);                                                                      \
999         P7 p7 = getArgument<P7>(info, 7);                                                                      \
1000         P8 p8 = getArgument<P8>(info, 8);                                                                      \
1001         P9 p9 = getArgument<P9>(info, 9);                                                                      \
1002         P10 p10 = getArgument<P10>(info, 10);                                                                  \
1003         P11 p11 = getArgument<P11>(info, 11);                                                                  \
1004         P12 p12 = getArgument<P12>(info, 12);                                                                  \
1005         P13 p13 = getArgument<P13>(info, 13);                                                                  \
1006         /* CC-OFFNXT(G.PRE.05) function gen */                                                                 \
1007         return makeResult<Ret>(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)); \
1008     }                                                                                                          \
1009     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1010 
1011 #define TS_INTEROP_V0(name)                                         \
1012     napi_value Node_##name(napi_env env, napi_callback_info cbinfo) \
1013     {                                                               \
1014         TS_MAYBE_LOG(name)                                          \
1015         CallbackInfo info(env, cbinfo);                             \
1016         impl_##name();                                              \
1017         /* CC-OFFNXT(G.PRE.05) function gen */                      \
1018         return makeVoid(info);                                      \
1019     }                                                               \
1020     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1021 
1022 #define TS_INTEROP_V1(name, P0)                                     \
1023     napi_value Node_##name(napi_env env, napi_callback_info cbinfo) \
1024     {                                                               \
1025         TS_MAYBE_LOG(name)                                          \
1026         CallbackInfo info(env, cbinfo);                             \
1027         P0 p0 = getArgument<P0>(info, 0);                           \
1028         impl_##name(p0);                                            \
1029         /* CC-OFFNXT(G.PRE.05) function gen */                      \
1030         return makeVoid(info);                                      \
1031     }                                                               \
1032     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1033 
1034 // CC-OFFNXT(G.PRE.06) solid logic
1035 #define TS_INTEROP_V2(name, P0, P1)                                 \
1036     napi_value Node_##name(napi_env env, napi_callback_info cbinfo) \
1037     {                                                               \
1038         TS_MAYBE_LOG(name)                                          \
1039         CallbackInfo info(env, cbinfo);                             \
1040         P0 p0 = getArgument<P0>(info, 0);                           \
1041         P1 p1 = getArgument<P1>(info, 1);                           \
1042         impl_##name(p0, p1);                                        \
1043         /* CC-OFFNXT(G.PRE.05) function gen */                      \
1044         return makeVoid(info);                                      \
1045     }                                                               \
1046     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1047 
1048 // CC-OFFNXT(G.PRE.06) solid logic
1049 #define TS_INTEROP_V3(name, P0, P1, P2)                             \
1050     napi_value Node_##name(napi_env env, napi_callback_info cbinfo) \
1051     {                                                               \
1052         TS_MAYBE_LOG(name)                                          \
1053         CallbackInfo info(env, cbinfo);                             \
1054         P0 p0 = getArgument<P0>(info, 0);                           \
1055         P1 p1 = getArgument<P1>(info, 1);                           \
1056         P2 p2 = getArgument<P2>(info, 2);                           \
1057         impl_##name(p0, p1, p2);                                    \
1058         /* CC-OFFNXT(G.PRE.05) function gen */                      \
1059         return makeVoid(info);                                      \
1060     }                                                               \
1061     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1062 
1063 // CC-OFFNXT(G.PRE.06) solid logic
1064 #define TS_INTEROP_V4(name, P0, P1, P2, P3)                         \
1065     napi_value Node_##name(napi_env env, napi_callback_info cbinfo) \
1066     {                                                               \
1067         TS_MAYBE_LOG(name)                                          \
1068         CallbackInfo info(env, cbinfo);                             \
1069         P0 p0 = getArgument<P0>(info, 0);                           \
1070         P1 p1 = getArgument<P1>(info, 1);                           \
1071         P2 p2 = getArgument<P2>(info, 2);                           \
1072         P3 p3 = getArgument<P3>(info, 3);                           \
1073         impl_##name(p0, p1, p2, p3);                                \
1074         /* CC-OFFNXT(G.PRE.05) function gen */                      \
1075         return makeVoid(info);                                      \
1076     }                                                               \
1077     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1078 
1079 // CC-OFFNXT(G.PRE.06) solid logic
1080 #define TS_INTEROP_V5(name, P0, P1, P2, P3, P4)                     \
1081     napi_value Node_##name(napi_env env, napi_callback_info cbinfo) \
1082     {                                                               \
1083         TS_MAYBE_LOG(name)                                          \
1084         CallbackInfo info(env, cbinfo);                             \
1085         P0 p0 = getArgument<P0>(info, 0);                           \
1086         P1 p1 = getArgument<P1>(info, 1);                           \
1087         P2 p2 = getArgument<P2>(info, 2);                           \
1088         P3 p3 = getArgument<P3>(info, 3);                           \
1089         P4 p4 = getArgument<P4>(info, 4);                           \
1090         impl_##name(p0, p1, p2, p3, p4);                            \
1091         /* CC-OFFNXT(G.PRE.05) function gen */                      \
1092         return makeVoid(info);                                      \
1093     }                                                               \
1094     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1095 
1096 // CC-OFFNXT(G.PRE.06) solid logic
1097 #define TS_INTEROP_V6(name, P0, P1, P2, P3, P4, P5)                 \
1098     napi_value Node_##name(napi_env env, napi_callback_info cbinfo) \
1099     {                                                               \
1100         TS_MAYBE_LOG(name)                                          \
1101         CallbackInfo info(env, cbinfo);                             \
1102         P0 p0 = getArgument<P0>(info, 0);                           \
1103         P1 p1 = getArgument<P1>(info, 1);                           \
1104         P2 p2 = getArgument<P2>(info, 2);                           \
1105         P3 p3 = getArgument<P3>(info, 3);                           \
1106         P4 p4 = getArgument<P4>(info, 4);                           \
1107         P5 p5 = getArgument<P5>(info, 5);                           \
1108         impl_##name(p0, p1, p2, p3, p4, p5);                        \
1109         /* CC-OFFNXT(G.PRE.05) function gen */                      \
1110         return makeVoid(info);                                      \
1111     }                                                               \
1112     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1113 
1114 // CC-OFFNXT(G.PRE.06) solid logic
1115 #define TS_INTEROP_V7(name, P0, P1, P2, P3, P4, P5, P6)             \
1116     napi_value Node_##name(napi_env env, napi_callback_info cbinfo) \
1117     {                                                               \
1118         TS_MAYBE_LOG(name)                                          \
1119         CallbackInfo info(env, cbinfo);                             \
1120         P0 p0 = getArgument<P0>(info, 0);                           \
1121         P1 p1 = getArgument<P1>(info, 1);                           \
1122         P2 p2 = getArgument<P2>(info, 2);                           \
1123         P3 p3 = getArgument<P3>(info, 3);                           \
1124         P4 p4 = getArgument<P4>(info, 4);                           \
1125         P5 p5 = getArgument<P5>(info, 5);                           \
1126         P6 p6 = getArgument<P6>(info, 6);                           \
1127         impl_##name(p0, p1, p2, p3, p4, p5, p6);                    \
1128         /* CC-OFFNXT(G.PRE.05) function gen */                      \
1129         return makeVoid(info);                                      \
1130     }                                                               \
1131     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1132 
1133 // CC-OFFNXT(G.PRE.06) solid logic
1134 #define TS_INTEROP_V8(name, P0, P1, P2, P3, P4, P5, P6, P7)         \
1135     napi_value Node_##name(napi_env env, napi_callback_info cbinfo) \
1136     {                                                               \
1137         TS_MAYBE_LOG(name)                                          \
1138         CallbackInfo info(env, cbinfo);                             \
1139         P0 p0 = getArgument<P0>(info, 0);                           \
1140         P1 p1 = getArgument<P1>(info, 1);                           \
1141         P2 p2 = getArgument<P2>(info, 2);                           \
1142         P3 p3 = getArgument<P3>(info, 3);                           \
1143         P4 p4 = getArgument<P4>(info, 4);                           \
1144         P5 p5 = getArgument<P5>(info, 5);                           \
1145         P6 p6 = getArgument<P6>(info, 6);                           \
1146         P7 p7 = getArgument<P7>(info, 7);                           \
1147         impl_##name(p0, p1, p2, p3, p4, p5, p6, p7);                \
1148         /* CC-OFFNXT(G.PRE.05) function gen */                      \
1149         return makeVoid(info);                                      \
1150     }                                                               \
1151     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1152 
1153 // CC-OFFNXT(G.PRE.06) solid logic
1154 #define TS_INTEROP_V9(name, P0, P1, P2, P3, P4, P5, P6, P7, P8)     \
1155     napi_value Node_##name(napi_env env, napi_callback_info cbinfo) \
1156     {                                                               \
1157         TS_MAYBE_LOG(impl_##name)                                   \
1158         CallbackInfo info(env, cbinfo);                             \
1159         P0 p0 = getArgument<P0>(info, 0);                           \
1160         P1 p1 = getArgument<P1>(info, 1);                           \
1161         P2 p2 = getArgument<P2>(info, 2);                           \
1162         P3 p3 = getArgument<P3>(info, 3);                           \
1163         P4 p4 = getArgument<P4>(info, 4);                           \
1164         P5 p5 = getArgument<P5>(info, 5);                           \
1165         P6 p6 = getArgument<P6>(info, 6);                           \
1166         P7 p7 = getArgument<P7>(info, 7);                           \
1167         P8 p8 = getArgument<P8>(info, 8);                           \
1168         impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8);            \
1169         /* CC-OFFNXT(G.PRE.05) function gen */                      \
1170         return makeVoid(info);                                      \
1171     }                                                               \
1172     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1173 
1174 // CC-OFFNXT(G.PRE.06) solid logic
1175 #define TS_INTEROP_V10(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) \
1176     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)  \
1177     {                                                                \
1178         TS_MAYBE_LOG(name)                                           \
1179         CallbackInfo info(env, cbinfo);                              \
1180         P0 p0 = getArgument<P0>(info, 0);                            \
1181         P1 p1 = getArgument<P1>(info, 1);                            \
1182         P2 p2 = getArgument<P2>(info, 2);                            \
1183         P3 p3 = getArgument<P3>(info, 3);                            \
1184         P4 p4 = getArgument<P4>(info, 4);                            \
1185         P5 p5 = getArgument<P5>(info, 5);                            \
1186         P6 p6 = getArgument<P6>(info, 6);                            \
1187         P7 p7 = getArgument<P7>(info, 7);                            \
1188         P8 p8 = getArgument<P8>(info, 8);                            \
1189         P9 p9 = getArgument<P9>(info, 9);                            \
1190         impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);         \
1191         /* CC-OFFNXT(G.PRE.05) function gen */                       \
1192         return makeVoid(info);                                       \
1193     }                                                                \
1194     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1195 
1196 // CC-OFFNXT(G.PRE.06) solid logic
1197 #define TS_INTEROP_V11(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) \
1198     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)       \
1199     {                                                                     \
1200         TS_MAYBE_LOG(impl_##name)                                         \
1201         CallbackInfo info(env, cbinfo);                                   \
1202         P0 p0 = getArgument<P0>(info, 0);                                 \
1203         P1 p1 = getArgument<P1>(info, 1);                                 \
1204         P2 p2 = getArgument<P2>(info, 2);                                 \
1205         P3 p3 = getArgument<P3>(info, 3);                                 \
1206         P4 p4 = getArgument<P4>(info, 4);                                 \
1207         P5 p5 = getArgument<P5>(info, 5);                                 \
1208         P6 p6 = getArgument<P6>(info, 6);                                 \
1209         P7 p7 = getArgument<P7>(info, 7);                                 \
1210         P8 p8 = getArgument<P8>(info, 8);                                 \
1211         P9 p9 = getArgument<P9>(info, 9);                                 \
1212         P10 p10 = getArgument<P10>(info, 10);                             \
1213         impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);         \
1214         /* CC-OFFNXT(G.PRE.05) function gen */                            \
1215         return makeVoid(info);                                            \
1216     }                                                                     \
1217     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1218 
1219 // CC-OFFNXT(G.PRE.06) solid logic
1220 #define TS_INTEROP_V12(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) \
1221     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)            \
1222     {                                                                          \
1223         TS_MAYBE_LOG(impl_##name)                                              \
1224         CallbackInfo info(env, cbinfo);                                        \
1225         P0 p0 = getArgument<P0>(info, 0);                                      \
1226         P1 p1 = getArgument<P1>(info, 1);                                      \
1227         P2 p2 = getArgument<P2>(info, 2);                                      \
1228         P3 p3 = getArgument<P3>(info, 3);                                      \
1229         P4 p4 = getArgument<P4>(info, 4);                                      \
1230         P5 p5 = getArgument<P5>(info, 5);                                      \
1231         P6 p6 = getArgument<P6>(info, 6);                                      \
1232         P7 p7 = getArgument<P7>(info, 7);                                      \
1233         P8 p8 = getArgument<P8>(info, 8);                                      \
1234         P9 p9 = getArgument<P9>(info, 9);                                      \
1235         P10 p10 = getArgument<P10>(info, 10);                                  \
1236         P11 p11 = getArgument<P11>(info, 11);                                  \
1237         impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);         \
1238         /* CC-OFFNXT(G.PRE.05) function gen */                                 \
1239         return makeVoid(info);                                                 \
1240     }                                                                          \
1241     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1242 
1243 // CC-OFFNXT(G.PRE.06) solid logic
1244 #define TS_INTEROP_V13(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) \
1245     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)                 \
1246     {                                                                               \
1247         TS_MAYBE_LOG(impl_##name)                                                   \
1248         CallbackInfo info(env, cbinfo);                                             \
1249         P0 p0 = getArgument<P0>(info, 0);                                           \
1250         P1 p1 = getArgument<P1>(info, 1);                                           \
1251         P2 p2 = getArgument<P2>(info, 2);                                           \
1252         P3 p3 = getArgument<P3>(info, 3);                                           \
1253         P4 p4 = getArgument<P4>(info, 4);                                           \
1254         P5 p5 = getArgument<P5>(info, 5);                                           \
1255         P6 p6 = getArgument<P6>(info, 6);                                           \
1256         P7 p7 = getArgument<P7>(info, 7);                                           \
1257         P8 p8 = getArgument<P8>(info, 8);                                           \
1258         P9 p9 = getArgument<P9>(info, 9);                                           \
1259         P10 p10 = getArgument<P10>(info, 10);                                       \
1260         P11 p11 = getArgument<P11>(info, 11);                                       \
1261         P12 p12 = getArgument<P12>(info, 12);                                       \
1262         impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);         \
1263         /* CC-OFFNXT(G.PRE.05) function gen */                                      \
1264         return makeVoid(info);                                                      \
1265     }                                                                               \
1266     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1267 
1268 // CC-OFFNXT(G.PRE.06) solid logic
1269 #define TS_INTEROP_V14(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) \
1270     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)                      \
1271     {                                                                                    \
1272         TS_MAYBE_LOG(name)                                                               \
1273         CallbackInfo info(env, cbinfo);                                                  \
1274         P0 p0 = getArgument<P0>(info, 0);                                                \
1275         P1 p1 = getArgument<P1>(info, 1);                                                \
1276         P2 p2 = getArgument<P2>(info, 2);                                                \
1277         P3 p3 = getArgument<P3>(info, 3);                                                \
1278         P4 p4 = getArgument<P4>(info, 4);                                                \
1279         P5 p5 = getArgument<P5>(info, 5);                                                \
1280         P6 p6 = getArgument<P6>(info, 6);                                                \
1281         P7 p7 = getArgument<P7>(info, 7);                                                \
1282         P8 p8 = getArgument<P8>(info, 8);                                                \
1283         P9 p9 = getArgument<P9>(info, 9);                                                \
1284         P10 p10 = getArgument<P10>(info, 10);                                            \
1285         P11 p11 = getArgument<P11>(info, 11);                                            \
1286         P12 p12 = getArgument<P12>(info, 12);                                            \
1287         P13 p13 = getArgument<P13>(info, 13);                                            \
1288         impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13);         \
1289         /* CC-OFFNXT(G.PRE.05) function gen */                                           \
1290         return makeVoid(info);                                                           \
1291     }                                                                                    \
1292     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1293 
1294 // CC-OFFNXT(G.PRE.06) solid logic
1295 #define TS_INTEROP_V15(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) \
1296     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)                           \
1297     {                                                                                         \
1298         TS_MAYBE_LOG(name)                                                                    \
1299         CallbackInfo info(env, cbinfo);                                                       \
1300         P0 p0 = getArgument<P0>(info, 0);                                                     \
1301         P1 p1 = getArgument<P1>(info, 1);                                                     \
1302         P2 p2 = getArgument<P2>(info, 2);                                                     \
1303         P3 p3 = getArgument<P3>(info, 3);                                                     \
1304         P4 p4 = getArgument<P4>(info, 4);                                                     \
1305         P5 p5 = getArgument<P5>(info, 5);                                                     \
1306         P6 p6 = getArgument<P6>(info, 6);                                                     \
1307         P7 p7 = getArgument<P7>(info, 7);                                                     \
1308         P8 p8 = getArgument<P8>(info, 8);                                                     \
1309         P9 p9 = getArgument<P9>(info, 9);                                                     \
1310         P10 p10 = getArgument<P10>(info, 10);                                                 \
1311         P11 p11 = getArgument<P11>(info, 11);                                                 \
1312         P12 p12 = getArgument<P12>(info, 12);                                                 \
1313         P13 p13 = getArgument<P13>(info, 13);                                                 \
1314         P14 p14 = getArgument<P14>(info, 14);                                                 \
1315         impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14);         \
1316         /* CC-OFFNXT(G.PRE.05) function gen */                                                \
1317         return makeVoid(info);                                                                \
1318     }                                                                                         \
1319     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1320 
1321 // CC-OFFNXT(G.PRE.06) solid logic
1322 #define TS_INTEROP_CTX_0(name, Ret)                                          \
1323     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)          \
1324     {                                                                        \
1325         TS_MAYBE_LOG(impl_##name)                                            \
1326         CallbackInfo info(env, cbinfo);                                      \
1327         KVMContext ctx = reinterpret_cast<KVMContext>((napi_env)info.Env()); \
1328         /* CC-OFFNXT(G.PRE.05) function gen */                               \
1329         return makeResult<Ret>(info, impl_##name(ctx));                      \
1330     }                                                                        \
1331     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1332 
1333 // CC-OFFNXT(G.PRE.06) solid logic
1334 #define TS_INTEROP_CTX_1(name, Ret, P0)                                      \
1335     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)          \
1336     {                                                                        \
1337         TS_MAYBE_LOG(impl_##name)                                            \
1338         CallbackInfo info(env, cbinfo);                                      \
1339         KVMContext ctx = reinterpret_cast<KVMContext>((napi_env)info.Env()); \
1340         P0 p0 = getArgument<P0>(info, 0);                                    \
1341         /* CC-OFFNXT(G.PRE.05) function gen */                               \
1342         return makeResult<Ret>(info, impl_##name(ctx, p0));                  \
1343     }                                                                        \
1344     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1345 
1346 // CC-OFFNXT(G.PRE.06) solid logic
1347 #define TS_INTEROP_CTX_2(name, Ret, P0, P1)                                  \
1348     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)          \
1349     {                                                                        \
1350         TS_MAYBE_LOG(name)                                                   \
1351         CallbackInfo info(env, cbinfo);                                      \
1352         KVMContext ctx = reinterpret_cast<KVMContext>((napi_env)info.Env()); \
1353         P0 p0 = getArgument<P0>(info, 0);                                    \
1354         P1 p1 = getArgument<P1>(info, 1);                                    \
1355         /* CC-OFFNXT(G.PRE.05) function gen */                               \
1356         return makeResult<Ret>(info, impl_##name(ctx, p0, p1));              \
1357     }                                                                        \
1358     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1359 
1360 // CC-OFFNXT(G.PRE.06) solid logic
1361 #define TS_INTEROP_CTX_3(name, Ret, P0, P1, P2)                              \
1362     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)          \
1363     {                                                                        \
1364         TS_MAYBE_LOG(name)                                                   \
1365         CallbackInfo info(env, cbinfo);                                      \
1366         KVMContext ctx = reinterpret_cast<KVMContext>((napi_env)info.Env()); \
1367         P0 p0 = getArgument<P0>(info, 0);                                    \
1368         P1 p1 = getArgument<P1>(info, 1);                                    \
1369         P2 p2 = getArgument<P2>(info, 2);                                    \
1370         /* CC-OFFNXT(G.PRE.05) function gen */                               \
1371         return makeResult<Ret>(info, impl_##name(ctx, p0, p1, p2));          \
1372     }                                                                        \
1373     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1374 
1375 // CC-OFFNXT(G.PRE.06) solid logic
1376 #define TS_INTEROP_CTX_4(name, Ret, P0, P1, P2, P3)                          \
1377     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)          \
1378     {                                                                        \
1379         TS_MAYBE_LOG(name)                                                   \
1380         CallbackInfo info(env, cbinfo);                                      \
1381         KVMContext ctx = reinterpret_cast<KVMContext>((napi_env)info.Env()); \
1382         P0 p0 = getArgument<P0>(info, 0);                                    \
1383         P1 p1 = getArgument<P1>(info, 1);                                    \
1384         P2 p2 = getArgument<P2>(info, 2);                                    \
1385         P3 p3 = getArgument<P3>(info, 3);                                    \
1386         /* CC-OFFNXT(G.PRE.05) function gen */                               \
1387         return makeResult<Ret>(info, impl_##name(ctx, p0, p1, p2, p3));      \
1388     }                                                                        \
1389     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1390 
1391 // CC-OFFNXT(G.PRE.06) solid logic
1392 #define TS_INTEROP_CTX_V0(name)                                              \
1393     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)          \
1394     {                                                                        \
1395         TS_MAYBE_LOG(name)                                                   \
1396         CallbackInfo info(env, cbinfo);                                      \
1397         KVMContext ctx = reinterpret_cast<KVMContext>((napi_env)info.Env()); \
1398         impl_##name(ctx);                                                    \
1399         /* CC-OFFNXT(G.PRE.05) function gen */                               \
1400         return makeVoid(info);                                               \
1401     }                                                                        \
1402     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1403 
1404 // CC-OFFNXT(G.PRE.06) solid logic
1405 #define TS_INTEROP_CTX_V1(name, P0)                                          \
1406     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)          \
1407     {                                                                        \
1408         TS_MAYBE_LOG(name)                                                   \
1409         CallbackInfo info(env, cbinfo);                                      \
1410         KVMContext ctx = reinterpret_cast<KVMContext>((napi_env)info.Env()); \
1411         P0 p0 = getArgument<P0>(info, 0);                                    \
1412         impl_##name(ctx, p0);                                                \
1413         /* CC-OFFNXT(G.PRE.05) function gen */                               \
1414         return makeVoid(info);                                               \
1415     }                                                                        \
1416     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1417 
1418 // CC-OFFNXT(G.PRE.06) solid logic
1419 #define TS_INTEROP_CTX_V2(name, P0, P1)                                      \
1420     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)          \
1421     {                                                                        \
1422         TS_MAYBE_LOG(name)                                                   \
1423         CallbackInfo info(env, cbinfo);                                      \
1424         KVMContext ctx = reinterpret_cast<KVMContext>((napi_env)info.Env()); \
1425         P0 p0 = getArgument<P0>(info, 0);                                    \
1426         P1 p1 = getArgument<P1>(info, 1);                                    \
1427         impl_##name(ctx, p0, p1);                                            \
1428         /* CC-OFFNXT(G.PRE.05) function gen */                               \
1429         return makeVoid(info);                                               \
1430     }                                                                        \
1431     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1432 
1433 // CC-OFFNXT(G.PRE.06) solid logic
1434 #define TS_INTEROP_CTX_V3(name, P0, P1, P2)                                  \
1435     napi_value Node_##name(napi_env env, napi_callback_info cbinfo)          \
1436     {                                                                        \
1437         TS_MAYBE_LOG(name)                                                   \
1438         CallbackInfo info(env, cbinfo);                                      \
1439         KVMContext ctx = reinterpret_cast<KVMContext>((napi_env)info.Env()); \
1440         P0 p0 = getArgument<P0>(info, 0);                                    \
1441         P1 p1 = getArgument<P1>(info, 1);                                    \
1442         P2 p2 = getArgument<P2>(info, 2);                                    \
1443         impl_##name(ctx, p0, p1, p2);                                        \
1444         /* CC-OFFNXT(G.PRE.05) function gen */                               \
1445         return makeVoid(info);                                               \
1446     }                                                                        \
1447     MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name)
1448 
1449 // CC-OFFNXT(G.PRE.06) solid logic
1450 #define NODEJS_GET_AND_THROW_LAST_ERROR(env)                                                           \
1451     do {                                                                                               \
1452         const napi_extended_error_info *error_info;                                                    \
1453         napi_get_last_error_info((env), &error_info);                                                  \
1454         bool is_pending;                                                                               \
1455         napi_is_exception_pending((env), &is_pending);                                                 \
1456         /* If an exception is already pending, don't rethrow it */                                     \
1457         if (!is_pending) {                                                                             \
1458             const char *error_message =                                                                \
1459                 error_info->error_message != NULL ? error_info->error_message : "empty error message"; \
1460             napi_throw_error((env), NULL, error_message);                                              \
1461         }                                                                                              \
1462     } while (0)
1463 
1464 napi_value getKoalaNapiCallbackDispatcher(napi_env env);
1465 
1466 // CC-OFFNXT(G.PRE.06) solid logic
1467 #define TS_INTEROP_CALL_VOID(venv, id, length, args)                                                     \
1468     {                                                                                                    \
1469         napi_env env = reinterpret_cast<napi_env>(venv);                                                 \
1470         napi_value bridge = getKoalaNapiCallbackDispatcher(env), global = nullptr, return_val = nullptr; \
1471         napi_handle_scope scope = nullptr;                                                               \
1472         napi_open_handle_scope(env, &scope);                                                             \
1473         napi_status status = napi_get_global(env, &global);                                              \
1474         napi_value node_args[3];                                                                         \
1475         napi_create_int32(env, id, &node_args[0]);                                                       \
1476         napi_value buffer = nullptr;                                                                     \
1477         napi_create_external_arraybuffer(                                                                \
1478             env, args, length, [](napi_env, void *data, void *hint) {}, nullptr, &buffer);               \
1479         napi_create_typedarray(env, napi_uint8_array, length, buffer, 0, &node_args[1]);                 \
1480         napi_create_int32(env, length, &node_args[2]);                                                   \
1481         status = napi_call_function(env, global, bridge, 3, node_args, &return_val);                     \
1482         if (status != napi_ok)                                                                           \
1483             NODEJS_GET_AND_THROW_LAST_ERROR((env));                                                      \
1484         napi_close_handle_scope(env, scope);                                                             \
1485     }
1486 
1487 // CC-OFFNXT(G.PRE.06) solid logic
1488 #define TS_INTEROP_CALL_INT(venv, id, length, args)                                                                \
1489     {                                                                                                              \
1490         napi_env env = reinterpret_cast<napi_env>(venv);                                                           \
1491         napi_value bridge = getKoalaNapiCallbackDispatcher(env), global = nullptr, return_val = nullptr;           \
1492         napi_handle_scope scope = nullptr;                                                                         \
1493         napi_open_handle_scope(env, &scope);                                                                       \
1494         napi_status status = napi_get_global(env, &global);                                                        \
1495         napi_value node_args[3];                                                                                   \
1496         napi_create_int32(env, id, &node_args[0]);                                                                 \
1497         napi_value buffer = nullptr;                                                                               \
1498         napi_create_external_arraybuffer(                                                                          \
1499             env, args, length, [](napi_env, [[maybe_unused]] void *data, [[maybe_unused]] void *hint) {}, nullptr, \
1500             &buffer);                                                                                              \
1501         napi_create_typedarray(env, napi_uint8_array, length, buffer, 0, &node_args[1]);                           \
1502         napi_create_int32(env, length, &node_args[2]);                                                             \
1503         status = napi_call_function(env, global, bridge, 3, node_args, &return_val);                               \
1504         if (status != napi_ok)                                                                                     \
1505             NODEJS_GET_AND_THROW_LAST_ERROR((env));                                                                \
1506         int result;                                                                                                \
1507         status = napi_get_value_int32(env, return_val, &result);                                                   \
1508         napi_close_handle_scope(env, scope);                                                                       \
1509         /* CC-OFFNXT(G.PRE.05) function gen */                                                                     \
1510         return result;                                                                                             \
1511     }
1512 
1513 #define TS_INTEROP_CALL_VOID_INTS32(venv, id, argc, args) TS_INTEROP_CALL_VOID(venv, id, (argc) * sizeof(int32_t), args)
1514 #define TS_INTEROP_CALL_INT_INTS32(venv, id, argc, args) TS_INTEROP_CALL_INT(venv, id, (argc) * sizeof(int32_t), args)
1515 
1516 // NOLINTEND
1517 
1518 #endif  // CONVERTORS_NAPI_H_
1519