koffi 3.0.1 → 3.0.2

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.
@@ -5,6 +5,7 @@
5
5
  #include "ffi.hh"
6
6
  #include "call.hh"
7
7
  #include "parser.hh"
8
+ #include "type.hh"
8
9
  #include "util.hh"
9
10
  #include "uv.hh"
10
11
  #if defined(_WIN32)
@@ -35,6 +36,13 @@
35
36
 
36
37
  namespace K {
37
38
 
39
+ // Value does not matter, the tag system uses memory addresses
40
+ const napi_type_tag LibraryHandleMarker = { 0xdb9b066e6f700474, 0x0aecd7e4c63fbda9 };
41
+ const napi_type_tag TypeObjectMarker = { 0x1cc449675b294374, 0xbb13a50e97dcb017 };
42
+ const napi_type_tag DirectionMarker = { 0xf9c306238b480580, 0xc2e168524a0823f5 };
43
+ const napi_type_tag UnionValueMarker = { 0x5eaf2245526a4c7d, 0x8c86c9ee2b96ffc8 };
44
+ const napi_type_tag CastMarker = { 0x77f459614a0a412f, 0x80b3dda1341dc8df };
45
+
38
46
  SharedData shared;
39
47
 
40
48
  // Some Node-API functions are loaded dynamically to work around bugs or because they are recent
@@ -45,13 +53,11 @@ napi_status (NAPI_CDECL *node_api_create_object_with_properties)(napi_env env, n
45
53
  const napi_value *property_values, size_t property_count, napi_value *result);
46
54
  napi_value (*translate_zero_call)(napi_env env, napi_callback_info info);
47
55
 
48
- static bool ChangeSize(const char *name, Napi::Value value, Size min_size, Size max_size, Size *out_size)
56
+ static bool ChangeSize(InstanceData *instance, const char *name, Napi::Value value, Size min_size, Size max_size, Size *out_size)
49
57
  {
50
- Napi::Env env = value.Env();
58
+ Napi::Env env = instance->env;
51
59
 
52
60
  if (!value.IsNumber()) {
53
- InstanceData *instance = env.GetInstanceData<InstanceData>();
54
-
55
61
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for '%2', expected number", GetValueType(instance, value), name);
56
62
  return false;
57
63
  }
@@ -67,21 +73,19 @@ static bool ChangeSize(const char *name, Napi::Value value, Size min_size, Size
67
73
  return true;
68
74
  }
69
75
 
70
- static bool ChangeMemorySize(const char *name, Napi::Value value, Size *out_size)
76
+ static bool ChangeMemorySize(InstanceData *instance, const char *name, Napi::Value value, Size *out_size)
71
77
  {
72
78
  const Size MinSize = Kibibytes(1);
73
79
  const Size MaxSize = Mebibytes(16);
74
80
 
75
- return ChangeSize(name, value, MinSize, MaxSize, out_size);
81
+ return ChangeSize(instance, name, value, MinSize, MaxSize, out_size);
76
82
  }
77
83
 
78
- static bool ChangeAsyncLimit(const char *name, Napi::Value value, int max, int *out_limit)
84
+ static bool ChangeAsyncLimit(InstanceData *instance, const char *name, Napi::Value value, int max, int *out_limit)
79
85
  {
80
86
  Napi::Env env = value.Env();
81
87
 
82
88
  if (!value.IsNumber()) {
83
- InstanceData *instance = env.GetInstanceData<InstanceData>();
84
-
85
89
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for '%2', expected number", GetValueType(instance, value), name);
86
90
  return false;
87
91
  }
@@ -100,7 +104,7 @@ static bool ChangeAsyncLimit(const char *name, Napi::Value value, int max, int *
100
104
  static Napi::Value GetSetConfig(const Napi::CallbackInfo &info)
101
105
  {
102
106
  Napi::Env env = info.Env();
103
- InstanceData *instance = env.GetInstanceData<InstanceData>();
107
+ InstanceData *instance = (InstanceData *)info.Data();
104
108
 
105
109
  if (info.Length()) {
106
110
  if (instance->memories.len) {
@@ -124,25 +128,25 @@ static Napi::Value GetSetConfig(const Napi::CallbackInfo &info)
124
128
  Napi::Value value = obj[key];
125
129
 
126
130
  if (key == "sync_stack_size") {
127
- if (!ChangeMemorySize(key.c_str(), value, &new_config.sync_stack_size))
131
+ if (!ChangeMemorySize(instance, key.c_str(), value, &new_config.sync_stack_size))
128
132
  return env.Null();
129
133
  } else if (key == "sync_heap_size") {
130
- if (!ChangeMemorySize(key.c_str(), value, &new_config.sync_heap_size))
134
+ if (!ChangeMemorySize(instance, key.c_str(), value, &new_config.sync_heap_size))
131
135
  return env.Null();
132
136
  } else if (key == "async_stack_size") {
133
- if (!ChangeMemorySize(key.c_str(), value, &new_config.async_stack_size))
137
+ if (!ChangeMemorySize(instance, key.c_str(), value, &new_config.async_stack_size))
134
138
  return env.Null();
135
139
  } else if (key == "async_heap_size") {
136
- if (!ChangeMemorySize(key.c_str(), value, &new_config.async_heap_size))
140
+ if (!ChangeMemorySize(instance, key.c_str(), value, &new_config.async_heap_size))
137
141
  return env.Null();
138
142
  } else if (key == "resident_async_pools") {
139
- if (!ChangeAsyncLimit(key.c_str(), value, K_LEN(instance->memories.data) - 1, &new_config.resident_async_pools))
143
+ if (!ChangeAsyncLimit(instance, key.c_str(), value, K_LEN(instance->memories.data) - 1, &new_config.resident_async_pools))
140
144
  return env.Null();
141
145
  } else if (key == "max_async_calls") {
142
- if (!ChangeAsyncLimit(key.c_str(), value, MaxAsyncCalls, &max_async_calls))
146
+ if (!ChangeAsyncLimit(instance, key.c_str(), value, MaxAsyncCalls, &max_async_calls))
143
147
  return env.Null();
144
148
  } else if (key == "max_type_size") {
145
- if (!ChangeSize(key.c_str(), value, 32, Mebibytes(512), &new_config.max_type_size))
149
+ if (!ChangeSize(instance, key.c_str(), value, 32, Mebibytes(512), &new_config.max_type_size))
146
150
  return env.Null();
147
151
  } else {
148
152
  ThrowError<Napi::Error>(env, "Unexpected config member '%1'", key.c_str());
@@ -175,7 +179,7 @@ static Napi::Value GetSetConfig(const Napi::CallbackInfo &info)
175
179
  static Napi::Value GetStats(const Napi::CallbackInfo &info)
176
180
  {
177
181
  Napi::Env env = info.Env();
178
- InstanceData *instance = env.GetInstanceData<InstanceData>();
182
+ InstanceData *instance = (InstanceData *)info.Data();
179
183
 
180
184
  Napi::Object obj = Napi::Object::New(env);
181
185
 
@@ -228,9 +232,9 @@ static bool FinalizeCompositeType(Napi::Env env, TypeInfo *type, PrimitiveKind p
228
232
  if (node_api_create_property_key_utf8) {
229
233
  for (RecordMember &member: type->members) {
230
234
  napi_value key = nullptr;
231
- node_api_create_property_key_utf8(env, member.name, NAPI_AUTO_LENGTH, &key);
232
235
 
233
- napi_create_reference(env, key, 1, &member.key);
236
+ NAPI_OK(node_api_create_property_key_utf8(env, member.name, NAPI_AUTO_LENGTH, &key));
237
+ NAPI_OK(napi_create_reference(env, key, 1, &member.key));
234
238
  }
235
239
  }
236
240
 
@@ -247,7 +251,7 @@ static bool FinalizeCompositeType(Napi::Env env, TypeInfo *type, PrimitiveKind p
247
251
  static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
248
252
  {
249
253
  Napi::Env env = info.Env();
250
- InstanceData *instance = env.GetInstanceData<InstanceData>();
254
+ InstanceData *instance = (InstanceData *)info.Data();
251
255
 
252
256
  if (info.Length() < 1) {
253
257
  ThrowError<Napi::TypeError>(env, "Expected 1 or 2 arguments, got %1", info.Length());
@@ -299,7 +303,7 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
299
303
  replace = external.Data();
300
304
  #else
301
305
  TypeObject *defn = nullptr;
302
- napi_unwrap(env, name, (void **)&defn);
306
+ NAPI_OK(napi_unwrap(env, name, (void **)&defn));
303
307
 
304
308
  replace = (TypeInfo *)defn->GetType();
305
309
  #endif
@@ -353,7 +357,7 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
353
357
  align = (int16_t)align64;
354
358
  }
355
359
 
356
- member.type = ResolveType(value);
360
+ member.type = ResolveType(instance, value);
357
361
  if (!member.type)
358
362
  return env.Null();
359
363
  if (!CanStoreType(member.type)) {
@@ -429,7 +433,8 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
429
433
  type = replace;
430
434
  }
431
435
 
432
- return WrapType(env, type);
436
+ napi_value wrapper = WrapType(env, type);
437
+ return Napi::Value(env, wrapper);
433
438
  }
434
439
 
435
440
  static Napi::Value CreatePaddedStructType(const Napi::CallbackInfo &info)
@@ -445,7 +450,7 @@ static Napi::Value CreatePackedStructType(const Napi::CallbackInfo &info)
445
450
  static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
446
451
  {
447
452
  Napi::Env env = info.Env();
448
- InstanceData *instance = env.GetInstanceData<InstanceData>();
453
+ InstanceData *instance = (InstanceData *)info.Data();
449
454
 
450
455
  if (info.Length() < 1) {
451
456
  ThrowError<Napi::TypeError>(env, "Expected 1 or 2 arguments, got %1", info.Length());
@@ -497,7 +502,7 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
497
502
  replace = external.Data();
498
503
  #else
499
504
  TypeObject *defn = nullptr;
500
- napi_unwrap(env, name, (void **)&defn);
505
+ NAPI_OK(napi_unwrap(env, name, (void **)&defn));
501
506
 
502
507
  replace = (TypeInfo *)defn->GetType();
503
508
  #endif
@@ -551,7 +556,7 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
551
556
  align = (int16_t)align64;
552
557
  }
553
558
 
554
- member.type = ResolveType(value);
559
+ member.type = ResolveType(instance, value);
555
560
  if (!member.type)
556
561
  return env.Null();
557
562
  if (!CanStoreType(member.type)) {
@@ -592,19 +597,21 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
592
597
  return env.Null();
593
598
  err_guard.Disable();
594
599
 
595
- type->construct = Napi::Persistent(UnionValue::InitClass(env, type));
600
+ type->construct = Napi::Persistent(UnionValue::InitClass(instance, type));
596
601
 
597
602
  if (replace) {
598
603
  std::swap(*type, *replace);
599
604
  type = replace;
600
605
  }
601
606
 
602
- return WrapType(env, type);
607
+ napi_value wrapper = WrapType(env, type);
608
+ return Napi::Value(env, wrapper);
603
609
  }
604
610
 
605
611
  Napi::Value InstantiateUnion(const Napi::CallbackInfo &info)
606
612
  {
607
613
  Napi::Env env = info.Env();
614
+ InstanceData *instance = (InstanceData *)info.Data();
608
615
 
609
616
  if (!info.IsConstructCall()) {
610
617
  ThrowError<Napi::TypeError>(env, "This function is a constructor and must be called with new");
@@ -615,7 +622,7 @@ Napi::Value InstantiateUnion(const Napi::CallbackInfo &info)
615
622
  return env.Null();
616
623
  }
617
624
 
618
- const TypeInfo *type = ResolveType(info[0]);
625
+ const TypeInfo *type = ResolveType(instance, info[0]);
619
626
  if (!type)
620
627
  return env.Null();
621
628
  if (type->primitive != PrimitiveKind::Union) {
@@ -632,7 +639,7 @@ Napi::Value InstantiateUnion(const Napi::CallbackInfo &info)
632
639
  static Napi::Value CreateOpaqueType(const Napi::CallbackInfo &info)
633
640
  {
634
641
  Napi::Env env = info.Env();
635
- InstanceData *instance = env.GetInstanceData<InstanceData>();
642
+ InstanceData *instance = (InstanceData *)info.Data();
636
643
 
637
644
  bool named = (info.Length() >= 1) && !IsNullOrUndefined(env, info[0]);
638
645
 
@@ -658,13 +665,14 @@ static Napi::Value CreateOpaqueType(const Napi::CallbackInfo &info)
658
665
  return env.Null();
659
666
  err_guard.Disable();
660
667
 
661
- return WrapType(env, type);
668
+ napi_value wrapper = WrapType(env, type);
669
+ return Napi::Value(env, wrapper);
662
670
  }
663
671
 
664
672
  static Napi::Value CreatePointerType(const Napi::CallbackInfo &info)
665
673
  {
666
674
  Napi::Env env = info.Env();
667
- InstanceData *instance = env.GetInstanceData<InstanceData>();
675
+ InstanceData *instance = (InstanceData *)info.Data();
668
676
 
669
677
  if (info.Length() < 1) {
670
678
  ThrowError<Napi::TypeError>(env, "Expected 1 to 3 arguments, got %1", info.Length());
@@ -681,7 +689,7 @@ static Napi::Value CreatePointerType(const Napi::CallbackInfo &info)
681
689
 
682
690
  std::string name = named ? info[0].As<Napi::String>() : std::string();
683
691
 
684
- const TypeInfo *ref = ResolveType(info[skip]);
692
+ const TypeInfo *ref = ResolveType(instance, info[skip]);
685
693
  if (!ref)
686
694
  return env.Null();
687
695
 
@@ -730,7 +738,8 @@ static Napi::Value CreatePointerType(const Napi::CallbackInfo &info)
730
738
  type = copy;
731
739
  }
732
740
 
733
- return WrapType(env, type);
741
+ napi_value wrapper = WrapType(env, type);
742
+ return Napi::Value(env, wrapper);
734
743
  }
735
744
 
736
745
  static Napi::Value EncodePointerDirection(const Napi::CallbackInfo &info, int directions)
@@ -738,13 +747,14 @@ static Napi::Value EncodePointerDirection(const Napi::CallbackInfo &info, int di
738
747
  K_ASSERT(directions >= 1 && directions <= 3);
739
748
 
740
749
  Napi::Env env = info.Env();
750
+ InstanceData *instance = (InstanceData *)info.Data();
741
751
 
742
752
  if (info.Length() < 1) {
743
753
  ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
744
754
  return env.Null();
745
755
  }
746
756
 
747
- const TypeInfo *type = ResolveType(info[0]);
757
+ const TypeInfo *type = ResolveType(instance, info[0]);
748
758
  if (!type)
749
759
  return env.Null();
750
760
 
@@ -783,7 +793,7 @@ static Napi::Value MarkInOut(const Napi::CallbackInfo &info)
783
793
  static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
784
794
  {
785
795
  Napi::Env env = info.Env();
786
- InstanceData *instance = env.GetInstanceData<InstanceData>();
796
+ InstanceData *instance = (InstanceData *)info.Data();
787
797
 
788
798
  if (info.Length() < 1) {
789
799
  ThrowError<Napi::TypeError>(env, "Expected 1 or 2 arguments, got %1", info.Length());
@@ -800,7 +810,7 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
800
810
 
801
811
  Napi::String name = info[0].As<Napi::String>();
802
812
 
803
- const TypeInfo *src = ResolveType(info[skip]);
813
+ const TypeInfo *src = ResolveType(instance, info[skip]);
804
814
  if (!src)
805
815
  return env.Null();
806
816
  if (src->primitive != PrimitiveKind::Pointer &&
@@ -829,12 +839,10 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
829
839
  InstanceData *instance = env.GetInstanceData<InstanceData>();
830
840
  const Napi::FunctionReference &ref = type->dispose_ref;
831
841
 
832
- Napi::Value p = WrapPointer(env, type->ref.type, (void *)ptr);
833
-
834
842
  napi_value self = env.Null();
835
- napi_value args[] = { p };
843
+ napi_value wrapper = WrapPointer(env, type->ref.type, (void *)ptr);
836
844
 
837
- ref.Call(self, K_LEN(args), args);
845
+ ref.Call(self, 1, &wrapper);
838
846
  instance->stats.disposed++;
839
847
  };
840
848
  dispose_func = func;
@@ -875,13 +883,14 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
875
883
  }
876
884
  err_guard.Disable();
877
885
 
878
- return WrapType(env, type);
886
+ napi_value wrapper = WrapType(env, type);
887
+ return Napi::Value(env, wrapper);
879
888
  }
880
889
 
881
890
  static Napi::Value CallAlloc(const Napi::CallbackInfo &info)
882
891
  {
883
892
  Napi::Env env = info.Env();
884
- InstanceData *instance = env.GetInstanceData<InstanceData>();
893
+ InstanceData *instance = (InstanceData *)info.Data();
885
894
 
886
895
  if (info.Length() < 2) {
887
896
  ThrowError<Napi::TypeError>(env, "Expected 2 arguments, got %1", info.Length());
@@ -892,7 +901,7 @@ static Napi::Value CallAlloc(const Napi::CallbackInfo &info)
892
901
  return env.Null();
893
902
  }
894
903
 
895
- const TypeInfo *type = ResolveType(info[0]);
904
+ const TypeInfo *type = ResolveType(instance, info[0]);
896
905
  if (!type)
897
906
  return env.Null();
898
907
 
@@ -921,12 +930,14 @@ static Napi::Value CallAlloc(const Napi::CallbackInfo &info)
921
930
  return env.Null();
922
931
  }
923
932
 
924
- return WrapPointer(env, type, ptr);
933
+ napi_value wrapper = WrapPointer(env, type, ptr);
934
+ return Napi::Value(env, wrapper);
925
935
  }
926
936
 
927
937
  static Napi::Value CallFree(const Napi::CallbackInfo &info)
928
938
  {
929
939
  Napi::Env env = info.Env();
940
+ InstanceData *instance = (InstanceData *)info.Data();
930
941
 
931
942
  if (info.Length() < 1) {
932
943
  ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
@@ -935,8 +946,6 @@ static Napi::Value CallFree(const Napi::CallbackInfo &info)
935
946
 
936
947
  void *ptr = nullptr;
937
948
  if (!TryPointer(env, info[0], &ptr)) {
938
- InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
939
-
940
949
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, info[0]));
941
950
  return env.Null();
942
951
  }
@@ -949,7 +958,7 @@ static Napi::Value CallFree(const Napi::CallbackInfo &info)
949
958
  static Napi::Value GetOrSetErrNo(const Napi::CallbackInfo &info)
950
959
  {
951
960
  Napi::Env env = info.Env();
952
- InstanceData *instance = env.GetInstanceData<InstanceData>();
961
+ InstanceData *instance = (InstanceData *)info.Data();
953
962
 
954
963
  if (info.Length() >= 1) {
955
964
  Napi::Number value = info[0].As<Napi::Number>();
@@ -969,14 +978,14 @@ static Napi::Value GetOrSetErrNo(const Napi::CallbackInfo &info)
969
978
  static Napi::Value CreateArrayType(const Napi::CallbackInfo &info)
970
979
  {
971
980
  Napi::Env env = info.Env();
972
- InstanceData *instance = env.GetInstanceData<InstanceData>();
981
+ InstanceData *instance = (InstanceData *)info.Data();
973
982
 
974
983
  if (info.Length() < 2) {
975
984
  ThrowError<Napi::TypeError>(env, "Expected 2 to 4 arguments, got %1", info.Length());
976
985
  return env.Null();
977
986
  }
978
987
 
979
- const TypeInfo *ref = ResolveType(info[0]);
988
+ const TypeInfo *ref = ResolveType(instance, info[0]);
980
989
  if (!ref)
981
990
  return env.Null();
982
991
 
@@ -1024,10 +1033,19 @@ static Napi::Value CreateArrayType(const Napi::CallbackInfo &info)
1024
1033
  }
1025
1034
 
1026
1035
  hint = ArrayHint::Typed;
1036
+ } else if (str == "Buffer" || str == "buffer") {
1037
+ if (!(ref->flags & (int)TypeFlag::HasTypedArray)) {
1038
+ ThrowError<Napi::Error>(env, "Array hint 'Buffer' cannot be used with type %1", ref->name);
1039
+ return env.Null();
1040
+ }
1041
+
1042
+ hint = ArrayHint::Buffer;
1027
1043
  } else if (str == "Array" || str == "array") {
1028
1044
  hint = ArrayHint::Array;
1029
1045
  } else if (str == "String" || str == "string") {
1030
- if (ref->primitive != PrimitiveKind::Int8 && ref->primitive != PrimitiveKind::Int16) {
1046
+ if (ref->primitive != PrimitiveKind::Int8 &&
1047
+ ref->primitive != PrimitiveKind::Int16 &&
1048
+ ref->primitive != PrimitiveKind::Int32) {
1031
1049
  ThrowError<Napi::Error>(env, "Array hint 'String' can only be used with 8, 16 and 32-bit signed integer types");
1032
1050
  return env.Null();
1033
1051
  }
@@ -1048,7 +1066,8 @@ static Napi::Value CreateArrayType(const Napi::CallbackInfo &info)
1048
1066
  type->countedby = DuplicateString(str.Utf8Value().c_str(), &instance->str_alloc).ptr;
1049
1067
  }
1050
1068
 
1051
- return WrapType(env, type);
1069
+ napi_value wrapper = WrapType(env, type);
1070
+ return Napi::Value(env, wrapper);
1052
1071
  }
1053
1072
 
1054
1073
  static bool ParseClassicFunction(const Napi::CallbackInfo &info, bool concrete, FunctionInfo *out_func)
@@ -1056,7 +1075,7 @@ static bool ParseClassicFunction(const Napi::CallbackInfo &info, bool concrete,
1056
1075
  K_ASSERT(info.Length() >= 2);
1057
1076
 
1058
1077
  Napi::Env env = info.Env();
1059
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1078
+ InstanceData *instance = (InstanceData *)info.Data();
1060
1079
 
1061
1080
  Napi::String name = info[0u].As<Napi::String>();
1062
1081
  Napi::Value ret = info[1u];
@@ -1099,7 +1118,7 @@ static bool ParseClassicFunction(const Napi::CallbackInfo &info, bool concrete,
1099
1118
  // Leave anonymous naming responsibility to caller
1100
1119
  out_func->name = named ? DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr : nullptr;
1101
1120
 
1102
- out_func->ret.type = ResolveType(ret);
1121
+ out_func->ret.type = ResolveType(instance, ret);
1103
1122
  if (!out_func->ret.type)
1104
1123
  return false;
1105
1124
  if (!CanReturnType(out_func->ret.type)) {
@@ -1126,7 +1145,7 @@ static bool ParseClassicFunction(const Napi::CallbackInfo &info, bool concrete,
1126
1145
  for (uint32_t j = 0; j < parameters_len; j++) {
1127
1146
  ParameterInfo param = {};
1128
1147
 
1129
- param.type = ResolveType(parameters[j], &param.directions);
1148
+ param.type = ResolveType(instance, parameters[j].AsValue(), &param.directions);
1130
1149
 
1131
1150
  if (!param.type)
1132
1151
  return false;
@@ -1152,7 +1171,7 @@ static bool ParseClassicFunction(const Napi::CallbackInfo &info, bool concrete,
1152
1171
  static Napi::Value CreateFunctionType(const Napi::CallbackInfo &info)
1153
1172
  {
1154
1173
  Napi::Env env = info.Env();
1155
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1174
+ InstanceData *instance = (InstanceData *)info.Data();
1156
1175
 
1157
1176
  FunctionInfo *func = instance->callbacks.AppendDefault();
1158
1177
  K_DEFER_N(err_guard) { instance->callbacks.RemoveLast(1); };
@@ -1204,13 +1223,14 @@ static Napi::Value CreateFunctionType(const Napi::CallbackInfo &info)
1204
1223
 
1205
1224
  instance->types_map.Set(type->name, type);
1206
1225
 
1207
- return WrapType(env, type);
1226
+ napi_value wrapper = WrapType(env, type);
1227
+ return Napi::Value(env, wrapper);
1208
1228
  }
1209
1229
 
1210
1230
  static Napi::Value CreateEnumType(const Napi::CallbackInfo &info)
1211
1231
  {
1212
1232
  Napi::Env env = info.Env();
1213
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1233
+ InstanceData *instance = (InstanceData *)info.Data();
1214
1234
 
1215
1235
  if (info.Length() < 1) {
1216
1236
  ThrowError<Napi::TypeError>(env, "Expected 1 or 2 arguments, got %1", info.Length());
@@ -1243,7 +1263,7 @@ static Napi::Value CreateEnumType(const Napi::CallbackInfo &info)
1243
1263
 
1244
1264
  // Determine needed storage type
1245
1265
  if (typed) {
1246
- const TypeInfo *storage = ResolveType(info[1 + named]);
1266
+ const TypeInfo *storage = ResolveType(instance, info[1 + named]);
1247
1267
  if (!storage)
1248
1268
  return env.Null();
1249
1269
 
@@ -1360,19 +1380,19 @@ static Napi::Value CreateEnumType(const Napi::CallbackInfo &info)
1360
1380
  return env.Null();
1361
1381
  err_guard.Disable();
1362
1382
 
1363
- Napi::Value wrapper = WrapType(env, type, false);
1383
+ napi_value wrapper = WrapType(env, type, false);
1364
1384
  Napi::Object defn = type->defn.Value();
1365
1385
 
1366
1386
  defn.Set("values", values);
1367
1387
  defn.Freeze();
1368
1388
 
1369
- return wrapper;
1389
+ return Napi::Value(env, wrapper);
1370
1390
  }
1371
1391
 
1372
1392
  static Napi::Value CreateTypeAlias(const Napi::CallbackInfo &info)
1373
1393
  {
1374
1394
  Napi::Env env = info.Env();
1375
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1395
+ InstanceData *instance = (InstanceData *)info.Data();
1376
1396
 
1377
1397
  if (info.Length() < 2) {
1378
1398
  ThrowError<Napi::TypeError>(env, "Expected 2 arguments, got %1", info.Length());
@@ -1386,7 +1406,7 @@ static Napi::Value CreateTypeAlias(const Napi::CallbackInfo &info)
1386
1406
  std::string name = info[0].As<Napi::String>();
1387
1407
  const char *alias = DuplicateString(name.c_str(), &instance->str_alloc).ptr;
1388
1408
 
1389
- const TypeInfo *type = ResolveType(info[1]);
1409
+ const TypeInfo *type = ResolveType(instance, info[1]);
1390
1410
  if (!type)
1391
1411
  return env.Null();
1392
1412
 
@@ -1394,23 +1414,26 @@ static Napi::Value CreateTypeAlias(const Napi::CallbackInfo &info)
1394
1414
  if (!MapType(env, instance, type, alias))
1395
1415
  return env.Null();
1396
1416
 
1397
- return WrapType(env, type);
1417
+ napi_value wrapper = WrapType(env, type);
1418
+ return Napi::Value(env, wrapper);
1398
1419
  }
1399
1420
 
1400
1421
  static Napi::Value GetResolvedType(const Napi::CallbackInfo &info)
1401
1422
  {
1402
1423
  Napi::Env env = info.Env();
1424
+ InstanceData *instance = (InstanceData *)info.Data();
1403
1425
 
1404
1426
  if (info.Length() < 1) {
1405
1427
  ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
1406
1428
  return env.Null();
1407
1429
  }
1408
1430
 
1409
- const TypeInfo *type = ResolveType(info[0]);
1431
+ const TypeInfo *type = ResolveType(instance, info[0]);
1410
1432
  if (!type)
1411
1433
  return env.Null();
1412
1434
 
1413
- return WrapType(env, type);
1435
+ napi_value wrapper = WrapType(env, type);
1436
+ return Napi::Value(env, wrapper);
1414
1437
  }
1415
1438
 
1416
1439
  #if defined(EXTERNAL_TYPES)
@@ -1424,7 +1447,7 @@ static Napi::Value GetTypeDefinition(const Napi::CallbackInfo &info)
1424
1447
  return env.Null();
1425
1448
  }
1426
1449
 
1427
- const TypeInfo *type = ResolveType(info[0]);
1450
+ const TypeInfo *type = ResolveType(instance, info[0]);
1428
1451
  if (!type)
1429
1452
  return env.Null();
1430
1453
 
@@ -1530,13 +1553,15 @@ void ReleaseMemory(InstanceData *instance, InstanceMemory *mem)
1530
1553
  }
1531
1554
  }
1532
1555
 
1533
- Napi::Function LibraryHandle::InitClass(Napi::Env env)
1556
+ Napi::Function LibraryHandle::InitClass(InstanceData *instance)
1534
1557
  {
1558
+ Napi::Env env = instance->env;
1559
+
1535
1560
  // node-addon-api wants std::vector
1536
1561
  std::vector<Napi::ClassPropertyDescriptor<LibraryHandle>> properties = {
1537
- InstanceMethod("func", &LibraryHandle::Func),
1538
- InstanceMethod("symbol", &LibraryHandle::Symbol),
1539
- InstanceMethod("unload", &LibraryHandle::Unload)
1562
+ InstanceMethod("func", &LibraryHandle::Func, napi_default, instance),
1563
+ InstanceMethod("symbol", &LibraryHandle::Symbol, napi_default, instance),
1564
+ InstanceMethod("unload", &LibraryHandle::Unload, napi_default, instance)
1540
1565
  };
1541
1566
 
1542
1567
  if (Napi::Value dispose = env.RunScript("Symbol.dispose"); !IsNullOrUndefined(env, dispose)) {
@@ -1573,7 +1598,7 @@ void LibraryHandle::Finalize(Napi::BasicEnv env)
1573
1598
  Napi::Value LibraryHandle::Func(const Napi::CallbackInfo &info)
1574
1599
  {
1575
1600
  Napi::Env env = info.Env();
1576
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1601
+ InstanceData *instance = (InstanceData *)info.Data();
1577
1602
 
1578
1603
  FunctionInfo *func = new FunctionInfo();
1579
1604
  K_DEFER { func->Unref(); };
@@ -1635,13 +1660,14 @@ Napi::Value LibraryHandle::Func(const Napi::CallbackInfo &info)
1635
1660
  return env.Null();
1636
1661
  }
1637
1662
 
1638
- return WrapFunction(env, func);
1663
+ napi_value wrapper = WrapFunction(env, func);
1664
+ return Napi::Value(env, wrapper);
1639
1665
  }
1640
1666
 
1641
1667
  Napi::Value LibraryHandle::Symbol(const Napi::CallbackInfo &info)
1642
1668
  {
1643
1669
  Napi::Env env = info.Env();
1644
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1670
+ InstanceData *instance = (InstanceData *)info.Data();
1645
1671
 
1646
1672
  if (info.Length() < 2) {
1647
1673
  ThrowError<Napi::TypeError>(env, "Expected 2, got %1", info.Length());
@@ -1654,7 +1680,7 @@ Napi::Value LibraryHandle::Symbol(const Napi::CallbackInfo &info)
1654
1680
 
1655
1681
  std::string name = info[0].As<Napi::String>();
1656
1682
 
1657
- const TypeInfo *type = ResolveType(info[1]);
1683
+ const TypeInfo *type = ResolveType(instance, info[1]);
1658
1684
  if (!type)
1659
1685
  return env.Null();
1660
1686
 
@@ -1668,7 +1694,8 @@ Napi::Value LibraryHandle::Symbol(const Napi::CallbackInfo &info)
1668
1694
  return env.Null();
1669
1695
  }
1670
1696
 
1671
- return WrapPointer(env, type, ptr);
1697
+ napi_value wrapper = WrapPointer(env, type, ptr);
1698
+ return Napi::Value(env, wrapper);
1672
1699
  }
1673
1700
 
1674
1701
  Napi::Value LibraryHandle::Unload(const Napi::CallbackInfo &info)
@@ -1683,7 +1710,7 @@ Napi::Value LibraryHandle::Unload(const Napi::CallbackInfo &info)
1683
1710
  static Napi::Value LoadSharedLibrary(const Napi::CallbackInfo &info)
1684
1711
  {
1685
1712
  Napi::Env env = info.Env();
1686
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1713
+ InstanceData *instance = (InstanceData *)info.Data();
1687
1714
 
1688
1715
  if (info.Length() < 1) {
1689
1716
  ThrowError<Napi::TypeError>(env, "Expected 1 or 2 arguments, got %1", info.Length());
@@ -1768,7 +1795,7 @@ static Napi::Value LoadSharedLibrary(const Napi::CallbackInfo &info)
1768
1795
  static Napi::Value RegisterCallback(const Napi::CallbackInfo &info)
1769
1796
  {
1770
1797
  Napi::Env env = info.Env();
1771
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1798
+ InstanceData *instance = (InstanceData *)info.Data();
1772
1799
 
1773
1800
  if (!InitAsyncBroker(env, instance)) [[unlikely]]
1774
1801
  return env.Null();
@@ -1784,7 +1811,7 @@ static Napi::Value RegisterCallback(const Napi::CallbackInfo &info)
1784
1811
 
1785
1812
  Napi::Function func = info[0].As<Napi::Function>();
1786
1813
 
1787
- const TypeInfo *type = ResolveType(info[1]);
1814
+ const TypeInfo *type = ResolveType(instance, info[1]);
1788
1815
  if (!type)
1789
1816
  return env.Null();
1790
1817
  if (type->primitive != PrimitiveKind::Callback) {
@@ -1811,20 +1838,21 @@ static Napi::Value RegisterCallback(const Napi::CallbackInfo &info)
1811
1838
  trampoline->instance = instance;
1812
1839
  trampoline->stack0 = instance->memories[0]->stack0;
1813
1840
  trampoline->proto = type->proto;
1814
- napi_create_reference(env, func, 1, &trampoline->func);
1841
+ NAPI_OK(napi_create_reference(env, func, 1, &trampoline->func));
1815
1842
 
1816
1843
  void *ptr = GetTrampoline(idx);
1817
1844
 
1818
1845
  // Cache index for fast unregistration
1819
1846
  instance->trampolines_map.Set(ptr, idx);
1820
1847
 
1821
- return WrapPointer(env, type->ref.type, ptr);
1848
+ napi_value wrapper = WrapPointer(env, type->ref.type, ptr);
1849
+ return Napi::Value(env, wrapper);
1822
1850
  }
1823
1851
 
1824
1852
  static Napi::Value UnregisterCallback(const Napi::CallbackInfo &info)
1825
1853
  {
1826
1854
  Napi::Env env = info.Env();
1827
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1855
+ InstanceData *instance = (InstanceData *)info.Data();
1828
1856
 
1829
1857
  if (info.Length() < 1) {
1830
1858
  ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
@@ -1870,6 +1898,7 @@ static Napi::Value UnregisterCallback(const Napi::CallbackInfo &info)
1870
1898
  static Napi::Value CastValue(const Napi::CallbackInfo &info)
1871
1899
  {
1872
1900
  Napi::Env env = info.Env();
1901
+ InstanceData *instance = (InstanceData *)info.Data();
1873
1902
 
1874
1903
  if (info.Length() < 2) [[unlikely]] {
1875
1904
  ThrowError<Napi::TypeError>(env, "Expected 2 arguments, got %1", info.Length());
@@ -1878,7 +1907,7 @@ static Napi::Value CastValue(const Napi::CallbackInfo &info)
1878
1907
 
1879
1908
  Napi::Value value = info[0];
1880
1909
 
1881
- const TypeInfo *type = ResolveType(info[1]);
1910
+ const TypeInfo *type = ResolveType(instance, info[1]);
1882
1911
  if (!type) [[unlikely]]
1883
1912
  return env.Null();
1884
1913
  if (type->primitive != PrimitiveKind::Pointer &&
@@ -1893,7 +1922,7 @@ static Napi::Value CastValue(const Napi::CallbackInfo &info)
1893
1922
  ValueCast *cast = new ValueCast();
1894
1923
 
1895
1924
  cast->env = env;
1896
- napi_create_reference(env, value, 1, &cast->ref);
1925
+ NAPI_OK(napi_create_reference(env, value, 1, &cast->ref));
1897
1926
  cast->type = type;
1898
1927
 
1899
1928
  Napi::External<ValueCast> external = Napi::External<ValueCast>::New(env, cast, [](Napi::Env, ValueCast *cast) { delete cast; });
@@ -1905,6 +1934,7 @@ static Napi::Value CastValue(const Napi::CallbackInfo &info)
1905
1934
  static Napi::Value DecodeValue(const Napi::CallbackInfo &info)
1906
1935
  {
1907
1936
  Napi::Env env = info.Env();
1937
+ InstanceData *instance = (InstanceData *)info.Data();
1908
1938
 
1909
1939
  bool has_offset = (info.Length() >= 2 && info[1].IsNumber());
1910
1940
  bool has_len = (info.Length() >= 3u + has_offset && info[2 + has_offset].IsNumber());
@@ -1914,22 +1944,78 @@ static Napi::Value DecodeValue(const Napi::CallbackInfo &info)
1914
1944
  return env.Null();
1915
1945
  }
1916
1946
 
1917
- const TypeInfo *type = ResolveType(info[1u + has_offset]);
1947
+ const TypeInfo *type = ResolveType(instance, info[1u + has_offset]);
1918
1948
  if (!type) [[unlikely]]
1919
1949
  return env.Null();
1920
1950
 
1921
- Napi::Value value = info[0];
1951
+ napi_value ref = info[0];
1922
1952
  int64_t offset = has_offset ? info[1].As<Napi::Number>().Int64Value() : 0;
1923
1953
 
1954
+ const void *src = nullptr;
1955
+ Size len = 0;
1956
+
1957
+ if (!TryPointer(env, ref, (void **)&src, &len)) {
1958
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for reference, expected pointer", GetValueType(instance, ref));
1959
+ return env.Null();
1960
+ }
1961
+
1962
+ if (len >= 0) {
1963
+ if (offset < 0) [[unlikely]] {
1964
+ ThrowError<Napi::Error>(env, "Offset must be >= 0");
1965
+ return env.Null();
1966
+ }
1967
+ if (len - offset < type->size) [[unlikely]] {
1968
+ ThrowError<Napi::Error>(env, "Expected buffer with size superior or equal to type %1 (%2 bytes)",
1969
+ type->name, type->size + offset);
1970
+ return env.Null();
1971
+ }
1972
+ }
1973
+
1974
+ if (!src) [[unlikely]] {
1975
+ ThrowError<Napi::Error>(env, "Cannot encode data in NULL pointer");
1976
+ return env.Null();
1977
+ }
1978
+
1979
+ src = (const void *)((const uint8_t *)src + offset);
1980
+
1924
1981
  if (has_len) {
1925
1982
  Size len = info[2 + has_offset].As<Napi::Number>();
1926
1983
 
1927
- napi_value ret = Decode(value, (Size)offset, type, &len);
1928
- return Napi::Value(env, ret);
1929
- } else {
1930
- napi_value ret = Decode(value, (Size)offset, type);
1931
- return Napi::Value(env, ret);
1984
+ if (len >= 0) {
1985
+ type = MakeArrayType(instance, type, len);
1986
+ } else {
1987
+ switch (type->primitive) {
1988
+ case PrimitiveKind::Int8:
1989
+ case PrimitiveKind::UInt8: {
1990
+ Size count = strlen((const char *)src);
1991
+ type = MakeArrayType(instance, type, count);
1992
+ } break;
1993
+ case PrimitiveKind::Int16:
1994
+ case PrimitiveKind::UInt16: {
1995
+ Size count = NullTerminatedLength((const char16_t *)src);
1996
+ type = MakeArrayType(instance, type, count);
1997
+ } break;
1998
+ case PrimitiveKind::Int32:
1999
+ case PrimitiveKind::UInt32: {
2000
+ Size count = NullTerminatedLength((const char32_t *)src);
2001
+ type = MakeArrayType(instance, type, count);
2002
+ } break;
2003
+
2004
+ case PrimitiveKind::Pointer: {
2005
+ Size count = NullTerminatedLength((const void **)src);
2006
+ type = MakeArrayType(instance, type, count);
2007
+ } break;
2008
+
2009
+ default: {
2010
+ ThrowError<Napi::TypeError>(env, "Cannot determine null-terminated length for type %1", type->name);
2011
+ return env.Null();
2012
+ } break;
2013
+ }
2014
+ }
1932
2015
  }
2016
+
2017
+ napi_value ret = Decode(instance, (const uint8_t *)src, type);
2018
+ return Napi::Value(env, ret);
1933
2019
  }
1934
2020
 
1935
2021
  template <typename T>
@@ -1938,8 +2024,7 @@ static FORCE_INLINE napi_value DecodeInteger(napi_env env, napi_callback_info in
1938
2024
  napi_value arg;
1939
2025
  size_t count = 1;
1940
2026
 
1941
- napi_status status = napi_get_cb_info(env, info, &count, &arg, nullptr, nullptr);
1942
- K_ASSERT(status == napi_ok);
2027
+ NAPI_OK(napi_get_cb_info(env, info, &count, &arg, nullptr, nullptr));
1943
2028
 
1944
2029
  if (count < 1) [[unlikely]] {
1945
2030
  ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", count);
@@ -1965,8 +2050,7 @@ static napi_value DecodeFloat(napi_env env, napi_callback_info info)
1965
2050
  napi_value arg;
1966
2051
  size_t count = 1;
1967
2052
 
1968
- napi_status status = napi_get_cb_info(env, info, &count, &arg, nullptr, nullptr);
1969
- K_ASSERT(status == napi_ok);
2053
+ NAPI_OK(napi_get_cb_info(env, info, &count, &arg, nullptr, nullptr));
1970
2054
 
1971
2055
  if (count < 1) [[unlikely]] {
1972
2056
  ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", count);
@@ -1992,8 +2076,7 @@ static napi_value DecodeDouble(napi_env env, napi_callback_info info)
1992
2076
  napi_value arg;
1993
2077
  size_t count = 1;
1994
2078
 
1995
- napi_status status = napi_get_cb_info(env, info, &count, &arg, nullptr, nullptr);
1996
- K_ASSERT(status == napi_ok);
2079
+ NAPI_OK(napi_get_cb_info(env, info, &count, &arg, nullptr, nullptr));
1997
2080
 
1998
2081
  if (count < 1) [[unlikely]] {
1999
2082
  ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", count);
@@ -2019,8 +2102,7 @@ static napi_value DecodeString(napi_env env, napi_callback_info info)
2019
2102
  napi_value args[2];
2020
2103
  size_t count = 2;
2021
2104
 
2022
- napi_status status = napi_get_cb_info(env, info, &count, args, nullptr, nullptr);
2023
- K_ASSERT(status == napi_ok);
2105
+ NAPI_OK(napi_get_cb_info(env, info, &count, args, nullptr, nullptr));
2024
2106
 
2025
2107
  if (count < 1) [[unlikely]] {
2026
2108
  ThrowError<Napi::TypeError>(env, "Expected 1 to 2 arguments, got %1", count);
@@ -2055,8 +2137,7 @@ static napi_value DecodeString16(napi_env env, napi_callback_info info)
2055
2137
  napi_value args[2];
2056
2138
  size_t count = 2;
2057
2139
 
2058
- napi_status status = napi_get_cb_info(env, info, &count, args, nullptr, nullptr);
2059
- K_ASSERT(status == napi_ok);
2140
+ NAPI_OK(napi_get_cb_info(env, info, &count, args, nullptr, nullptr));
2060
2141
 
2061
2142
  if (count < 1) [[unlikely]] {
2062
2143
  ThrowError<Napi::TypeError>(env, "Expected 1 to 2 arguments, got %1", count);
@@ -2091,8 +2172,7 @@ static napi_value DecodeString32(napi_env env, napi_callback_info info)
2091
2172
  napi_value args[2];
2092
2173
  size_t count = 2;
2093
2174
 
2094
- napi_status status = napi_get_cb_info(env, info, &count, args, nullptr, nullptr);
2095
- K_ASSERT(status == napi_ok);
2175
+ NAPI_OK(napi_get_cb_info(env, info, &count, args, nullptr, nullptr));
2096
2176
 
2097
2177
  if (count < 1) [[unlikely]] {
2098
2178
  ThrowError<Napi::TypeError>(env, "Expected 1 to 2 arguments, got %1", count);
@@ -2125,6 +2205,7 @@ static napi_value DecodeString32(napi_env env, napi_callback_info info)
2125
2205
  static Napi::Value GetPointerAddress(const Napi::CallbackInfo &info)
2126
2206
  {
2127
2207
  Napi::Env env = info.Env();
2208
+ InstanceData *instance = (InstanceData *)info.Data();
2128
2209
 
2129
2210
  if (info.Length() < 1) {
2130
2211
  ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
@@ -2133,8 +2214,6 @@ static Napi::Value GetPointerAddress(const Napi::CallbackInfo &info)
2133
2214
 
2134
2215
  void *ptr = nullptr;
2135
2216
  if (!TryPointer(env, info[0], &ptr)) {
2136
- InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
2137
-
2138
2217
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, info[0]));
2139
2218
  return env.Null();
2140
2219
  }
@@ -2148,6 +2227,7 @@ static Napi::Value GetPointerAddress(const Napi::CallbackInfo &info)
2148
2227
  static Napi::Value CallPointerSync(const Napi::CallbackInfo &info)
2149
2228
  {
2150
2229
  Napi::Env env = info.Env();
2230
+ InstanceData *instance = (InstanceData *)info.Data();
2151
2231
 
2152
2232
  if (info.Length() < 2) [[unlikely]] {
2153
2233
  ThrowError<Napi::TypeError>(env, "Expected 2 or more arguments, got %1", info.Length());
@@ -2156,18 +2236,14 @@ static Napi::Value CallPointerSync(const Napi::CallbackInfo &info)
2156
2236
 
2157
2237
  void *ptr = nullptr;
2158
2238
  if (!TryPointer(env, info[0], &ptr)) {
2159
- InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
2160
-
2161
2239
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, info[0]));
2162
2240
  return env.Null();
2163
2241
  }
2164
2242
 
2165
- const TypeInfo *type = ResolveType(info[1]);
2243
+ const TypeInfo *type = ResolveType(instance, info[1]);
2166
2244
  if (!type) [[unlikely]]
2167
2245
  return env.Null();
2168
2246
  if (type->primitive != PrimitiveKind::Prototype) [[unlikely]] {
2169
- InstanceData *instance = env.GetInstanceData<InstanceData>();
2170
-
2171
2247
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for type, expected function type", GetValueType(instance, info[1]));
2172
2248
  return env.Null();
2173
2249
  }
@@ -2179,6 +2255,7 @@ static Napi::Value CallPointerSync(const Napi::CallbackInfo &info)
2179
2255
  static Napi::Value EncodeValue(const Napi::CallbackInfo &info)
2180
2256
  {
2181
2257
  Napi::Env env = info.Env();
2258
+ InstanceData *instance = (InstanceData *)info.Data();
2182
2259
 
2183
2260
  bool has_offset = (info.Length() >= 2 && info[1].IsNumber());
2184
2261
  bool has_len = (info.Length() >= 4u + has_offset && info[3 + has_offset].IsNumber());
@@ -2188,7 +2265,7 @@ static Napi::Value EncodeValue(const Napi::CallbackInfo &info)
2188
2265
  return env.Null();
2189
2266
  }
2190
2267
 
2191
- const TypeInfo *type = ResolveType(info[1u + has_offset]);
2268
+ const TypeInfo *type = ResolveType(instance, info[1u + has_offset]);
2192
2269
  if (!type) [[unlikely]]
2193
2270
  return env.Null();
2194
2271
 
@@ -2196,38 +2273,71 @@ static Napi::Value EncodeValue(const Napi::CallbackInfo &info)
2196
2273
  int64_t offset = has_offset ? info[1].As<Napi::Number>().Int64Value() : 0;
2197
2274
  Napi::Value value = info[2 + has_offset];
2198
2275
 
2199
- if (has_len) {
2200
- Size len = info[3 + has_offset].As<Napi::Number>();
2276
+ void *dest = nullptr;
2277
+ Size len = 0;
2201
2278
 
2202
- if (!Encode(ref, (Size)offset, value, type, &len))
2279
+ if (!TryPointer(env, ref, &dest, &len)) {
2280
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for reference, expected pointer", GetValueType(instance, ref));
2281
+ return env.Null();
2282
+ }
2283
+
2284
+ if (len >= 0) {
2285
+ if (offset < 0) [[unlikely]] {
2286
+ ThrowError<Napi::Error>(env, "Offset must be >= 0");
2203
2287
  return env.Null();
2204
- } else {
2205
- if (!Encode(ref, (Size)offset, value, type))
2288
+ }
2289
+ if (len - offset < type->size) [[unlikely]] {
2290
+ ThrowError<Napi::Error>(env, "Expected buffer with size superior or equal to type %1 (%2 bytes)",
2291
+ type->name, type->size + offset);
2206
2292
  return env.Null();
2293
+ }
2294
+ }
2295
+
2296
+ if (!dest) [[unlikely]] {
2297
+ ThrowError<Napi::Error>(env, "Cannot encode data in NULL pointer");
2298
+ return env.Null();
2299
+ }
2300
+
2301
+ dest = (void *)((uint8_t *)dest + offset);
2302
+
2303
+ if (has_len) {
2304
+ Size len = info[3 + has_offset].As<Napi::Number>();
2305
+
2306
+ if (type->primitive != PrimitiveKind::String &&
2307
+ type->primitive != PrimitiveKind::String16 &&
2308
+ type->primitive != PrimitiveKind::String32 &&
2309
+ type->primitive != PrimitiveKind::Prototype) {
2310
+ if (len < 0) [[unlikely]] {
2311
+ ThrowError<Napi::TypeError>(env, "Automatic (negative) length is only supported when decoding");
2312
+ return env.Null();
2313
+ }
2314
+
2315
+ type = MakeArrayType(instance, type, len);
2316
+ }
2207
2317
  }
2208
2318
 
2319
+ if (!Encode(instance, (uint8_t *)dest, value, type))
2320
+ return env.Null();
2321
+
2209
2322
  return env.Undefined();
2210
2323
  }
2211
2324
 
2212
2325
  static Napi::Value CreateView(const Napi::CallbackInfo &info)
2213
2326
  {
2214
2327
  Napi::Env env = info.Env();
2328
+ InstanceData *instance = (InstanceData *)info.Data();
2215
2329
 
2216
2330
  if (info.Length() < 1) {
2217
2331
  ThrowError<Napi::TypeError>(env, "Expected 2 arguments, got %1", info.Length());
2218
2332
  return env.Null();
2219
2333
  }
2220
2334
  if (!info[1].IsNumber()) {
2221
- InstanceData *instance = env.GetInstanceData<InstanceData>();
2222
-
2223
2335
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for length, expected integer", GetValueType(instance, info[1]));
2224
2336
  return env.Null();
2225
2337
  }
2226
2338
 
2227
2339
  void *ptr = nullptr;
2228
2340
  if (!TryPointer(env, info[0], &ptr)) {
2229
- InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
2230
-
2231
2341
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, info[0]));
2232
2342
  return env.Null();
2233
2343
  }
@@ -2256,7 +2366,7 @@ static Napi::Value CreateView(const Napi::CallbackInfo &info)
2256
2366
  static Napi::Value ResetKoffi(const Napi::CallbackInfo &info)
2257
2367
  {
2258
2368
  Napi::Env env = info.Env();
2259
- InstanceData *instance = env.GetInstanceData<InstanceData>();
2369
+ InstanceData *instance = (InstanceData *)info.Data();
2260
2370
 
2261
2371
  if (instance->broker) {
2262
2372
  napi_release_threadsafe_function(instance->broker, napi_tsfn_abort);
@@ -2338,13 +2448,13 @@ InstanceMemory::~InstanceMemory()
2338
2448
  #endif
2339
2449
  }
2340
2450
 
2341
- static void RegisterPrimitiveType(Napi::Env env, Napi::Object map, std::initializer_list<const char *> names,
2451
+ static void RegisterPrimitiveType(InstanceData *instance, Napi::Object map, std::initializer_list<const char *> names,
2342
2452
  PrimitiveKind primitive, int32_t size, int16_t align, const char *ref = nullptr)
2343
2453
  {
2344
2454
  K_ASSERT(names.size() > 0);
2345
2455
  K_ASSERT(align <= size);
2346
2456
 
2347
- InstanceData *instance = env.GetInstanceData<InstanceData>();
2457
+ Napi::Env env = instance->env;
2348
2458
 
2349
2459
  TypeInfo *type = instance->types.AppendDefault();
2350
2460
 
@@ -2369,7 +2479,7 @@ static void RegisterPrimitiveType(Napi::Env env, Napi::Object map, std::initiali
2369
2479
  K_ASSERT(type->ref.type);
2370
2480
  }
2371
2481
 
2372
- Napi::Value wrapper = WrapType(env, type);
2482
+ napi_value wrapper = WrapType(env, type);
2373
2483
 
2374
2484
  for (const char *name: names) {
2375
2485
  bool inserted;
@@ -2451,12 +2561,12 @@ static bool CanDeleteReferenceInFinalizer(const napi_node_version &node, uint32_
2451
2561
  return false;
2452
2562
  }
2453
2563
 
2454
- static napi_value CreateFunction(napi_env env, napi_callback native, const char *name = nullptr)
2564
+ static napi_value CreateFunction(InstanceData *instance, napi_callback native, const char *name = nullptr)
2455
2565
  {
2456
- napi_value func;
2566
+ Napi::Env env = instance->env;
2457
2567
 
2458
- napi_status status = napi_create_function(env, name, NAPI_AUTO_LENGTH, native, nullptr, &func);
2459
- K_ASSERT(status == napi_ok);
2568
+ napi_value func;
2569
+ NAPI_OK(napi_create_function(env, name, NAPI_AUTO_LENGTH, native, instance, &func));
2460
2570
 
2461
2571
  return func;
2462
2572
  }
@@ -2528,77 +2638,77 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
2528
2638
  Napi::Number::New(env, 0.0);
2529
2639
  #endif
2530
2640
 
2531
- exports.Set("config", Napi::Function::New(env, GetSetConfig, "config"));
2532
- exports.Set("stats", Napi::Function::New(env, GetStats, "stats"));
2533
-
2534
- exports.Set("struct", Napi::Function::New(env, CreatePaddedStructType, "struct"));
2535
- exports.Set("pack", Napi::Function::New(env, CreatePackedStructType, "pack"));
2536
- exports.Set("union", Napi::Function::New(env, CreateUnionType, "union"));
2537
- exports.Set("Union", Napi::Function::New(env, InstantiateUnion, "Union"));
2538
- exports.Set("opaque", Napi::Function::New(env, CreateOpaqueType, "opaque"));
2539
- exports.Set("pointer", Napi::Function::New(env, CreatePointerType, "pointer"));
2540
- exports.Set("array", Napi::Function::New(env, CreateArrayType, "array"));
2541
- exports.Set("proto", Napi::Function::New(env, CreateFunctionType, "proto"));
2542
- exports.Set("alias", Napi::Function::New(env, CreateTypeAlias, "alias"));
2543
- exports.Set("enumeration", Napi::Function::New(env, CreateEnumType, "enumeration"));
2544
-
2545
- exports.Set("type", Napi::Function::New(env, GetResolvedType, "type"));
2641
+ exports.Set("config", Napi::Function::New(env, GetSetConfig, "config", instance));
2642
+ exports.Set("stats", Napi::Function::New(env, GetStats, "stats", instance));
2643
+
2644
+ exports.Set("struct", Napi::Function::New(env, CreatePaddedStructType, "struct", instance));
2645
+ exports.Set("pack", Napi::Function::New(env, CreatePackedStructType, "pack", instance));
2646
+ exports.Set("union", Napi::Function::New(env, CreateUnionType, "union", instance));
2647
+ exports.Set("Union", Napi::Function::New(env, InstantiateUnion, "Union", instance));
2648
+ exports.Set("opaque", Napi::Function::New(env, CreateOpaqueType, "opaque", instance));
2649
+ exports.Set("pointer", Napi::Function::New(env, CreatePointerType, "pointer", instance));
2650
+ exports.Set("array", Napi::Function::New(env, CreateArrayType, "array", instance));
2651
+ exports.Set("proto", Napi::Function::New(env, CreateFunctionType, "proto", instance));
2652
+ exports.Set("alias", Napi::Function::New(env, CreateTypeAlias, "alias", instance));
2653
+ exports.Set("enumeration", Napi::Function::New(env, CreateEnumType, "enumeration", instance));
2654
+
2655
+ exports.Set("type", Napi::Function::New(env, GetResolvedType, "type", instance));
2546
2656
  #if defined(EXTERNAL_TYPES)
2547
- exports.Set("introspect", Napi::Function::New(env, GetTypeDefinition, "introspect"));
2657
+ exports.Set("introspect", Napi::Function::New(env, GetTypeDefinition, "introspect", instance));
2548
2658
  #endif
2549
2659
 
2550
- exports.Set("load", Napi::Function::New(env, LoadSharedLibrary, "load"));
2660
+ exports.Set("load", Napi::Function::New(env, LoadSharedLibrary, "load", instance));
2551
2661
 
2552
- exports.Set("in", Napi::Function::New(env, MarkIn, "in"));
2553
- exports.Set("out", Napi::Function::New(env, MarkOut, "out"));
2554
- exports.Set("inout", Napi::Function::New(env, MarkInOut, "inout"));
2662
+ exports.Set("in", Napi::Function::New(env, MarkIn, "in", instance));
2663
+ exports.Set("out", Napi::Function::New(env, MarkOut, "out", instance));
2664
+ exports.Set("inout", Napi::Function::New(env, MarkInOut, "inout", instance));
2555
2665
 
2556
- exports.Set("disposable", Napi::Function::New(env, CreateDisposableType, "disposable"));
2557
- exports.Set("alloc", Napi::Function::New(env, CallAlloc, "alloc"));
2558
- exports.Set("free", Napi::Function::New(env, CallFree, "free"));
2666
+ exports.Set("disposable", Napi::Function::New(env, CreateDisposableType, "disposable", instance));
2667
+ exports.Set("alloc", Napi::Function::New(env, CallAlloc, "alloc", instance));
2668
+ exports.Set("free", Napi::Function::New(env, CallFree, "free", instance));
2559
2669
 
2560
- exports.Set("register", Napi::Function::New(env, RegisterCallback, "register"));
2561
- exports.Set("unregister", Napi::Function::New(env, UnregisterCallback, "unregister"));
2670
+ exports.Set("register", Napi::Function::New(env, RegisterCallback, "register", instance));
2671
+ exports.Set("unregister", Napi::Function::New(env, UnregisterCallback, "unregister", instance));
2562
2672
 
2563
- exports.Set("as", Napi::Function::New(env, CastValue, "as"));
2564
- exports.Set("address", Napi::Function::New(env, GetPointerAddress, "address"));
2565
- exports.Set("call", Napi::Function::New(env, CallPointerSync, "call"));
2566
- exports.Set("encode", Napi::Function::New(env, EncodeValue, "encode"));
2567
- exports.Set("view", Napi::Function::New(env, CreateView, "view"));
2673
+ exports.Set("as", Napi::Function::New(env, CastValue, "as", instance));
2674
+ exports.Set("address", Napi::Function::New(env, GetPointerAddress, "address", instance));
2675
+ exports.Set("call", Napi::Function::New(env, CallPointerSync, "call", instance));
2676
+ exports.Set("encode", Napi::Function::New(env, EncodeValue, "encode", instance));
2677
+ exports.Set("view", Napi::Function::New(env, CreateView, "view", instance));
2568
2678
 
2569
2679
  {
2570
- Napi::Function decode = Napi::Function::New(env, DecodeValue, "decode");
2571
-
2572
- decode.Set("char", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<char>(env, info); }, "char"));
2573
- decode.Set("uchar", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<unsigned char>(env, info); }, "uchar"));
2574
- decode.Set("short", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<short>(env, info); }, "short"));
2575
- decode.Set("ushort", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<unsigned short>(env, info); }, "ushort"));
2576
- decode.Set("int", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<int>(env, info); }, "int"));
2577
- decode.Set("uint", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<unsigned int>(env, info); }, "uint"));
2578
- decode.Set("long", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<long>(env, info); }, "long"));
2579
- decode.Set("ulong", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<unsigned long>(env, info); }, "ulong"));
2580
- decode.Set("longlong", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<long long>(env, info); }, "longlong"));
2581
- decode.Set("ulonglong", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<unsigned long long>(env, info); }, "ulonglong"));
2582
- decode.Set("int8", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<int8_t>(env, info); }, "int8"));
2583
- decode.Set("uint8", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<uint8_t>(env, info); }, "uint8"));
2584
- decode.Set("int16", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<int16_t>(env, info); }, "int16"));
2585
- decode.Set("uint16", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<uint16_t>(env, info); }, "uint16"));
2586
- decode.Set("int32", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<int32_t>(env, info); }, "int32"));
2587
- decode.Set("uint32", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<uint32_t>(env, info); }, "uint32"));
2588
- decode.Set("int64", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<int64_t>(env, info); }, "int64"));
2589
- decode.Set("uint64", CreateFunction(env, [](napi_env env, napi_callback_info info) { return DecodeInteger<uint64_t>(env, info); }, "uint64"));
2590
- decode.Set("float", CreateFunction(env, DecodeFloat, "float"));
2591
- decode.Set("double", CreateFunction(env, DecodeDouble, "double"));
2592
- decode.Set("string", CreateFunction(env, DecodeString, "string"));
2593
- decode.Set("string16", CreateFunction(env, DecodeString16, "string16"));
2594
- decode.Set("string32", CreateFunction(env, DecodeString32, "string32"));
2680
+ Napi::Function decode = Napi::Function::New(env, DecodeValue, "decode", instance);
2681
+
2682
+ decode.Set("char", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<char>(env, info); }, "char"));
2683
+ decode.Set("uchar", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<unsigned char>(env, info); }, "uchar"));
2684
+ decode.Set("short", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<short>(env, info); }, "short"));
2685
+ decode.Set("ushort", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<unsigned short>(env, info); }, "ushort"));
2686
+ decode.Set("int", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<int>(env, info); }, "int"));
2687
+ decode.Set("uint", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<unsigned int>(env, info); }, "uint"));
2688
+ decode.Set("long", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<long>(env, info); }, "long"));
2689
+ decode.Set("ulong", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<unsigned long>(env, info); }, "ulong"));
2690
+ decode.Set("longlong", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<long long>(env, info); }, "longlong"));
2691
+ decode.Set("ulonglong", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<unsigned long long>(env, info); }, "ulonglong"));
2692
+ decode.Set("int8", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<int8_t>(env, info); }, "int8"));
2693
+ decode.Set("uint8", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<uint8_t>(env, info); }, "uint8"));
2694
+ decode.Set("int16", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<int16_t>(env, info); }, "int16"));
2695
+ decode.Set("uint16", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<uint16_t>(env, info); }, "uint16"));
2696
+ decode.Set("int32", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<int32_t>(env, info); }, "int32"));
2697
+ decode.Set("uint32", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<uint32_t>(env, info); }, "uint32"));
2698
+ decode.Set("int64", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<int64_t>(env, info); }, "int64"));
2699
+ decode.Set("uint64", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<uint64_t>(env, info); }, "uint64"));
2700
+ decode.Set("float", CreateFunction(instance, DecodeFloat, "float"));
2701
+ decode.Set("double", CreateFunction(instance, DecodeDouble, "double"));
2702
+ decode.Set("string", CreateFunction(instance, DecodeString, "string"));
2703
+ decode.Set("string16", CreateFunction(instance, DecodeString16, "string16"));
2704
+ decode.Set("string32", CreateFunction(instance, DecodeString32, "string32"));
2595
2705
 
