koffi 3.0.0 → 3.0.1

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.
@@ -17,6 +17,8 @@ const napi_type_tag DirectionMarker = { 0xf9c306238b480580, 0xc2e168524a0823f5 }
17
17
  const napi_type_tag UnionValueMarker = { 0x5eaf2245526a4c7d, 0x8c86c9ee2b96ffc8 };
18
18
  const napi_type_tag CastMarker = { 0x77f459614a0a412f, 0x80b3dda1341dc8df };
19
19
 
20
+ #if !defined(EXTERNAL_TYPES)
21
+
20
22
  Napi::Function TypeObject::InitClass(Napi::Env env)
21
23
  {
22
24
  Napi::Function constructor = DefineClass(env, "TypeObject", {});
@@ -43,6 +45,8 @@ void TypeObject::Finalize(Napi::BasicEnv env)
43
45
  SuppressDestruct();
44
46
  }
45
47
 
48
+ #endif
49
+
46
50
  Napi::Function UnionValue::InitClass(Napi::Env env, const TypeInfo *type)
47
51
  {
48
52
  K_ASSERT(type->primitive == PrimitiveKind::Union);
@@ -104,7 +108,7 @@ Napi::Value UnionValue::Getter(const Napi::CallbackInfo &info)
104
108
  Size idx = (Size)info.Data();
105
109
  const RecordMember &member = type->members[idx];
106
110
 
107
- Napi::Value value;
111
+ napi_value value = nullptr;
108
112
 
109
113
  if (idx == active_idx) {
110
114
  value = Value().Get(instance->active_symbol.Value());
@@ -116,14 +120,14 @@ Napi::Value UnionValue::Getter(const Napi::CallbackInfo &info)
116
120
  return env.Null();
117
121
  }
118
122
 
119
- value = Decode(env, raw.ptr, member.type);
123
+ value = Decode(instance, raw.ptr, member.type);
120
124
 
121
125
  Value().Set(instance->active_symbol.Value(), value);
122
126
  active_idx = idx;
123
127
  }
124
128
 
125
- K_ASSERT(!value.IsEmpty());
126
- return value;
129
+ K_ASSERT(value);
130
+ return Napi::Value(info.Env(), value);
127
131
  }
128
132
 
129
133
  void UnionValue::Setter(const Napi::CallbackInfo &info, const Napi::Value &value)
@@ -240,6 +244,16 @@ const TypeInfo *ResolveType(Napi::Value value, int *out_directions)
240
244
  }
241
245
 
242
246
  return type;
247
+ #if defined(EXTERNAL_TYPES)
248
+ } else if (kind == napi_external && CheckValueTag(env, value, &TypeObjectMarker)) {
249
+ Napi::External<TypeInfo> external = Napi::External<TypeInfo>(env, value);
250
+ const TypeInfo *type = external.Data();
251
+
252
+ if (out_directions) {
253
+ *out_directions = 1;
254
+ }
255
+ return type;
256
+ #else
243
257
  } else if (kind == napi_object && CheckValueTag(env, value, &TypeObjectMarker)) {
244
258
  TypeObject *defn = nullptr;
245
259
  napi_unwrap(env, value, (void **)&defn);
@@ -248,6 +262,7 @@ const TypeInfo *ResolveType(Napi::Value value, int *out_directions)
248
262
  *out_directions = 1;
249
263
  }
250
264
  return defn->GetType();
265
+ #endif
251
266
  } else {
252
267
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value as type specifier, expected string or type", GetValueType(instance, value));
253
268
  return nullptr;
@@ -513,14 +528,18 @@ TypeInfo *MakeArrayType(InstanceData *instance, const TypeInfo *ref, Size len, A
513
528
  return MakeArrayType(instance, ref, len, hint, false);
514
529
  }
515
530
 
516
- Napi::Object WrapType(Napi::Env env, const TypeInfo *type, bool freeze)
531
+ Napi::Value WrapType(Napi::Env env, const TypeInfo *type, bool freeze)
517
532
  {
518
533
  if (type->defn.IsEmpty()) {
534
+ #if defined(EXTERNAL_TYPES)
535
+ Napi::Object defn = Napi::Object::New(env);
536
+ #else
519
537
  InstanceData *instance = env.GetInstanceData<InstanceData>();
520
538
 
521
539
  Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, (TypeInfo *)type);
522
540
  Napi::Object defn = instance->construct_type.New({ external });
523
541
  SetValueTag(env, defn, &TypeObjectMarker);
542
+ #endif
524
543
 
525
544
  defn.Set("name", Napi::String::New(env, type->name));
526
545
  defn.Set("primitive", PrimitiveKindNames[(int)type->primitive]);
@@ -592,7 +611,14 @@ Napi::Object WrapType(Napi::Env env, const TypeInfo *type, bool freeze)
592
611
  }
593
612
  }
