koffi 2.7.3 → 2.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,13 @@
4
4
 
5
5
  ### Koffi 2.7
6
6
 
7
+ #### Koffi 2.7.4 (2024-02-04)
8
+
9
+ - Support callbacks happening on main thread but outside JS call (such as during event loop)
10
+ - Improve stability after `koffi.reset()`
11
+ - Expose internal Node/NAPI `env` pointer
12
+ - Name main Koffi API functions
13
+
7
14
  #### Koffi 2.7.3 (2024-01-26)
8
15
 
9
16
  - Support decoding NULL terminated arrays
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/index.js CHANGED
@@ -378,8 +378,8 @@ var require_package = __commonJS({
378
378
  "build/dist/src/koffi/package.json"(exports2, module2) {
379
379
  module2.exports = {
380
380
  name: "koffi",
381
- version: "2.7.3",
382
- stable: "2.7.3",
381
+ version: "2.7.4",
382
+ stable: "2.7.4",
383
383
  description: "Fast and simple C FFI (foreign function interface) for Node.js",
384
384
  keywords: [
385
385
  "foreign",
package/indirect.js CHANGED
@@ -378,8 +378,8 @@ var require_package = __commonJS({
378
378
  "build/dist/src/koffi/package.json"(exports2, module2) {
379
379
  module2.exports = {
380
380
  name: "koffi",
381
- version: "2.7.3",
382
- stable: "2.7.3",
381
+ version: "2.7.4",
382
+ stable: "2.7.4",
383
383
  description: "Fast and simple C FFI (foreign function interface) for Node.js",
384
384
  keywords: [
385
385
  "foreign",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koffi",
3
- "version": "2.7.3",
4
- "stable": "2.7.3",
3
+ "version": "2.7.4",
4
+ "stable": "2.7.4",
5
5
  "description": "Fast and simple C FFI (foreign function interface) for Node.js",
6
6
  "keywords": [
7
7
  "foreign",
@@ -30,12 +30,16 @@ function(add_node_addon)
30
30
  cmake_parse_arguments(ARG "" "NAME" "SOURCES" ${ARGN})
31
31
 
32
32
  add_library(${ARG_NAME} SHARED ${ARG_SOURCES} ${NODE_JS_SOURCES})
33
+ target_link_node(${ARG_NAME})
33
34
  set_target_properties(${ARG_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
34
- target_include_directories(${ARG_NAME} PRIVATE ${NODE_JS_INCLUDE_DIRS})
35
- target_link_libraries(${ARG_NAME} PRIVATE ${NODE_JS_LIBRARIES})
36
- target_compile_options(${ARG_NAME} PRIVATE ${NODE_JS_COMPILE_FLAGS})
35
+ endfunction()
36
+
37
+ function(target_link_node TARGET)
38
+ target_include_directories(${TARGET} PRIVATE ${NODE_JS_INCLUDE_DIRS})
39
+ target_link_libraries(${TARGET} PRIVATE ${NODE_JS_LIBRARIES})
40
+ target_compile_options(${TARGET} PRIVATE ${NODE_JS_COMPILE_FLAGS})
37
41
  if (NODE_JS_LINK_FLAGS)
38
- target_link_options(${ARG_NAME} PRIVATE ${NODE_JS_LINK_FLAGS})
42
+ target_link_options(${TARGET} PRIVATE ${NODE_JS_LINK_FLAGS})
39
43
  endif()
40
44
  endfunction()
41
45
 
@@ -3142,10 +3142,10 @@ static inline void Log(LogLevel level, const char *ctx, const char *fmt, Args...
3142
3142
  #ifdef RG_DEBUG
3143
3143
  const char *DebugLogContext(const char *filename, int line);
3144
3144
 
3145
- #define LogDebug(...) Log(LogLevel::Debug, DebugLogContext(__FILE__, __LINE__) __VA_OPT__(,) __VA_ARGS__)
3146
- #define LogInfo(...) Log(LogLevel::Info, nullptr __VA_OPT__(,) __VA_ARGS__)
3147
- #define LogWarning(...) Log(LogLevel::Warning, DebugLogContext(__FILE__, __LINE__) __VA_OPT__(,) __VA_ARGS__)
3148
- #define LogError(...) Log(LogLevel::Error, DebugLogContext(__FILE__, __LINE__) __VA_OPT__(,) __VA_ARGS__)
3145
+ #define LogDebug(...) Log(LogLevel::Debug, DebugLogContext(__FILE__, __LINE__), __VA_ARGS__)
3146
+ #define LogInfo(...) Log(LogLevel::Info, nullptr, __VA_ARGS__)
3147
+ #define LogWarning(...) Log(LogLevel::Warning, DebugLogContext(__FILE__, __LINE__), __VA_ARGS__)
3148
+ #define LogError(...) Log(LogLevel::Error, DebugLogContext(__FILE__, __LINE__), __VA_ARGS__)
3149
3149
  #else
3150
3150
  template <typename... Args>
3151
3151
  static inline void LogDebug(Args...) {}
@@ -21,13 +21,12 @@
21
21
 
22
22
  cmake_minimum_required(VERSION 3.6)
23
23
  cmake_policy(SET CMP0091 NEW)
24
-
25
24
  project(koffi C CXX ASM)
26
25
 
27
- include(CheckCXXCompilerFlag)
28
-
29
26
  find_package(CNoke)
30
27
 
28
+ include(CheckCXXCompilerFlag)
29
+
31
30
  set(CMAKE_CXX_STANDARD 20)
32
31
  if(MSVC)
33
32
  set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded)
@@ -564,7 +564,7 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
564
564
  RG_UNREACHABLE();
565
565
  }
566
566
 
567
- void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async, BackRegisters *out_reg)
567
+ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_stack, BackRegisters *out_reg)
568
568
  {
569
569
  if (env.IsExceptionPending()) [[unlikely]]
570
570
  return;
@@ -827,11 +827,11 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
827
827
 
828
828
  // Make the call
829
829
  napi_value ret;
830
- if (async) {
831
- ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
832
- } else {
830
+ if (switch_stack) {
833
831
  ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
834
832
  [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
833
+ } else {
834
+ ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
835
835
  }
836
836
  Napi::Value value(env, ret);
837
837
 
@@ -709,7 +709,7 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
709
709
  RG_UNREACHABLE();
710
710
  }
711
711
 
712
- void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async, BackRegisters *out_reg)
712
+ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_stack, BackRegisters *out_reg)
713
713
  {
714
714
  if (env.IsExceptionPending()) [[unlikely]]
715
715
  return;
@@ -1143,11 +1143,11 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
1143
1143
 
1144
1144
  // Make the call
1145
1145
  napi_value ret;
1146
- if (async) {
1147
- ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
1148
- } else {
1146
+ if (switch_stack) {
1149
1147
  ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
1150
1148
  [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
1149
+ } else {
1150
+ ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
1151
1151
  }
1152
1152
  Napi::Value value(env, ret);
1153
1153
 
@@ -506,7 +506,7 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
506
506
  RG_UNREACHABLE();
507
507
  }
508
508
 
509
- void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async, BackRegisters *out_reg)
509
+ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_stack, BackRegisters *out_reg)
510
510
  {
511
511
  if (env.IsExceptionPending()) [[unlikely]]
512
512
  return;
@@ -740,11 +740,11 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
740
740
 
741
741
  // Make the call
742
742
  napi_value ret;
743
- if (async) {
744
- ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
745
- } else {
743
+ if (switch_stack) {
746
744
  ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
747
745
  [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
746
+ } else {
747
+ ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
748
748
  }
749
749
  Napi::Value value(env, ret);
750
750
 
@@ -541,7 +541,7 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
541
541
  RG_UNREACHABLE();
542
542
  }
543
543
 
544
- void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async, BackRegisters *out_reg)
544
+ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_stack, BackRegisters *out_reg)
545
545
  {
546
546
  if (env.IsExceptionPending()) [[unlikely]]
547
547
  return;
@@ -764,11 +764,11 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
764
764
 
765
765
  // Make the call
766
766
  napi_value ret;
767
- if (async) {
768
- ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
769
- } else {
767
+ if (switch_stack) {
770
768
  ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
771
769
  [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
770
+ } else {
771
+ ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
772
772
  }
773
773
  Napi::Value value(env, ret);
774
774
 
@@ -350,7 +350,7 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
350
350
  RG_UNREACHABLE();
351
351
  }
352
352
 
353
- void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async, BackRegisters *out_reg)
353
+ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_stack, BackRegisters *out_reg)
354
354
  {
355
355
  if (env.IsExceptionPending()) [[unlikely]]
356
356
  return;
@@ -587,11 +587,11 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
587
587
 
588
588
  // Make the call
589
589
  napi_value ret;
590
- if (async) {
591
- ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
592
- } else {
590
+ if (switch_stack) {
593
591
  ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
594
592
  [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
593
+ } else {
594
+ ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
595
595
  }
596
596
  Napi::Value value(env, ret);
597
597
 
@@ -464,7 +464,7 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
464
464
  RG_UNREACHABLE();
465
465
  }
466
466
 
467
- void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRegisters *out_reg)
467
+ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack, BackRegisters *out_reg)
468
468
  {
469
469
  if (env.IsExceptionPending()) [[unlikely]]
470
470
  return;
@@ -700,11 +700,11 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
700
700
 
701
701
  // Make the call
702
702
  napi_value ret;
703
- if (async) {
704
- ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
705
- } else {
703
+ if (switch_stack) {
706
704
  ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
707
705
  [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
706
+ } else {
707
+ ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
708
708
  }
709
709
  Napi::Value value(env, ret);
710
710
 
@@ -101,7 +101,7 @@ void CallData::Dispose()
101
101
  instance = nullptr;
102
102
  }
103
103
 
104
- void CallData::RelaySafe(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool dispose_call, BackRegisters *out_reg)
104
+ void CallData::RelaySafe(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool outside_call, BackRegisters *out_reg)
105
105
  {
106
106
  if (std::this_thread::get_id() != instance->main_thread_id) {
107
107
  // JS/V8 is single-threaded, and runs on main_thread_id. Forward the call
@@ -110,7 +110,7 @@ void CallData::RelaySafe(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool dis
110
110
  RelayContext ctx;
111
111
 
112
112
  ctx.call = this;
113
- ctx.dispose_call = dispose_call;
113
+ ctx.dispose_call = outside_call;
114
114
  ctx.idx = idx;
115
115
  ctx.own_sp = own_sp;
116
116
  ctx.caller_sp = caller_sp;
@@ -124,8 +124,8 @@ void CallData::RelaySafe(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool dis
124
124
  ctx.cv.wait(lock);
125
125
  }
126
126
  } else {
127
- RG_ASSERT(!dispose_call);
128
- Relay(idx, own_sp, caller_sp, false, out_reg);
127
+ Napi::HandleScope scope(env);
128
+ Relay(idx, own_sp, caller_sp, !outside_call, out_reg);
129
129
  }
130
130
  }
131
131
 
@@ -133,7 +133,7 @@ void CallData::RelayAsync(napi_env, napi_value, void *, void *udata)
133
133
  {
134
134
  RelayContext *ctx = (RelayContext *)udata;
135
135
 
136
- ctx->call->Relay(ctx->idx, ctx->own_sp, ctx->caller_sp, true, ctx->out_reg);
136
+ ctx->call->Relay(ctx->idx, ctx->own_sp, ctx->caller_sp, false, ctx->out_reg);
137
137
 
138
138
  if (ctx->dispose_call) {
139
139
  ctx->call->Dispose();
@@ -107,8 +107,8 @@ public:
107
107
 
108
108
  #undef INLINE_IF_UNITY
109
109
 
110
- void Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async, BackRegisters *out_reg);
111
- void RelaySafe(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool dispose_call, BackRegisters *out_reg);
110
+ void Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_stack, BackRegisters *out_reg);
111
+ void RelaySafe(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool outside_call, BackRegisters *out_reg);
112
112
  static void RelayAsync(napi_env, napi_value, void *, void *udata);
113
113
 
114
114
  void DumpForward(const FunctionInfo *func) const;
@@ -48,10 +48,6 @@
48
48
  #endif
49
49
 
50
50
  #include <napi.h>
51
- #if NODE_WANT_INTERNALS
52
- #include <env-inl.h>
53
- #include <js_native_api_v8.h>
54
- #endif
55
51
 
56
52
  namespace RG {
57
53
 
@@ -2001,6 +1997,40 @@ static Napi::Value EncodeValue(const Napi::CallbackInfo &info)
2001
1997
  return env.Undefined();
2002
1998
  }
2003
1999
 
2000
+ static Napi::Value ResetKoffi(const Napi::CallbackInfo &info)
2001
+ {
2002
+ Napi::Env env = info.Env();
2003
+ InstanceData *instance = env.GetInstanceData<InstanceData>();
2004
+
2005
+ if (instance->broker) {
2006
+ napi_release_threadsafe_function(instance->broker, napi_tsfn_abort);
2007
+ instance->broker = nullptr;
2008
+ }
2009
+
2010
+ instance->types.RemoveFrom(instance->base_types_len);
2011
+
2012
+ {
2013
+ HashSet<const void *> base_types;
2014
+ HashMap<const char *, const TypeInfo *> new_map;
2015
+
2016
+ for (const TypeInfo &type: instance->types) {
2017
+ base_types.Set(&type);
2018
+ }
2019
+
2020
+ for (const auto &bucket: instance->types_map.table) {
2021
+ if (base_types.Find(bucket.value)) {
2022
+ new_map.Set(bucket.key, bucket.value);
2023
+ }
2024
+ }
2025
+
2026
+ std::swap(instance->types_map, new_map);
2027
+ }
2028
+
2029
+ instance->callbacks.Clear();
2030
+
2031
+ return env.Undefined();
2032
+ }
2033
+
2004
2034
  void LibraryHolder::Unload()
2005
2035
  {
2006
2036
  #ifdef _WIN32
@@ -2084,11 +2114,6 @@ bool InitAsyncBroker(Napi::Env env, InstanceData *instance)
2084
2114
  return true;
2085
2115
  }
2086
2116
 
2087
- CallData *GetThreadCall()
2088
- {
2089
- return exec_call;
2090
- }
2091
-
2092
2117
  static void RegisterPrimitiveType(Napi::Env env, Napi::Object map, std::initializer_list<const char *> names,
2093
2118
  PrimitiveKind primitive, int32_t size, int16_t align, const char *ref = nullptr)
2094
2119
  {
@@ -2162,83 +2187,6 @@ static inline PrimitiveKind GetBigEndianPrimitive(PrimitiveKind kind)
2162
2187
  #endif
2163
2188
  }
2164
2189
 
2165
- static Napi::Object InitBaseTypes(Napi::Env env)
2166
- {
2167
- InstanceData *instance = env.GetInstanceData<InstanceData>();
2168
-
2169
- Napi::Object types = Napi::Object::New(env);
2170
-
2171
- RegisterPrimitiveType(env, types, {"void"}, PrimitiveKind::Void, 0, 0);
2172
- RegisterPrimitiveType(env, types, {"bool"}, PrimitiveKind::Bool, RG_SIZE(bool), alignof(bool));
2173
- RegisterPrimitiveType(env, types, {"int8_t", "int8"}, PrimitiveKind::Int8, 1, 1);
2174
- RegisterPrimitiveType(env, types, {"uint8_t", "uint8"}, PrimitiveKind::UInt8, 1, 1);
2175
- RegisterPrimitiveType(env, types, {"char"}, PrimitiveKind::Int8, 1, 1);
2176
- RegisterPrimitiveType(env, types, {"unsigned char", "uchar"}, PrimitiveKind::UInt8, 1, 1);
2177
- RegisterPrimitiveType(env, types, {"char16_t", "char16"}, PrimitiveKind::Int16, 2, 2);
2178
- RegisterPrimitiveType(env, types, {"int16_t", "int16"}, PrimitiveKind::Int16, 2, 2);
2179
- RegisterPrimitiveType(env, types, {"int16_le_t", "int16_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int16), 2, 2);
2180
- RegisterPrimitiveType(env, types, {"int16_be_t", "int16_be"}, GetBigEndianPrimitive(PrimitiveKind::Int16), 2, 2);
2181
- RegisterPrimitiveType(env, types, {"uint16_t", "uint16"}, PrimitiveKind::UInt16, 2, 2);
2182
- RegisterPrimitiveType(env, types, {"uint16_le_t", "uint16_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt16), 2, 2);
2183
- RegisterPrimitiveType(env, types, {"uint16_be_t", "uint16_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt16), 2, 2);
2184
- RegisterPrimitiveType(env, types, {"short"}, PrimitiveKind::Int16, 2, 2);
2185
- RegisterPrimitiveType(env, types, {"unsigned short", "ushort"}, PrimitiveKind::UInt16, 2, 2);
2186
- RegisterPrimitiveType(env, types, {"int32_t", "int32"}, PrimitiveKind::Int32, 4, 4);
2187
- RegisterPrimitiveType(env, types, {"int32_le_t", "int32_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int32), 4, 4);
2188
- RegisterPrimitiveType(env, types, {"int32_be_t", "int32_be"}, GetBigEndianPrimitive(PrimitiveKind::Int32), 4, 4);
2189
- RegisterPrimitiveType(env, types, {"uint32_t", "uint32"}, PrimitiveKind::UInt32, 4, 4);
2190
- RegisterPrimitiveType(env, types, {"uint32_le_t", "uint32_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt32), 4, 4);
2191
- RegisterPrimitiveType(env, types, {"uint32_be_t", "uint32_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt32), 4, 4);
2192
- RegisterPrimitiveType(env, types, {"int"}, PrimitiveKind::Int32, 4, 4);
2193
- RegisterPrimitiveType(env, types, {"unsigned int", "uint"}, PrimitiveKind::UInt32, 4, 4);
2194
- RegisterPrimitiveType(env, types, {"int64_t", "int64"}, PrimitiveKind::Int64, 8, alignof(int64_t));
2195
- RegisterPrimitiveType(env, types, {"int64_le_t", "int64_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int64), 8, alignof(int64_t));
2196
- RegisterPrimitiveType(env, types, {"int64_be_t", "int64_be"}, GetBigEndianPrimitive(PrimitiveKind::Int64), 8, alignof(int64_t));
2197
- RegisterPrimitiveType(env, types, {"uint64_t", "uint64"}, PrimitiveKind::UInt64, 8, alignof(int64_t));
2198
- RegisterPrimitiveType(env, types, {"uint64_le_t", "uint64_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt64), 8, alignof(int64_t));
2199
- RegisterPrimitiveType(env, types, {"uint64_be_t", "uint64_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt64), 8, alignof(int64_t));
2200
- RegisterPrimitiveType(env, types, {"intptr_t", "intptr"}, GetSignPrimitive(RG_SIZE(intptr_t), true), RG_SIZE(intptr_t), alignof(intptr_t));
2201
- RegisterPrimitiveType(env, types, {"uintptr_t", "uintptr"}, GetSignPrimitive(RG_SIZE(intptr_t), false), RG_SIZE(intptr_t), alignof(intptr_t));
2202
- RegisterPrimitiveType(env, types, {"size_t"}, GetSignPrimitive(RG_SIZE(size_t), false), RG_SIZE(size_t), alignof(size_t));
2203
- RegisterPrimitiveType(env, types, {"long"}, GetSignPrimitive(RG_SIZE(long), true), RG_SIZE(long), alignof(long));
2204
- RegisterPrimitiveType(env, types, {"unsigned long", "ulong"}, GetSignPrimitive(RG_SIZE(long), false), RG_SIZE(long), alignof(long));
2205
- RegisterPrimitiveType(env, types, {"long long", "longlong"}, PrimitiveKind::Int64, RG_SIZE(int64_t), alignof(int64_t));
2206
- RegisterPrimitiveType(env, types, {"unsigned long long", "ulonglong"}, PrimitiveKind::UInt64, RG_SIZE(uint64_t), alignof(uint64_t));
2207
- RegisterPrimitiveType(env, types, {"float", "float32"}, PrimitiveKind::Float32, 4, alignof(float));
2208
- RegisterPrimitiveType(env, types, {"double", "float64"}, PrimitiveKind::Float64, 8, alignof(double));
2209
- RegisterPrimitiveType(env, types, {"char *", "str", "string"}, PrimitiveKind::String, RG_SIZE(void *), alignof(void *), "char");
2210
- RegisterPrimitiveType(env, types, {"char16_t *", "char16 *", "str16", "string16"}, PrimitiveKind::String16, RG_SIZE(void *), alignof(void *), "char16_t");
2211
-
2212
- instance->void_type = instance->types_map.FindValue("void", nullptr);
2213
- instance->char_type = instance->types_map.FindValue("char", nullptr);
2214
- instance->char16_type = instance->types_map.FindValue("char16", nullptr);
2215
-
2216
- instance->active_symbol = Napi::Symbol::New(env, "active");
2217
-
2218
- types.Freeze();
2219
-
2220
- return types;
2221
- }
2222
-
2223
- static Napi::Value ResetKoffi(const Napi::CallbackInfo &info)
2224
- {
2225
- Napi::Env env = info.Env();
2226
- InstanceData *instance = env.GetInstanceData<InstanceData>();
2227
-
2228
- if (instance->broker) {
2229
- napi_release_threadsafe_function(instance->broker, napi_tsfn_abort);
2230
- instance->broker = nullptr;
2231
- }
2232
-
2233
- instance->types.Clear();
2234
- instance->types_map.Clear();
2235
- instance->callbacks.Clear();
2236
-
2237
- InitBaseTypes(env);
2238
-
2239
- return env.Undefined();
2240
- }
2241
-
2242
2190
  static InstanceData *CreateInstance()
2243
2191
  {
2244
2192
  InstanceData *instance = new InstanceData();
@@ -2267,52 +2215,52 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
2267
2215
 
2268
2216
  env.SetInstanceData(instance);
2269
2217
 
2270
- exports.Set("config", Napi::Function::New(env, GetSetConfig));
2271
- exports.Set("stats", Napi::Function::New(env, GetStats));
2218
+ exports.Set("config", Napi::Function::New(env, GetSetConfig, "config"));
2219
+ exports.Set("stats", Napi::Function::New(env, GetStats, "stats"));
2272
2220
 
2273
- exports.Set("struct", Napi::Function::New(env, CreatePaddedStructType));
2274
- exports.Set("pack", Napi::Function::New(env, CreatePackedStructType));
2275
- exports.Set("union", Napi::Function::New(env, CreateUnionType));
2276
- exports.Set("Union", Napi::Function::New(env, InstantiateUnion));
2277
- exports.Set("opaque", Napi::Function::New(env, CreateOpaqueType));
2278
- exports.Set("pointer", Napi::Function::New(env, CreatePointerType));
2279
- exports.Set("array", Napi::Function::New(env, CreateArrayType));
2280
- exports.Set("proto", Napi::Function::New(env, CreateFunctionType));
2281
- exports.Set("alias", Napi::Function::New(env, CreateTypeAlias));
2221
+ exports.Set("struct", Napi::Function::New(env, CreatePaddedStructType, "struct"));
2222
+ exports.Set("pack", Napi::Function::New(env, CreatePackedStructType, "pack"));
2223
+ exports.Set("union", Napi::Function::New(env, CreateUnionType, "union"));
2224
+ exports.Set("Union", Napi::Function::New(env, InstantiateUnion, "Union"));
2225
+ exports.Set("opaque", Napi::Function::New(env, CreateOpaqueType, "opaque"));
2226
+ exports.Set("pointer", Napi::Function::New(env, CreatePointerType, "pointer"));
2227
+ exports.Set("array", Napi::Function::New(env, CreateArrayType, "array"));
2228
+ exports.Set("proto", Napi::Function::New(env, CreateFunctionType, "proto"));
2229
+ exports.Set("alias", Napi::Function::New(env, CreateTypeAlias, "alias"));
2282
2230
 
2283
- exports.Set("sizeof", Napi::Function::New(env, GetTypeSize));
2284
- exports.Set("alignof", Napi::Function::New(env, GetTypeAlign));
2285
- exports.Set("offsetof", Napi::Function::New(env, GetMemberOffset));
2286
- exports.Set("resolve", Napi::Function::New(env, GetResolvedType));
2287
- exports.Set("introspect", Napi::Function::New(env, GetTypeDefinition));
2231
+ exports.Set("sizeof", Napi::Function::New(env, GetTypeSize, "sizeof"));
2232
+ exports.Set("alignof", Napi::Function::New(env, GetTypeAlign, "alignof"));
2233
+ exports.Set("offsetof", Napi::Function::New(env, GetMemberOffset, "offsetof"));
2234
+ exports.Set("resolve", Napi::Function::New(env, GetResolvedType, "resolve"));
2235
+ exports.Set("introspect", Napi::Function::New(env, GetTypeDefinition, "introspect"));
2288
2236
 
2289
- exports.Set("load", Napi::Function::New(env, LoadSharedLibrary));
2237
+ exports.Set("load", Napi::Function::New(env, LoadSharedLibrary, "load"));
2290
2238
 
2291
- exports.Set("in", Napi::Function::New(env, MarkIn));
2292
- exports.Set("out", Napi::Function::New(env, MarkOut));
2293
- exports.Set("inout", Napi::Function::New(env, MarkInOut));
2239
+ exports.Set("in", Napi::Function::New(env, MarkIn, "in"));
2240
+ exports.Set("out", Napi::Function::New(env, MarkOut, "out"));
2241
+ exports.Set("inout", Napi::Function::New(env, MarkInOut, "inout"));
2294
2242
 
2295
- exports.Set("disposable", Napi::Function::New(env, CreateDisposableType));
2296
- exports.Set("free", Napi::Function::New(env, CallFree));
2243
+ exports.Set("disposable", Napi::Function::New(env, CreateDisposableType, "disposable"));
2244
+ exports.Set("free", Napi::Function::New(env, CallFree, "free"));
2297
2245
 
2298
- exports.Set("register", Napi::Function::New(env, RegisterCallback));
2299
- exports.Set("unregister", Napi::Function::New(env, UnregisterCallback));
2246
+ exports.Set("register", Napi::Function::New(env, RegisterCallback, "register"));
2247
+ exports.Set("unregister", Napi::Function::New(env, UnregisterCallback, "unregister"));
2300
2248
 
2301
- exports.Set("as", Napi::Function::New(env, CastValue));
2302
- exports.Set("decode", Napi::Function::New(env, DecodeValue));
2303
- exports.Set("address", Napi::Function::New(env, GetPointerAddress));
2304
- exports.Set("call", Napi::Function::New(env, CallPointerSync));
2305
- exports.Set("encode", Napi::Function::New(env, EncodeValue));
2249
+ exports.Set("as", Napi::Function::New(env, CastValue, "as"));
2250
+ exports.Set("decode", Napi::Function::New(env, DecodeValue, "decode"));
2251
+ exports.Set("address", Napi::Function::New(env, GetPointerAddress, "address"));
2252
+ exports.Set("call", Napi::Function::New(env, CallPointerSync, "call"));
2253
+ exports.Set("encode", Napi::Function::New(env, EncodeValue, "encode"));
2306
2254
 
2307
- exports.Set("reset", Napi::Function::New(env, ResetKoffi));
2255
+ exports.Set("reset", Napi::Function::New(env, ResetKoffi, "reset"));
2308
2256
 
2309
- exports.Set("errno", Napi::Function::New(env, GetOrSetErrNo));
2257
+ exports.Set("errno", Napi::Function::New(env, GetOrSetErrNo, "errno"));
2310
2258
 
2311
- Napi::Object os = Napi::Object::New(env);
2312
- exports.Set("os", os);
2313
-
2314
- // Init constants mapping
2259
+ // Export useful OS info
2315
2260
  {
2261
+ Napi::Object os = Napi::Object::New(env);
2262
+ exports.Set("os", os);
2263
+
2316
2264
  Napi::Object codes = Napi::Object::New(env);
2317
2265
 
2318
2266
  for (const ErrnoCodeInfo &info: ErrnoCodes) {
@@ -2330,8 +2278,71 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
2330
2278
  exports.Set("extension", Napi::String::New(env, ".so"));
2331
2279
  #endif
2332
2280
 
2333
- Napi::Object types = InitBaseTypes(env);
2334
- exports.Set("types", types);
2281
+ // Init base types
2282
+ {
2283
+ Napi::Object types = Napi::Object::New(env);
2284
+ exports.Set("types", types);
2285
+
2286
+ RegisterPrimitiveType(env, types, {"void"}, PrimitiveKind::Void, 0, 0);
2287
+ RegisterPrimitiveType(env, types, {"bool"}, PrimitiveKind::Bool, RG_SIZE(bool), alignof(bool));
2288
+ RegisterPrimitiveType(env, types, {"int8_t", "int8"}, PrimitiveKind::Int8, 1, 1);
2289
+ RegisterPrimitiveType(env, types, {"uint8_t", "uint8"}, PrimitiveKind::UInt8, 1, 1);
2290
+ RegisterPrimitiveType(env, types, {"char"}, PrimitiveKind::Int8, 1, 1);
2291
+ RegisterPrimitiveType(env, types, {"unsigned char", "uchar"}, PrimitiveKind::UInt8, 1, 1);
2292
+ RegisterPrimitiveType(env, types, {"char16_t", "char16"}, PrimitiveKind::Int16, 2, 2);
2293
+ RegisterPrimitiveType(env, types, {"int16_t", "int16"}, PrimitiveKind::Int16, 2, 2);
2294
+ RegisterPrimitiveType(env, types, {"int16_le_t", "int16_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int16), 2, 2);
2295
+ RegisterPrimitiveType(env, types, {"int16_be_t", "int16_be"}, GetBigEndianPrimitive(PrimitiveKind::Int16), 2, 2);
2296
+ RegisterPrimitiveType(env, types, {"uint16_t", "uint16"}, PrimitiveKind::UInt16, 2, 2);
2297
+ RegisterPrimitiveType(env, types, {"uint16_le_t", "uint16_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt16), 2, 2);
2298
+ RegisterPrimitiveType(env, types, {"uint16_be_t", "uint16_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt16), 2, 2);
2299
+ RegisterPrimitiveType(env, types, {"short"}, PrimitiveKind::Int16, 2, 2);
2300
+ RegisterPrimitiveType(env, types, {"unsigned short", "ushort"}, PrimitiveKind::UInt16, 2, 2);
2301
+ RegisterPrimitiveType(env, types, {"int32_t", "int32"}, PrimitiveKind::Int32, 4, 4);
2302
+ RegisterPrimitiveType(env, types, {"int32_le_t", "int32_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int32), 4, 4);
2303
+ RegisterPrimitiveType(env, types, {"int32_be_t", "int32_be"}, GetBigEndianPrimitive(PrimitiveKind::Int32), 4, 4);
2304
+ RegisterPrimitiveType(env, types, {"uint32_t", "uint32"}, PrimitiveKind::UInt32, 4, 4);
2305
+ RegisterPrimitiveType(env, types, {"uint32_le_t", "uint32_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt32), 4, 4);
2306
+ RegisterPrimitiveType(env, types, {"uint32_be_t", "uint32_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt32), 4, 4);
2307
+ RegisterPrimitiveType(env, types, {"int"}, PrimitiveKind::Int32, 4, 4);
2308
+ RegisterPrimitiveType(env, types, {"unsigned int", "uint"}, PrimitiveKind::UInt32, 4, 4);
2309
+ RegisterPrimitiveType(env, types, {"int64_t", "int64"}, PrimitiveKind::Int64, 8, alignof(int64_t));
2310
+ RegisterPrimitiveType(env, types, {"int64_le_t", "int64_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int64), 8, alignof(int64_t));
2311
+ RegisterPrimitiveType(env, types, {"int64_be_t", "int64_be"}, GetBigEndianPrimitive(PrimitiveKind::Int64), 8, alignof(int64_t));
2312
+ RegisterPrimitiveType(env, types, {"uint64_t", "uint64"}, PrimitiveKind::UInt64, 8, alignof(int64_t));
2313
+ RegisterPrimitiveType(env, types, {"uint64_le_t", "uint64_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt64), 8, alignof(int64_t));
2314
+ RegisterPrimitiveType(env, types, {"uint64_be_t", "uint64_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt64), 8, alignof(int64_t));
2315
+ RegisterPrimitiveType(env, types, {"intptr_t", "intptr"}, GetSignPrimitive(RG_SIZE(intptr_t), true), RG_SIZE(intptr_t), alignof(intptr_t));
2316
+ RegisterPrimitiveType(env, types, {"uintptr_t", "uintptr"}, GetSignPrimitive(RG_SIZE(intptr_t), false), RG_SIZE(intptr_t), alignof(intptr_t));
2317
+ RegisterPrimitiveType(env, types, {"size_t"}, GetSignPrimitive(RG_SIZE(size_t), false), RG_SIZE(size_t), alignof(size_t));
2318
+ RegisterPrimitiveType(env, types, {"long"}, GetSignPrimitive(RG_SIZE(long), true), RG_SIZE(long), alignof(long));
2319
+ RegisterPrimitiveType(env, types, {"unsigned long", "ulong"}, GetSignPrimitive(RG_SIZE(long), false), RG_SIZE(long), alignof(long));
2320
+ RegisterPrimitiveType(env, types, {"long long", "longlong"}, PrimitiveKind::Int64, RG_SIZE(int64_t), alignof(int64_t));
2321
+ RegisterPrimitiveType(env, types, {"unsigned long long", "ulonglong"}, PrimitiveKind::UInt64, RG_SIZE(uint64_t), alignof(uint64_t));
2322
+ RegisterPrimitiveType(env, types, {"float", "float32"}, PrimitiveKind::Float32, 4, alignof(float));
2323
+ RegisterPrimitiveType(env, types, {"double", "float64"}, PrimitiveKind::Float64, 8, alignof(double));
2324
+ RegisterPrimitiveType(env, types, {"char *", "str", "string"}, PrimitiveKind::String, RG_SIZE(void *), alignof(void *), "char");
2325
+ RegisterPrimitiveType(env, types, {"char16_t *", "char16 *", "str16", "string16"}, PrimitiveKind::String16, RG_SIZE(void *), alignof(void *), "char16_t");
2326
+
2327
+ instance->void_type = instance->types_map.FindValue("void", nullptr);
2328
+ instance->char_type = instance->types_map.FindValue("char", nullptr);
2329
+ instance->char16_type = instance->types_map.FindValue("char16", nullptr);
2330
+
2331
+ instance->active_symbol = Napi::Symbol::New(env, "active");
2332
+
2333
+ instance->base_types_len = instance->types.len;
2334
+ }
2335
+
2336
+ // Expose internal Node stuff
2337
+ {
2338
+ Napi::Object node = Napi::Object::New(env);
2339
+ exports.Set("node", node);
2340
+
2341
+ Napi::External<void> external = Napi::External<void>::New(env, (napi_env)env);
2342
+ SetValueTag(instance, external, instance->void_type);
2343
+
2344
+ node.Set("env", external);
2345
+ }
2335
2346
 
2336
2347
  exports.Set("version", Napi::String::New(env, RG_STRINGIFY(VERSION)));
2337
2348
 
@@ -269,6 +269,7 @@ struct InstanceData {
269
269
  BucketArray<TypeInfo> types;
270
270
  HashMap<const char *, const TypeInfo *> types_map;
271
271
  BucketArray<FunctionInfo> callbacks;
272
+ Size base_types_len;
272
273
 
273
274
  bool debug;
274
275
  uint64_t tag_lower;
@@ -352,6 +353,5 @@ Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info);
352
353
  Napi::Value TranslateAsyncCall(const Napi::CallbackInfo &info);
353
354
 
354
355
  bool InitAsyncBroker(Napi::Env env, InstanceData *instance);
355
- CallData *GetThreadCall();
356
356
 
357
357
  }