2596
2706
  exports.Set("decode", decode);
2597
2707
  }
2598
2708
 
2599
- exports.Set("reset", Napi::Function::New(env, ResetKoffi, "reset"));
2709
+ exports.Set("reset", Napi::Function::New(env, ResetKoffi, "reset", instance));
2600
2710
 
2601
- exports.Set("errno", Napi::Function::New(env, GetOrSetErrNo, "errno"));
2711
+ exports.Set("errno", Napi::Function::New(env, GetOrSetErrNo, "errno", instance));
2602
2712
 
2603
2713
  // Export useful OS info
2604
2714
  {
@@ -2625,11 +2735,11 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
2625
2735
  // Init object classes and symbols
2626
2736
  {
2627
2737
  instance->object_constructor = Napi::Persistent(env.RunScript("Object.prototype").As<Napi::Object>());
2628
- instance->construct_lib = Napi::Persistent(LibraryHandle::InitClass(env));
2738
+ instance->construct_lib = Napi::Persistent(LibraryHandle::InitClass(instance));
2629
2739
  #if !defined(EXTERNAL_TYPES)
2630
- instance->construct_type = Napi::Persistent(TypeObject::InitClass(env));
2740
+ instance->construct_type = Napi::Persistent(TypeObject::InitClass(instance));
2631
2741
  #endif
2632
- instance->construct_poll = Napi::Persistent(PollHandle::InitClass(env));
2742
+ instance->construct_poll = Napi::Persistent(PollHandle::InitClass(instance));
2633
2743
  instance->active_symbol = Napi::Persistent(Napi::Symbol::New(env, "active"));
2634
2744
 
2635
2745
  exports.Set("LibraryHandle", instance->construct_lib.Value());
@@ -2643,57 +2753,57 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
2643
2753
  Napi::Object types = Napi::Object::New(env);
2644
2754
  exports.Set("types", types);
2645
2755
 
2646
- RegisterPrimitiveType(env, types, {"void"}, PrimitiveKind::Void, 0, 0);
2647
- RegisterPrimitiveType(env, types, {"bool"}, PrimitiveKind::Bool, K_SIZE(bool), alignof(bool));
2648
- RegisterPrimitiveType(env, types, {"int8_t", "int8"}, PrimitiveKind::Int8, 1, 1);
2649
- RegisterPrimitiveType(env, types, {"uint8_t", "uint8"}, PrimitiveKind::UInt8, 1, 1);
2650
- RegisterPrimitiveType(env, types, {"char"}, PrimitiveKind::Int8, 1, 1);
2651
- RegisterPrimitiveType(env, types, {"unsigned char", "uchar"}, PrimitiveKind::UInt8, 1, 1);
2652
- RegisterPrimitiveType(env, types, {"char16_t", "char16"}, PrimitiveKind::Int16, 2, 2);
2653
- RegisterPrimitiveType(env, types, {"char32_t", "char32"}, PrimitiveKind::Int32, 4, 4);
2756
+ RegisterPrimitiveType(instance, types, {"void"}, PrimitiveKind::Void, 0, 0);
2757
+ RegisterPrimitiveType(instance, types, {"bool"}, PrimitiveKind::Bool, K_SIZE(bool), alignof(bool));
2758
+ RegisterPrimitiveType(instance, types, {"int8_t", "int8"}, PrimitiveKind::Int8, 1, 1);
2759
+ RegisterPrimitiveType(instance, types, {"uint8_t", "uint8"}, PrimitiveKind::UInt8, 1, 1);
2760
+ RegisterPrimitiveType(instance, types, {"char"}, PrimitiveKind::Int8, 1, 1);
2761
+ RegisterPrimitiveType(instance, types, {"unsigned char", "uchar"}, PrimitiveKind::UInt8, 1, 1);
2762
+ RegisterPrimitiveType(instance, types, {"char16_t", "char16"}, PrimitiveKind::Int16, 2, 2);
2763
+ RegisterPrimitiveType(instance, types, {"char32_t", "char32"}, PrimitiveKind::Int32, 4, 4);
2654
2764
  if (K_SIZE(wchar_t) == 2) {
2655
- RegisterPrimitiveType(env, types, {"wchar_t", "wchar"}, PrimitiveKind::Int16, 2, 2);
2765
+ RegisterPrimitiveType(instance, types, {"wchar_t", "wchar"}, PrimitiveKind::Int16, 2, 2);
2656
2766
  } else if (K_SIZE(wchar_t) == 4) {
2657
- RegisterPrimitiveType(env, types, {"wchar_t", "wchar"}, PrimitiveKind::Int32, 4, 4);
2658
- }
2659
- RegisterPrimitiveType(env, types, {"int16_t", "int16"}, PrimitiveKind::Int16, 2, 2);
2660
- RegisterPrimitiveType(env, types, {"int16_le_t", "int16_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int16), 2, 2);
2661
- RegisterPrimitiveType(env, types, {"int16_be_t", "int16_be"}, GetBigEndianPrimitive(PrimitiveKind::Int16), 2, 2);
2662
- RegisterPrimitiveType(env, types, {"uint16_t", "uint16"}, PrimitiveKind::UInt16, 2, 2);
2663
- RegisterPrimitiveType(env, types, {"uint16_le_t", "uint16_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt16), 2, 2);
2664
- RegisterPrimitiveType(env, types, {"uint16_be_t", "uint16_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt16), 2, 2);
2665
- RegisterPrimitiveType(env, types, {"short"}, PrimitiveKind::Int16, 2, 2);
2666
- RegisterPrimitiveType(env, types, {"unsigned short", "ushort"}, PrimitiveKind::UInt16, 2, 2);
2667
- RegisterPrimitiveType(env, types, {"int32_t", "int32"}, PrimitiveKind::Int32, 4, 4);
2668
- RegisterPrimitiveType(env, types, {"int32_le_t", "int32_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int32), 4, 4);
2669
- RegisterPrimitiveType(env, types, {"int32_be_t", "int32_be"}, GetBigEndianPrimitive(PrimitiveKind::Int32), 4, 4);
2670
- RegisterPrimitiveType(env, types, {"uint32_t", "uint32"}, PrimitiveKind::UInt32, 4, 4);
2671
- RegisterPrimitiveType(env, types, {"uint32_le_t", "uint32_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt32), 4, 4);
2672
- RegisterPrimitiveType(env, types, {"uint32_be_t", "uint32_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt32), 4, 4);
2673
- RegisterPrimitiveType(env, types, {"int"}, PrimitiveKind::Int32, 4, 4);
2674
- RegisterPrimitiveType(env, types, {"unsigned int", "uint"}, PrimitiveKind::UInt32, 4, 4);
2675
- RegisterPrimitiveType(env, types, {"int64_t", "int64"}, PrimitiveKind::Int64, 8, alignof(int64_t));
2676
- RegisterPrimitiveType(env, types, {"int64_le_t", "int64_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int64), 8, alignof(int64_t));
2677
- RegisterPrimitiveType(env, types, {"int64_be_t", "int64_be"}, GetBigEndianPrimitive(PrimitiveKind::Int64), 8, alignof(int64_t));
2678
- RegisterPrimitiveType(env, types, {"uint64_t", "uint64"}, PrimitiveKind::UInt64, 8, alignof(int64_t));
2679
- RegisterPrimitiveType(env, types, {"uint64_le_t", "uint64_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt64), 8, alignof(int64_t));
2680
- RegisterPrimitiveType(env, types, {"uint64_be_t", "uint64_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt64), 8, alignof(int64_t));
2681
- RegisterPrimitiveType(env, types, {"intptr_t", "intptr"}, GetSignPrimitive(K_SIZE(intptr_t), true), K_SIZE(intptr_t), alignof(intptr_t));
2682
- RegisterPrimitiveType(env, types, {"uintptr_t", "uintptr"}, GetSignPrimitive(K_SIZE(intptr_t), false), K_SIZE(intptr_t), alignof(intptr_t));
2683
- RegisterPrimitiveType(env, types, {"size_t"}, GetSignPrimitive(K_SIZE(size_t), false), K_SIZE(size_t), alignof(size_t));
2684
- RegisterPrimitiveType(env, types, {"long"}, GetSignPrimitive(K_SIZE(long), true), K_SIZE(long), alignof(long));
2685
- RegisterPrimitiveType(env, types, {"unsigned long", "ulong"}, GetSignPrimitive(K_SIZE(long), false), K_SIZE(long), alignof(long));
2686
- RegisterPrimitiveType(env, types, {"long long", "longlong"}, PrimitiveKind::Int64, K_SIZE(int64_t), alignof(int64_t));
2687
- RegisterPrimitiveType(env, types, {"unsigned long long", "ulonglong"}, PrimitiveKind::UInt64, K_SIZE(uint64_t), alignof(uint64_t));
2688
- RegisterPrimitiveType(env, types, {"float", "float32"}, PrimitiveKind::Float32, 4, alignof(float));
2689
- RegisterPrimitiveType(env, types, {"double", "float64"}, PrimitiveKind::Float64, 8, alignof(double));
2690
- RegisterPrimitiveType(env, types, {"char *", "str", "string"}, PrimitiveKind::String, K_SIZE(void *), alignof(void *), "char");
2691
- RegisterPrimitiveType(env, types, {"char16_t *", "char16 *", "str16", "string16"}, PrimitiveKind::String16, K_SIZE(void *), alignof(void *), "char16_t");
2692
- RegisterPrimitiveType(env, types, {"char32_t *", "char32 *", "str32", "string32"}, PrimitiveKind::String32, K_SIZE(void *), alignof(void *), "char32_t");
2767
+ RegisterPrimitiveType(instance, types, {"wchar_t", "wchar"}, PrimitiveKind::Int32, 4, 4);
2768
+ }
2769
+ RegisterPrimitiveType(instance, types, {"int16_t", "int16"}, PrimitiveKind::Int16, 2, 2);
2770
+ RegisterPrimitiveType(instance, types, {"int16_le_t", "int16_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int16), 2, 2);
2771
+ RegisterPrimitiveType(instance, types, {"int16_be_t", "int16_be"}, GetBigEndianPrimitive(PrimitiveKind::Int16), 2, 2);
2772
+ RegisterPrimitiveType(instance, types, {"uint16_t", "uint16"}, PrimitiveKind::UInt16, 2, 2);
2773
+ RegisterPrimitiveType(instance, types, {"uint16_le_t", "uint16_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt16), 2, 2);
2774
+ RegisterPrimitiveType(instance, types, {"uint16_be_t", "uint16_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt16), 2, 2);
2775
+ RegisterPrimitiveType(instance, types, {"short"}, PrimitiveKind::Int16, 2, 2);
2776
+ RegisterPrimitiveType(instance, types, {"unsigned short", "ushort"}, PrimitiveKind::UInt16, 2, 2);
2777
+ RegisterPrimitiveType(instance, types, {"int32_t", "int32"}, PrimitiveKind::Int32, 4, 4);
2778
+ RegisterPrimitiveType(instance, types, {"int32_le_t", "int32_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int32), 4, 4);
2779
+ RegisterPrimitiveType(instance, types, {"int32_be_t", "int32_be"}, GetBigEndianPrimitive(PrimitiveKind::Int32), 4, 4);
2780
+ RegisterPrimitiveType(instance, types, {"uint32_t", "uint32"}, PrimitiveKind::UInt32, 4, 4);
2781
+ RegisterPrimitiveType(instance, types, {"uint32_le_t", "uint32_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt32), 4, 4);
2782
+ RegisterPrimitiveType(instance, types, {"uint32_be_t", "uint32_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt32), 4, 4);
2783
+ RegisterPrimitiveType(instance, types, {"int"}, PrimitiveKind::Int32, 4, 4);
2784
+ RegisterPrimitiveType(instance, types, {"unsigned int", "uint"}, PrimitiveKind::UInt32, 4, 4);
2785
+ RegisterPrimitiveType(instance, types, {"int64_t", "int64"}, PrimitiveKind::Int64, 8, alignof(int64_t));
2786
+ RegisterPrimitiveType(instance, types, {"int64_le_t", "int64_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int64), 8, alignof(int64_t));
2787
+ RegisterPrimitiveType(instance, types, {"int64_be_t", "int64_be"}, GetBigEndianPrimitive(PrimitiveKind::Int64), 8, alignof(int64_t));
2788
+ RegisterPrimitiveType(instance, types, {"uint64_t", "uint64"}, PrimitiveKind::UInt64, 8, alignof(int64_t));
2789
+ RegisterPrimitiveType(instance, types, {"uint64_le_t", "uint64_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt64), 8, alignof(int64_t));
2790
+ RegisterPrimitiveType(instance, types, {"uint64_be_t", "uint64_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt64), 8, alignof(int64_t));
2791
+ RegisterPrimitiveType(instance, types, {"intptr_t", "intptr"}, GetSignPrimitive(K_SIZE(intptr_t), true), K_SIZE(intptr_t), alignof(intptr_t));
2792
+ RegisterPrimitiveType(instance, types, {"uintptr_t", "uintptr"}, GetSignPrimitive(K_SIZE(intptr_t), false), K_SIZE(intptr_t), alignof(intptr_t));
2793
+ RegisterPrimitiveType(instance, types, {"size_t"}, GetSignPrimitive(K_SIZE(size_t), false), K_SIZE(size_t), alignof(size_t));
2794
+ RegisterPrimitiveType(instance, types, {"long"}, GetSignPrimitive(K_SIZE(long), true), K_SIZE(long), alignof(long));
2795
+ RegisterPrimitiveType(instance, types, {"unsigned long", "ulong"}, GetSignPrimitive(K_SIZE(long), false), K_SIZE(long), alignof(long));
2796
+ RegisterPrimitiveType(instance, types, {"long long", "longlong"}, PrimitiveKind::Int64, K_SIZE(int64_t), alignof(int64_t));
2797
+ RegisterPrimitiveType(instance, types, {"unsigned long long", "ulonglong"}, PrimitiveKind::UInt64, K_SIZE(uint64_t), alignof(uint64_t));
2798
+ RegisterPrimitiveType(instance, types, {"float", "float32"}, PrimitiveKind::Float32, 4, alignof(float));
2799
+ RegisterPrimitiveType(instance, types, {"double", "float64"}, PrimitiveKind::Float64, 8, alignof(double));
2800
+ RegisterPrimitiveType(instance, types, {"char *", "str", "string"}, PrimitiveKind::String, K_SIZE(void *), alignof(void *), "char");
2801
+ RegisterPrimitiveType(instance, types, {"char16_t *", "char16 *", "str16", "string16"}, PrimitiveKind::String16, K_SIZE(void *), alignof(void *), "char16_t");
2802
+ RegisterPrimitiveType(instance, types, {"char32_t *", "char32 *", "str32", "string32"}, PrimitiveKind::String32, K_SIZE(void *), alignof(void *), "char32_t");
2693
2803
  if (K_SIZE(wchar_t) == 2) {
2694
- RegisterPrimitiveType(env, types, {"wchar_t *", "wchar *"}, PrimitiveKind::String16, K_SIZE(void *), alignof(void *), "wchar_t");
2804
+ RegisterPrimitiveType(instance, types, {"wchar_t *", "wchar *"}, PrimitiveKind::String16, K_SIZE(void *), alignof(void *), "wchar_t");
2695
2805
  } else if (K_SIZE(wchar_t) == 4) {
2696
- RegisterPrimitiveType(env, types, {"wchar_t *", "wchar *"}, PrimitiveKind::String32, K_SIZE(void *), alignof(void *), "wchar_t");
2806
+ RegisterPrimitiveType(instance, types, {"wchar_t *", "wchar *"}, PrimitiveKind::String32, K_SIZE(void *), alignof(void *), "wchar_t");
2697
2807
  }
2698
2808
 
2699
2809
  instance->void_type = instance->types_map.FindValue("void", nullptr);
@@ -2714,7 +2824,7 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
2714
2824
 
2715
2825
  node.Set("env", WrapPointer(env, instance->void_type, (napi_env)env));
2716
2826
 
2717
- node.Set("poll", Napi::Function::New(env, &Poll, "poll"));
2827
+ node.Set("poll", Napi::Function::New(env, &Poll, "poll", instance));
2718
2828
  node.Set("PollHandle", instance->construct_poll.Value());
2719
2829
  }
2720
2830