594
613
 
614
+ #if defined(EXTERNAL_TYPES)
615
+ Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, (TypeInfo *)type);
616
+ SetValueTag(env, external, &TypeObjectMarker);
617
+
618
+ return external;
619
+ #else
595
620
  return type->defn.Value();
621
+ #endif
596
622
  }
597
623
 
598
624
  const TypeInfo *ReshapeType(InstanceData *instance, const TypeInfo *type, int32_t stride, uint16_t flags)
@@ -868,23 +894,6 @@ Napi::String MakeStringFromUTF32(Napi::Env env, const char32_t *ptr, Size len)
868
894
  return str;
869
895
  }
870
896
 
871
- Napi::Object DecodeObject(Napi::Env env, const uint8_t *origin, const TypeInfo *type)
872
- {
873
- // We can't decode unions because we don't know which member is valid
874
- if (type->primitive == PrimitiveKind::Union) {
875
- Napi::External<void> external = Napi::External<void>::New(env, (void *)origin);
876
- Napi::Object wrapper = type->construct.New({ external }).As<Napi::Object>();
877
- SetValueTag(env, wrapper, &UnionValueMarker);
878
-
879
- return wrapper;
880
- }
881
-
882
- Napi::Object obj = Napi::Object::New(env);
883
- DecodeObject(env, obj, origin, type);
884
-
885
- return obj;
886
- }
887
-
888
897
  static uint32_t DecodeDynamicLength(const uint8_t *origin, const RecordMember &by)
889
898
  {
890
899
  const uint8_t *src = origin + by.offset;
@@ -977,27 +986,16 @@ static uint32_t DecodeDynamicLength(const uint8_t *origin, const RecordMember &b
977
986
  K_UNREACHABLE();
978
987
  }
979
988
 
980
- static inline void SetMemberValue(napi_env env, napi_value obj, const RecordMember &member, napi_value value)
981
- {
982
- if (member.key) {
983
- napi_value key = nullptr;
984
- napi_get_reference_value(env, member.key, &key);
985
-
986
- napi_status status = napi_set_property(env, obj, key, value);
987
- K_ASSERT(status == napi_ok);
988
- } else {
989
- napi_status status = napi_set_named_property(env, obj, member.name, value);
990
- K_ASSERT(status == napi_ok);
991
- }
992
- }
993
-
994
- void DecodeObject(Napi::Env env, napi_value obj, const uint8_t *origin, const TypeInfo *type)
989
+ template <typename SetFunc>
990
+ static FORCE_INLINE void DecodeObject(InstanceData *instance, const uint8_t *origin, const TypeInfo *type, SetFunc set)
995
991
  {
996
992
  K_ASSERT(type->primitive == PrimitiveKind::Record);
997
993
 
994
+ Napi::Env env = instance->env;
998
995
  Span<const RecordMember> members = type->members;
999
996
 
1000
- for (const RecordMember &member: members) {
997
+ for (Size i = 0; i < members.len; i++) {
998
+ const RecordMember &member = members[i];
1001
999
  const uint8_t *src = origin + member.offset;
1002
1000
 
1003
1001
  switch (member.type->primitive) {
@@ -1005,80 +1003,80 @@ void DecodeObject(Napi::Env env, napi_value obj, const uint8_t *origin, const Ty
1005
1003
 
1006
1004
  case PrimitiveKind::Bool: {
1007
1005
  bool b = *(bool *)src;
1008
- SetMemberValue(env, obj, member, Napi::Boolean::New(env, b));
1006
+ set(i, member, Napi::Boolean::New(env, b));
1009
1007
  } break;
1010
1008
  case PrimitiveKind::Int8: {
1011
- int8_t i = *(int8_t *)src;
1012
- SetMemberValue(env, obj, member, NewInt(env, i));
1009
+ int8_t v = *(int8_t *)src;
1010
+ set(i, member, NewInt(env, v));
1013
1011
  } break;
1014
1012
  case PrimitiveKind::UInt8: {
1015
- uint8_t u = *(uint8_t *)src;
1016
- SetMemberValue(env, obj, member, NewInt(env, u));
1013
+ uint8_t v = *(uint8_t *)src;
1014
+ set(i, member, NewInt(env, v));
1017
1015
  } break;
1018
1016
  case PrimitiveKind::Int16: {
1019
- int16_t i;
1020
- memcpy(&i, src, 2);
1021
- SetMemberValue(env, obj, member, NewInt(env, i));
1017
+ int16_t v;
1018
+ memcpy(&v, src, 2);
1019
+ set(i, member, NewInt(env, v));
1022
1020
  } break;
1023
1021
  case PrimitiveKind::Int16S: {
1024
- int16_t i;
1025
- memcpy(&i, src, 2);
1026
- SetMemberValue(env, obj, member, NewInt(env, ReverseBytes(i)));
1022
+ int16_t v;
1023
+ memcpy(&v, src, 2);
1024
+ set(i, member, NewInt(env, ReverseBytes(v)));
1027
1025
  } break;
1028
1026
  case PrimitiveKind::UInt16: {
1029
- uint16_t u;
1030
- memcpy(&u, src, 2);
1031
- SetMemberValue(env, obj, member, NewInt(env, u));
1027
+ uint16_t v;
1028
+ memcpy(&v, src, 2);
1029
+ set(i, member, NewInt(env, v));
1032
1030
  } break;
1033
1031
  case PrimitiveKind::UInt16S: {
1034
- uint16_t u;
1035
- memcpy(&u, src, 2);
1036
- SetMemberValue(env, obj, member, NewInt(env, ReverseBytes(u)));
1032
+ uint16_t v;
1033
+ memcpy(&v, src, 2);
1034
+ set(i, member, NewInt(env, ReverseBytes(v)));
1037
1035
  } break;
1038
1036
  case PrimitiveKind::Int32: {
1039
- int32_t i;
1040
- memcpy(&i, src, 4);
1041
- SetMemberValue(env, obj, member, NewInt(env, i));
1037
+ int32_t v;
1038
+ memcpy(&v, src, 4);
1039
+ set(i, member, NewInt(env, v));
1042
1040
  } break;
1043
1041
  case PrimitiveKind::Int32S: {
1044
- int32_t i;
1045
- memcpy(&i, src, 4);
1046
- SetMemberValue(env, obj, member, NewInt(env, ReverseBytes(i)));
1042
+ int32_t v;
1043
+ memcpy(&v, src, 4);
1044
+ set(i, member, NewInt(env, ReverseBytes(v)));
1047
1045
  } break;
1048
1046
  case PrimitiveKind::UInt32: {
1049
- uint32_t u;
1050
- memcpy(&u, src, 4);
1051
- SetMemberValue(env, obj, member, NewInt(env, u));
1047
+ uint32_t v;
1048
+ memcpy(&v, src, 4);
1049
+ set(i, member, NewInt(env, v));
1052
1050
  } break;
1053
1051
  case PrimitiveKind::UInt32S: {
1054
- uint32_t u;
1055
- memcpy(&u, src, 4);
1056
- SetMemberValue(env, obj, member, NewInt(env, ReverseBytes(u)));
1052
+ uint32_t v;
1053
+ memcpy(&v, src, 4);
1054
+ set(i, member, NewInt(env, ReverseBytes(v)));
1057
1055
  } break;
1058
1056
  case PrimitiveKind::Int64: {
1059
- int64_t i;
1060
- memcpy(&i, src, 8);
1061
- SetMemberValue(env, obj, member, NewInt(env, i));
1057
+ int64_t v;
1058
+ memcpy(&v, src, 8);
1059
+ set(i, member, NewInt(env, v));
1062
1060
  } break;
1063
1061
  case PrimitiveKind::Int64S: {
1064
- int64_t i;
1065
- memcpy(&i, src, 8);
1066
- SetMemberValue(env, obj, member, NewInt(env, ReverseBytes(i)));
1062
+ int64_t v;
1063
+ memcpy(&v, src, 8);
1064
+ set(i, member, NewInt(env, ReverseBytes(v)));
1067
1065
  } break;
1068
1066
  case PrimitiveKind::UInt64: {
1069
- uint64_t u;
1070
- memcpy(&u, src, 8);
1071
- SetMemberValue(env, obj, member, NewInt(env, u));
1067
+ uint64_t v;
1068
+ memcpy(&v, src, 8);
1069
+ set(i, member, NewInt(env, v));
1072
1070
  } break;
1073
1071
  case PrimitiveKind::UInt64S: {
1074
- uint64_t u;
1075
- memcpy(&u, src, 8);
1076
- SetMemberValue(env, obj, member, NewInt(env, ReverseBytes(u)));
1072
+ uint64_t v;
1073
+ memcpy(&v, src, 8);
1074
+ set(i, member, NewInt(env, ReverseBytes(v)));
1077
1075
  } break;
1078
1076
  case PrimitiveKind::String: {
1079
1077
  const char *str;
1080
1078
  memcpy(&str, src, K_SIZE(void *));
1081
- SetMemberValue(env, obj, member, str ? Napi::String::New(env, str) : env.Null());
1079
+ set(i, member, str ? Napi::String::New(env, str) : env.Null());
1082
1080
 
1083
1081
  if (member.type->dispose) {
1084
1082
  member.type->dispose(env, member.type, str);
@@ -1087,7 +1085,7 @@ void DecodeObject(Napi::Env env, napi_value obj, const uint8_t *origin, const Ty
1087
1085
  case PrimitiveKind::String16: {
1088
1086
  const char16_t *str16;
1089
1087
  memcpy(&str16, src, K_SIZE(void *));
1090
- SetMemberValue(env, obj, member, str16 ? Napi::String::New(env, str16) : env.Null());
1088
+ set(i, member, str16 ? Napi::String::New(env, str16) : env.Null());
1091
1089
 
1092
1090
  if (member.type->dispose) {
1093
1091
  member.type->dispose(env, member.type, str16);
@@ -1096,7 +1094,7 @@ void DecodeObject(Napi::Env env, napi_value obj, const uint8_t *origin, const Ty
1096
1094
  case PrimitiveKind::String32: {
1097
1095
  const char32_t *str32;
1098
1096
  memcpy(&str32, src, K_SIZE(void *));
1099
- SetMemberValue(env, obj, member, str32 ? MakeStringFromUTF32(env, str32) : env.Null());
1097
+ set(i, member, str32 ? MakeStringFromUTF32(env, str32) : env.Null());
1100
1098
  } break;
1101
1099
  case PrimitiveKind::Pointer: {
1102
1100
  void *ptr2;
@@ -1106,11 +1104,11 @@ void DecodeObject(Napi::Env env, napi_value obj, const uint8_t *origin, const Ty
1106
1104
  const RecordMember &by = members[member.countedby];
1107
1105
  uint32_t len = DecodeDynamicLength(origin, by);
1108
1106
 
1109
- Napi::Value value = DecodeArray(env, (const uint8_t *)ptr2, member.type, len);
1110
- SetMemberValue(env, obj, member, value);
1107
+ napi_value value = DecodeArray(instance, (const uint8_t *)ptr2, member.type, len);
1108
+ set(i, member, value);
1111
1109
  } else {
1112
- Napi::Value p = ptr2 ? WrapPointer(env, member.type->ref.type, ptr2) : env.Null();
1113
- SetMemberValue(env, obj, member, p);
1110
+ napi_value p = ptr2 ? WrapPointer(env, member.type->ref.type, ptr2) : env.Null();
1111
+ set(i, member, p);
1114
1112
  }
1115
1113
 
1116
1114
  if (member.type->dispose) {
@@ -1121,8 +1119,8 @@ void DecodeObject(Napi::Env env, napi_value obj, const uint8_t *origin, const Ty
1121
1119
  void *ptr2;
1122
1120
  memcpy(&ptr2, src, K_SIZE(void *));
1123
1121
 
1124
- Napi::Value p = ptr2 ? WrapPointer(env, member.type->ref.type, ptr2) : env.Null();
1125
- SetMemberValue(env, obj, member, p);
1122
+ napi_value p = ptr2 ? WrapPointer(env, member.type->ref.type, ptr2) : env.Null();
1123
+ set(i, member, p);
1126
1124
 
1127
1125
  if (member.type->dispose) {
1128
1126
  member.type->dispose(env, member.type, ptr2);
@@ -1130,8 +1128,8 @@ void DecodeObject(Napi::Env env, napi_value obj, const uint8_t *origin, const Ty
1130
1128
  } break;
1131
1129
  case PrimitiveKind::Record:
1132
1130
  case PrimitiveKind::Union: {
1133
- Napi::Object obj2 = DecodeObject(env, src, member.type);
1134
- SetMemberValue(env, obj, member, obj2);
1131
+ napi_value obj2 = DecodeObject(instance, src, member.type);
1132
+ set(i, member, obj2);
1135
1133
  } break;
1136
1134
  case PrimitiveKind::Array: {
1137
1135
  if (member.countedby >= 0) {
@@ -1143,22 +1141,22 @@ void DecodeObject(Napi::Env env, napi_value obj, const uint8_t *origin, const Ty
1143
1141
  // Silently truncate result
1144
1142
  len = std::min(len, max);
1145
1143
 
1146
- Napi::Value value = DecodeArray(env, src, member.type, len);
1147
- SetMemberValue(env, obj, member, value);
1144
+ napi_value value = DecodeArray(instance, src, member.type, len);
1145
+ set(i, member, value);
1148
1146
  } else {
1149
- Napi::Value value = DecodeArray(env, src, member.type);
1150
- SetMemberValue(env, obj, member, value);
1147
+ napi_value value = DecodeArray(instance, src, member.type);
1148
+ set(i, member, value);
1151
1149
  }
1152
1150
  } break;
1153
1151
  case PrimitiveKind::Float32: {
1154
1152
  float f;
1155
1153
  memcpy(&f, src, 4);
1156
- SetMemberValue(env, obj, member, Napi::Number::New(env, (double)f));
1154
+ set(i, member, Napi::Number::New(env, (double)f));
1157
1155
  } break;
1158
1156
  case PrimitiveKind::Float64: {
1159
1157
  double d;
1160
1158
  memcpy(&d, src, 8);
1161
- SetMemberValue(env, obj, member, Napi::Number::New(env, d));
1159
+ set(i, member, Napi::Number::New(env, d));
1162
1160
  } break;
1163
1161
 
1164
1162
  case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
@@ -1166,18 +1164,77 @@ void DecodeObject(Napi::Env env, napi_value obj, const uint8_t *origin, const Ty
1166
1164
  }
1167
1165
  }
1168
1166
 
1169
- Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *type)
1167
+ napi_value DecodeObject(InstanceData *instance, const uint8_t *origin, const TypeInfo *type)
1168
+ {
1169
+ Napi::Env env = instance->env;
1170
+
1171
+ // We can't decode unions because we don't know which member is valid
1172
+ if (type->primitive == PrimitiveKind::Union) {
1173
+ Napi::External<void> external = Napi::External<void>::New(env, (void *)origin);
1174
+ Napi::Object wrapper = type->construct.New({ external }).As<Napi::Object>();
1175
+ SetValueTag(env, wrapper, &UnionValueMarker);
1176
+
1177
+ return wrapper;
1178
+ }
1179
+
1180
+ // Only supported in recent Node versions, and still experimental at this time
1181
+ if (node_api_create_object_with_properties && type->members.len <= 256) {
1182
+ napi_value properties[256];
1183
+ napi_value values[256];
1184
+
1185
+ DecodeObject(instance, origin, type, [&](Size i, const RecordMember &member, napi_value value) {
1186
+ napi_status status = napi_get_reference_value(env, member.key, &properties[i]);
1187
+ K_ASSERT(status == napi_ok);
1188
+
1189
+ values[i] = value;
1190
+ });
1191
+
1192
+ napi_value obj;
1193
+ napi_status status = node_api_create_object_with_properties(env, instance->object_constructor.Value(), properties, values, type->members.len, &obj);
1194
+ K_ASSERT(status == napi_ok);
1195
+
1196
+ return obj;
1197
+ }
1198
+
1199
+ Napi::Object obj = Napi::Object::New(env);
1200
+ DecodeObject(instance, obj, origin, type);
1201
+
1202
+ return obj;
1203
+ }
1204
+
1205
+ void DecodeObject(InstanceData *instance, napi_value obj, const uint8_t *origin, const TypeInfo *type)
1206
+ {
1207
+ Napi::Env env = instance->env;
1208
+
1209
+ if (node_api_create_property_key_utf8) {
1210
+ DecodeObject(instance, origin, type, [&](Size i, const RecordMember &member, napi_value value) {
1211
+ napi_value key = nullptr;
1212
+ napi_get_reference_value(env, member.key, &key);
1213
+
1214
+ napi_status status = napi_set_property(env, obj, key, value);
1215
+ K_ASSERT(status == napi_ok);
1216
+ });
1217
+ } else {
1218
+ DecodeObject(instance, origin, type, [&](Size i, const RecordMember &member, napi_value value) {
1219
+ napi_status status = napi_set_named_property(env, obj, member.name, value);
1220
+ K_ASSERT(status == napi_ok);
1221
+ });
1222
+ }
1223
+ }
1224
+
1225
+ napi_value DecodeArray(InstanceData *instance, const uint8_t *origin, const TypeInfo *type)
1170
1226
  {
1171
1227
  K_ASSERT(type->primitive == PrimitiveKind::Array);
1172
1228
 
1173
1229
  uint32_t len = type->size / type->ref.stride;
1174
- return DecodeArray(env, origin, type, len);
1230
+ return DecodeArray(instance, origin, type, len);
1175
1231
  }
1176
1232
 
1177
- Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *type, uint32_t len)
1233
+ napi_value DecodeArray(InstanceData *instance, const uint8_t *origin, const TypeInfo *type, uint32_t len)
1178
1234
  {
1179
1235
  K_ASSERT(type->primitive == PrimitiveKind::Array || type->primitive == PrimitiveKind::Pointer);
1180
1236
 
1237
+ Napi::Env env = instance->env;
1181
1238
  const TypeInfo *ref = type->ref.type;
1182
1239
  int32_t stride = type->ref.stride;
1183
1240
 
@@ -1279,7 +1336,7 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
1279
1336
  K_ASSERT(type->hint == ArrayHint::Array);
1280
1337
 
1281
1338
  Napi::Array array = Napi::Array::New(env);
1282
- DecodeElements(env, array, origin, type, len);
1339
+ DecodeElements(instance, array, origin, type, len);
1283
1340
 
1284
1341
  return array;
1285
1342
  }
@@ -1287,10 +1344,11 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
1287
1344
  K_UNREACHABLE();
1288
1345
  }
1289
1346
 
1290
- void DecodeElements(Napi::Env env, napi_value array, const uint8_t *origin, const TypeInfo *type, uint32_t len)
1347
+ void DecodeElements(InstanceData *instance, napi_value array, const uint8_t *origin, const TypeInfo *type, uint32_t len)
1291
1348
  {
1292
- K_ASSERT(IsArray(env, array));
1349
+ K_ASSERT(IsArray(instance->env, array));
1293
1350
 
1351
+ Napi::Env env = instance->env;
1294
1352
  const TypeInfo *ref = type->ref.type;
1295
1353
  int32_t stride = type->ref.stride;
1296
1354
 
@@ -1377,7 +1435,7 @@ void DecodeElements(Napi::Env env, napi_value array, const uint8_t *origin, cons
1377
1435
  POP_ARRAY({
1378
1436
  void *ptr2 = *(void **)src;
1379
1437
 
1380
- Napi::Value p = ptr2 ? WrapPointer(env, ref->ref.type, ptr2) : env.Null();
1438
+ napi_value p = ptr2 ? WrapPointer(env, ref->ref.type, ptr2) : env.Null();
1381
1439
  napi_set_element(env, array, i, p);
1382
1440
 
1383
1441
  if (ref->dispose) {
@@ -1389,7 +1447,7 @@ void DecodeElements(Napi::Env env, napi_value array, const uint8_t *origin, cons
1389
1447
  POP_ARRAY({
1390
1448
  void *ptr2 = *(void **)src;
1391
1449
 
1392
- Napi::Value p = ptr2 ? WrapPointer(env, ref->ref.type, ptr2) : env.Null();
1450
+ napi_value p = ptr2 ? WrapPointer(env, ref->ref.type, ptr2) : env.Null();
1393
1451
  napi_set_element(env, array, i, p);
1394
1452
 
1395
1453
  if (ref->dispose) {
@@ -1400,13 +1458,13 @@ void DecodeElements(Napi::Env env, napi_value array, const uint8_t *origin, cons
1400
1458
  case PrimitiveKind::Record:
1401
1459
  case PrimitiveKind::Union: {
1402
1460
  POP_ARRAY({
1403
- Napi::Object obj = DecodeObject(env, src, ref);
1461
+ napi_value obj = DecodeObject(instance, src, ref);
1404
1462
  napi_set_element(env, array, i, obj);
1405
1463
  });
1406
1464
  } break;
1407
1465
  case PrimitiveKind::Array: {
1408
1466
  POP_ARRAY({
1409
- Napi::Value value = DecodeArray(env, src, ref);
1467
+ napi_value value = DecodeArray(instance, src, ref);
1410
1468
  napi_set_element(env, array, i, value);
1411
1469
  });
1412
1470
  } break;
@@ -1476,7 +1534,7 @@ void DecodeBuffer(Span<uint8_t> buffer, const uint8_t *origin, const TypeInfo *t
1476
1534
  #undef SWAP
1477
1535
  }
1478
1536
 
1479
- Napi::Value Decode(Napi::Value value, Size offset, const TypeInfo *type, const Size *len)
1537
+ napi_value Decode(Napi::Value value, Size offset, const TypeInfo *type, const Size *len)
1480
1538
  {
1481
1539
  Napi::Env env = value.Env();
1482
1540
  InstanceData *instance = env.GetInstanceData<InstanceData>();
@@ -1506,13 +1564,12 @@ Napi::Value Decode(Napi::Value value, Size offset, const TypeInfo *type, const S
1506
1564
  return env.Null();
1507
1565
  src += offset;
1508
1566
 
1509
- Napi::Value ret = Decode(env, src, type, len);
1510
- return ret;
1567
+ return Decode(instance, src, type, len);
1511
1568
  }
1512
1569
 
1513
- Napi::Value Decode(Napi::Env env, const uint8_t *ptr, const TypeInfo *type, const Size *len)
1570
+ napi_value Decode(InstanceData *instance, const uint8_t *ptr, const TypeInfo *type, const Size *len)
1514
1571
  {
1515
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1572
+ Napi::Env env = instance->env;
1516
1573
 
1517
1574
  if (len && type->primitive != PrimitiveKind::String &&
1518
1575
  type->primitive != PrimitiveKind::String16 &&
@@ -1554,12 +1611,12 @@ Napi::Value Decode(Napi::Env env, const uint8_t *ptr, const TypeInfo *type, cons
1554
1611
  #define RETURN_INT(Type, NewCall) \
1555
1612
  do { \
1556
1613
  Type v = *(Type *)ptr; \
1557
- return Napi::Value(env, NewCall(env, v)); \
1614
+ return NewCall(env, v); \
1558
1615
  } while (false)
1559
1616
  #define RETURN_INT_SWAP(Type, NewCall) \
1560
1617
  do { \
1561
1618
  Type v = ReverseBytes(*(Type *)ptr); \
1562
- return Napi::Value(env, NewCall(env, v)); \
1619
+ return NewCall(env, v); \
1563
1620
  } while (false)
1564
1621
 
1565
1622
  switch (type->primitive) {
@@ -1622,12 +1679,9 @@ Napi::Value Decode(Napi::Env env, const uint8_t *ptr, const TypeInfo *type, cons
1622
1679
  return ptr2 ? WrapPointer(env, type->ref.type, ptr2) : env.Null();
1623
1680
  } break;
1624
1681
  case PrimitiveKind::Record:
1625
- case PrimitiveKind::Union: {
1626
- Napi::Object obj = DecodeObject(env, ptr, type);
1627
- return obj;
1628
- } break;
1682
+ case PrimitiveKind::Union: { return DecodeObject(instance, ptr, type); } break;
1629
1683
  case PrimitiveKind::Array: {
1630
- Napi::Value array = DecodeArray(env, ptr, type);
1684
+ napi_value array = DecodeArray(instance, ptr, type);
1631
1685
  return array;
1632
1686
  } break;
1633
1687
  case PrimitiveKind::Float32: {
@@ -1704,12 +1758,12 @@ bool Encode(Napi::Value ref, Size offset, Napi::Value value, const TypeInfo *typ
1704
1758
  }
1705
1759
  dest += offset;
1706
1760
 
1707
- return Encode(env, dest, value, type, len);
1761
+ return Encode(instance, dest, value, type, len);
1708
1762
  }
1709
1763
 
1710
- bool Encode(Napi::Env env, uint8_t *origin, Napi::Value value, const TypeInfo *type, const Size *len)
1764
+ bool Encode(InstanceData *instance, uint8_t *origin, Napi::Value value, const TypeInfo *type, const Size *len)
1711
1765
  {
1712
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1766
+ Napi::Env env = instance->env;
1713
1767
 
1714
1768
  if (len && type->primitive != PrimitiveKind::String &&
1715
1769
  type->primitive != PrimitiveKind::String16 &&
@@ -10,8 +10,6 @@
10
10
 
11
11
  namespace K {
12
12
 
13
- // #define EXTERNAL_POINTERS
14
-
15
13
  #if defined(_MSC_VER)
16
14
  #define FORCE_INLINE __forceinline
17
15
  #else
@@ -40,6 +38,8 @@ extern const napi_type_tag DirectionMarker;
40
38
  extern const napi_type_tag UnionValueMarker;
41
39
  extern const napi_type_tag CastMarker;
42
40
 
41
+ #if !defined(EXTERNAL_TYPES)
42
+
43
43
  class TypeObject: public Napi::ObjectWrap<TypeObject> {
44
44
  const TypeInfo *type;
45
45
 
@@ -55,6 +55,8 @@ public:
55
55
  const TypeInfo *GetType() { return type; }
56
56
  };
57
57
 
58
+ #endif
59
+
58
60
  class UnionValue: public Napi::ObjectWrap<UnionValue> {
59
61
  InstanceData *instance;
60
62
  const TypeInfo *type;
@@ -119,7 +121,7 @@ TypeInfo *MakePointerType(InstanceData *instance, const TypeInfo *ref, int count
119
121
  TypeInfo *MakeArrayType(InstanceData *instance, const TypeInfo *ref, Size len);
120
122
  TypeInfo *MakeArrayType(InstanceData *instance, const TypeInfo *ref, Size len, ArrayHint hint);
121
123
 
122
- Napi::Object WrapType(Napi::Env env, const TypeInfo *type, bool freeze = true);
124
+ Napi::Value WrapType(Napi::Env env, const TypeInfo *type, bool freeze = true);
123
125
 
124
126
  const TypeInfo *ReshapeType(InstanceData *instance, const TypeInfo *type, int32_t stride, uint16_t flags);
125
127
 
@@ -403,19 +405,19 @@ Napi::String MakeStringFromUTF32(Napi::Env env, const char32_t *ptr, Size len);
403
405
  static inline Napi::String MakeStringFromUTF32(Napi::Env env, const char32_t *ptr)
404
406
  { return MakeStringFromUTF32(env, ptr, NullTerminatedLength(ptr)); }
405
407
 
406
- Napi::Object DecodeObject(Napi::Env env, const uint8_t *origin, const TypeInfo *type);
407
- void DecodeObject(Napi::Env env, napi_value obj, const uint8_t *origin, const TypeInfo *type);
408
+ napi_value DecodeObject(InstanceData *instance, const uint8_t *origin, const TypeInfo *type);
409
+ void DecodeObject(InstanceData *instance, napi_value obj, const uint8_t *origin, const TypeInfo *type);
408
410
 
409
- Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *type);
410
- Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *type, uint32_t len);
411
- void DecodeElements(Napi::Env env, napi_value array, const uint8_t *origin, const TypeInfo *type, uint32_t len);
411
+ napi_value DecodeArray(InstanceData *instance, const uint8_t *origin, const TypeInfo *type);
412
+ napi_value DecodeArray(InstanceData *instance, const uint8_t *origin, const TypeInfo *type, uint32_t len);
413
+ void DecodeElements(InstanceData *instance, napi_value array, const uint8_t *origin, const TypeInfo *type, uint32_t len);
412
414
  INLINE_UNITY void DecodeBuffer(Span<uint8_t> buffer, const uint8_t *origin, const TypeInfo *type);
413
415
 
414
- Napi::Value Decode(Napi::Value value, Size offset, const TypeInfo *type, const Size *len = nullptr);
415
- Napi::Value Decode(Napi::Env env, const uint8_t *ptr, const TypeInfo *type, const Size *len = nullptr);
416
+ napi_value Decode(Napi::Value value, Size offset, const TypeInfo *type, const Size *len = nullptr);
417
+ napi_value Decode(InstanceData *instance, const uint8_t *ptr, const TypeInfo *type, const Size *len = nullptr);
416
418
 
417
419
  bool Encode(Napi::Value ref, Size offset, Napi::Value value, const TypeInfo *type, const Size *len = nullptr);
418
- bool Encode(Napi::Env env, uint8_t *ptr, Napi::Value value, const TypeInfo *type, const Size *len = nullptr);
420
+ bool Encode(InstanceData *instance, uint8_t *ptr, Napi::Value value, const TypeInfo *type, const Size *len = nullptr);
419
421
 
420
422
  static FORCE_INLINE napi_value NewInt(Napi::Env env, char i) { napi_value value; napi_create_int32(env, (int32_t)i, &value); return value; }
421
423
  static FORCE_INLINE napi_value NewInt(Napi::Env env, signed char i) { napi_value value; napi_create_int32(env, (int32_t)i, &value); return value; }
@@ -480,9 +482,6 @@ static FORCE_INLINE Napi::Value WrapPointer(Napi::Env env, const TypeInfo *ref,
480
482
  #endif
481
483
  }
482
484
 
483
- Napi::Value INLINE_UNITY WrapPointer(Napi::Env env, const TypeInfo *ref, void *ptr);
484
- Napi::Value INLINE_UNITY WrapPointer(Napi::Env env, const TypeInfo *ref, void *ptr);
485
-
486
485
  bool DetectCallConvention(Span<const char> name, CallConvention *out_convention);
487
486
 
488
487
  int AnalyseFlat(const TypeInfo *type, FunctionRef<void(const TypeInfo *type, int offset, int count)> func);