koffi 2.3.16 → 2.3.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -1
- package/build/2.3.18/koffi_darwin_arm64/koffi.node +0 -0
- package/build/2.3.18/koffi_darwin_x64/koffi.node +0 -0
- package/build/2.3.18/koffi_freebsd_arm64/koffi.node +0 -0
- package/build/2.3.18/koffi_freebsd_ia32/koffi.node +0 -0
- package/build/2.3.18/koffi_freebsd_x64/koffi.node +0 -0
- package/build/2.3.18/koffi_linux_arm32hf/koffi.node +0 -0
- package/build/2.3.18/koffi_linux_arm64/koffi.node +0 -0
- package/build/2.3.18/koffi_linux_ia32/koffi.node +0 -0
- package/build/2.3.18/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/build/2.3.18/koffi_linux_x64/koffi.node +0 -0
- package/build/2.3.18/koffi_openbsd_ia32/koffi.node +0 -0
- package/build/2.3.18/koffi_openbsd_x64/koffi.node +0 -0
- package/build/2.3.18/koffi_win32_arm64/koffi.node +0 -0
- package/build/2.3.18/koffi_win32_ia32/koffi.node +0 -0
- package/build/2.3.18/koffi_win32_x64/koffi.node +0 -0
- package/package.json +2 -2
- package/src/koffi/src/call.cc +121 -24
- package/src/koffi/src/call.hh +13 -0
- package/src/koffi/src/ffi.cc +14 -11
- package/src/koffi/src/ffi.hh +2 -0
- package/src/koffi/src/util.cc +1 -1
- package/src/koffi/src/util.hh +2 -0
- package/vendor/node-addon-api/CHANGELOG.md +41 -0
- package/vendor/node-addon-api/README.md +1 -1
- package/vendor/node-addon-api/doc/array_buffer.md +10 -0
- package/vendor/node-addon-api/doc/buffer.md +97 -0
- package/vendor/node-addon-api/doc/env.md +2 -2
- package/vendor/node-addon-api/doc/external.md +2 -2
- package/vendor/node-addon-api/doc/external_buffer.md +18 -0
- package/vendor/node-addon-api/doc/hierarchy.md +4 -2
- package/vendor/node-addon-api/doc/object.md +2 -29
- package/vendor/node-addon-api/doc/type_taggable.md +40 -0
- package/vendor/node-addon-api/doc/value.md +7 -1
- package/vendor/node-addon-api/napi-inl.h +317 -22
- package/vendor/node-addon-api/napi.h +84 -7
- package/vendor/node-addon-api/package.json +9 -1
- package/vendor/node-addon-api/test/async_progress_worker.cc +15 -3
- package/vendor/node-addon-api/test/binding.cc +4 -2
- package/vendor/node-addon-api/test/binding.gyp +11 -1
- package/vendor/node-addon-api/test/buffer.cc +13 -19
- package/vendor/node-addon-api/test/buffer.h +26 -0
- package/vendor/node-addon-api/test/buffer.js +82 -0
- package/vendor/node-addon-api/test/buffer_new_or_copy-inl.h +68 -0
- package/vendor/node-addon-api/test/buffer_no_external.cc +24 -0
- package/vendor/node-addon-api/test/error.cc +101 -0
- package/vendor/node-addon-api/test/error.js +15 -1
- package/vendor/node-addon-api/test/index.js +1 -1
- package/vendor/node-addon-api/test/object_reference.cc +220 -22
- package/vendor/node-addon-api/test/object_reference.js +83 -80
- package/vendor/node-addon-api/test/objectwrap.cc +23 -3
- package/vendor/node-addon-api/test/objectwrap.js +14 -2
- package/vendor/node-addon-api/test/reference.cc +55 -1
- package/vendor/node-addon-api/test/reference.js +7 -1
- package/vendor/node-addon-api/test/type_taggable.cc +66 -0
- package/vendor/node-addon-api/test/type_taggable.js +60 -0
- package/vendor/node-addon-api/test/value_type_cast.cc +60 -0
- package/vendor/node-addon-api/test/value_type_cast.js +106 -0
- package/vendor/node-addon-api/tools/eslint-format.js +2 -2
- package/build/2.3.16/koffi_darwin_arm64/koffi.node +0 -0
- package/build/2.3.16/koffi_darwin_x64/koffi.node +0 -0
- package/build/2.3.16/koffi_freebsd_arm64/koffi.node +0 -0
- package/build/2.3.16/koffi_freebsd_ia32/koffi.node +0 -0
- package/build/2.3.16/koffi_freebsd_x64/koffi.node +0 -0
- package/build/2.3.16/koffi_linux_arm32hf/koffi.node +0 -0
- package/build/2.3.16/koffi_linux_arm64/koffi.node +0 -0
- package/build/2.3.16/koffi_linux_ia32/koffi.node +0 -0
- package/build/2.3.16/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/build/2.3.16/koffi_linux_x64/koffi.node +0 -0
- package/build/2.3.16/koffi_openbsd_ia32/koffi.node +0 -0
- package/build/2.3.16/koffi_openbsd_x64/koffi.node +0 -0
- package/build/2.3.16/koffi_win32_arm64/koffi.node +0 -0
- package/build/2.3.16/koffi_win32_ia32/koffi.node +0 -0
- package/build/2.3.16/koffi_win32_x64/koffi.node +0 -0
- package/vendor/node-addon-api/test/object/object_type_tag.cc +0 -39
- package/vendor/node-addon-api/test/object/object_type_tag.js +0 -55
- /package/build/{2.3.16 → 2.3.18}/koffi_win32_arm64/koffi.exp +0 -0
- /package/build/{2.3.16 → 2.3.18}/koffi_win32_arm64/koffi.lib +0 -0
- /package/build/{2.3.16 → 2.3.18}/koffi_win32_ia32/koffi.exp +0 -0
- /package/build/{2.3.16 → 2.3.18}/koffi_win32_ia32/koffi.lib +0 -0
- /package/build/{2.3.16 → 2.3.18}/koffi_win32_x64/koffi.exp +0 -0
- /package/build/{2.3.16 → 2.3.18}/koffi_win32_x64/koffi.lib +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
### Koffi 2.3
|
|
6
6
|
|
|
7
|
+
#### Koffi 2.3.18
|
|
8
|
+
|
|
9
|
+
**Main fixes:**
|
|
10
|
+
|
|
11
|
+
- Fix possible crash on exit caused by unregistered callbacks
|
|
12
|
+
|
|
13
|
+
#### Koffi 2.3.17
|
|
14
|
+
|
|
15
|
+
**Main changes:**
|
|
16
|
+
|
|
17
|
+
- Allow strings for input `void *`, `int8_t *` and `int16_t *` pointer arguments
|
|
18
|
+
- Support using `[string]` (single-element string arrays) for polymorphic input/output arguments
|
|
19
|
+
|
|
7
20
|
#### Koffi 2.3.16
|
|
8
21
|
|
|
9
22
|
**Main changes:**
|
|
@@ -13,7 +26,7 @@
|
|
|
13
26
|
|
|
14
27
|
**Other changes:**
|
|
15
28
|
|
|
16
|
-
- Support null in koffi.free() and koffi.address()
|
|
29
|
+
- Support null in `koffi.free()` and `koffi.address()`
|
|
17
30
|
|
|
18
31
|
#### Koffi 2.3.15
|
|
19
32
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
package/src/koffi/src/call.cc
CHANGED
|
@@ -77,8 +77,10 @@ void CallData::Dispose()
|
|
|
77
77
|
int16_t idx = used_trampolines[i];
|
|
78
78
|
TrampolineInfo *trampoline = &shared.trampolines[idx];
|
|
79
79
|
|
|
80
|
+
RG_ASSERT(trampoline->instance == instance);
|
|
80
81
|
RG_ASSERT(!trampoline->func.IsEmpty());
|
|
81
82
|
|
|
83
|
+
trampoline->instance = nullptr;
|
|
82
84
|
trampoline->func.Reset();
|
|
83
85
|
trampoline->recv.Reset();
|
|
84
86
|
|
|
@@ -147,7 +149,7 @@ bool CallData::PushString(Napi::Value value, int directions, const char **out_st
|
|
|
147
149
|
{
|
|
148
150
|
if (value.IsString()) {
|
|
149
151
|
if (RG_UNLIKELY(directions & 2)) {
|
|
150
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
|
|
152
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, value));
|
|
151
153
|
return false;
|
|
152
154
|
}
|
|
153
155
|
|
|
@@ -200,6 +202,7 @@ bool CallData::PushString(Napi::Value value, int directions, const char **out_st
|
|
|
200
202
|
napi_status status = napi_create_reference(env, array, 1, &out->ref);
|
|
201
203
|
RG_ASSERT(status == napi_ok);
|
|
202
204
|
|
|
205
|
+
out->kind = OutArgument::Kind::Array;
|
|
203
206
|
out->ptr = (const uint8_t *)*out_str;
|
|
204
207
|
out->type = type;
|
|
205
208
|
}
|
|
@@ -301,6 +304,7 @@ bool CallData::PushString16(Napi::Value value, int directions, const char16_t **
|
|
|
301
304
|
napi_status status = napi_create_reference(env, array, 1, &out->ref);
|
|
302
305
|
RG_ASSERT(status == napi_ok);
|
|
303
306
|
|
|
307
|
+
out->kind = OutArgument::Kind::Array;
|
|
304
308
|
out->ptr = (const uint8_t *)*out_str16;
|
|
305
309
|
out->type = type;
|
|
306
310
|
}
|
|
@@ -973,6 +977,9 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
973
977
|
case napi_object: {
|
|
974
978
|
uint8_t *ptr = nullptr;
|
|
975
979
|
|
|
980
|
+
OutArgument::Kind out_kind;
|
|
981
|
+
Size out_max_len = -1;
|
|
982
|
+
|
|
976
983
|
if (value.IsArray()) {
|
|
977
984
|
if (RG_UNLIKELY(!type->ref.type->size)) {
|
|
978
985
|
ThrowError<Napi::TypeError>(env, "Cannot pass %1 value to void *, use koffi.as()",
|
|
@@ -981,17 +988,25 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
981
988
|
}
|
|
982
989
|
|
|
983
990
|
Napi::Array array = value.As<Napi::Array>();
|
|
991
|
+
Size len = PushIndirectString(array, type->ref.type, &ptr);
|
|
984
992
|
|
|
985
|
-
|
|
986
|
-
|
|
993
|
+
if (len >= 0) {
|
|
994
|
+
out_kind = (type->ref.type->size == 2) ? OutArgument::Kind::String16 : OutArgument::Kind::String;
|
|
995
|
+
out_max_len = len;
|
|
996
|
+
} else {
|
|
997
|
+
Size len = (Size)array.Length();
|
|
998
|
+
Size size = len * type->ref.type->size;
|
|
987
999
|
|
|
988
|
-
|
|
1000
|
+
ptr = AllocHeap(size, 16);
|
|
989
1001
|
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
1002
|
+
if (directions & 1) {
|
|
1003
|
+
if (!PushNormalArray(array, len, type, ptr))
|
|
1004
|
+
return false;
|
|
1005
|
+
} else {
|
|
1006
|
+
memset_safe(ptr, 0, size);
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
out_kind = OutArgument::Kind::Array;
|
|
995
1010
|
}
|
|
996
1011
|
} else if (IsRawBuffer(value)) {
|
|
997
1012
|
Span<uint8_t> buffer = GetRawBuffer(value);
|
|
@@ -1006,6 +1021,8 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
1006
1021
|
ptr = buffer.ptr;
|
|
1007
1022
|
directions = 1;
|
|
1008
1023
|
}
|
|
1024
|
+
|
|
1025
|
+
out_kind = OutArgument::Kind::Buffer;
|
|
1009
1026
|
} else if (RG_LIKELY(type->ref.type->primitive == PrimitiveKind::Record ||
|
|
1010
1027
|
type->ref.type->primitive == PrimitiveKind::Union)) {
|
|
1011
1028
|
if (RG_UNLIKELY(!type->ref.type->size)) {
|
|
@@ -1031,6 +1048,8 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
1031
1048
|
|
|
1032
1049
|
memset_safe(ptr, 0, type->size);
|
|
1033
1050
|
}
|
|
1051
|
+
|
|
1052
|
+
out_kind = OutArgument::Kind::Object;
|
|
1034
1053
|
} else {
|
|
1035
1054
|
goto unexpected;
|
|
1036
1055
|
}
|
|
@@ -1041,14 +1060,36 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
1041
1060
|
napi_status status = napi_create_reference(env, value, 1, &out->ref);
|
|
1042
1061
|
RG_ASSERT(status == napi_ok);
|
|
1043
1062
|
|
|
1063
|
+
out->kind = out_kind;
|
|
1044
1064
|
out->ptr = ptr;
|
|
1045
1065
|
out->type = type->ref.type;
|
|
1066
|
+
out->max_len = out_max_len;
|
|
1046
1067
|
}
|
|
1047
1068
|
|
|
1048
1069
|
*out_ptr = ptr;
|
|
1049
1070
|
return true;
|
|
1050
1071
|
} break;
|
|
1051
1072
|
|
|
1073
|
+
case napi_string: {
|
|
1074
|
+
RG_ASSERT(type->primitive == PrimitiveKind::Pointer);
|
|
1075
|
+
|
|
1076
|
+
if (RG_UNLIKELY(directions & 2))
|
|
1077
|
+
goto unexpected;
|
|
1078
|
+
|
|
1079
|
+
if (type->ref.type == instance->void_type) {
|
|
1080
|
+
PushStringValue(value, (const char **)out_ptr);
|
|
1081
|
+
return true;
|
|
1082
|
+
} else if (type->ref.type->primitive == PrimitiveKind::Int8) {
|
|
1083
|
+
PushStringValue(value, (const char **)out_ptr);
|
|
1084
|
+
return true;
|
|
1085
|
+
} else if (type->ref.type->primitive == PrimitiveKind::Int16) {
|
|
1086
|
+
PushString16Value(value, (const char16_t **)out_ptr);
|
|
1087
|
+
return true;
|
|
1088
|
+
} else {
|
|
1089
|
+
goto unexpected;
|
|
1090
|
+
}
|
|
1091
|
+
} break;
|
|
1092
|
+
|
|
1052
1093
|
case napi_number: {
|
|
1053
1094
|
Napi::Number number = value.As<Napi::Number>();
|
|
1054
1095
|
intptr_t ptr = (intptr_t)number.Int32Value();
|
|
@@ -1075,6 +1116,27 @@ unexpected:
|
|
|
1075
1116
|
return false;
|
|
1076
1117
|
}
|
|
1077
1118
|
|
|
1119
|
+
Size CallData::PushIndirectString(Napi::Array array, const TypeInfo *ref, uint8_t **out_ptr)
|
|
1120
|
+
{
|
|
1121
|
+
if (array.Length() != 1)
|
|
1122
|
+
return -1;
|
|
1123
|
+
|
|
1124
|
+
Napi::Value value = array[0u];
|
|
1125
|
+
|
|
1126
|
+
if (!value.IsString())
|
|
1127
|
+
return -1;
|
|
1128
|
+
|
|
1129
|
+
if (ref == instance->void_type) {
|
|
1130
|
+
return PushStringValue(value, (const char **)out_ptr);
|
|
1131
|
+
} else if (ref->primitive == PrimitiveKind::Int8) {
|
|
1132
|
+
return PushStringValue(value, (const char **)out_ptr);
|
|
1133
|
+
} else if (ref->primitive == PrimitiveKind::Int16) {
|
|
1134
|
+
return PushString16Value(value, (const char16_t **)out_ptr);
|
|
1135
|
+
} else {
|
|
1136
|
+
return -1;
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1078
1140
|
static inline Napi::Value GetReferenceValue(Napi::Env env, napi_ref ref)
|
|
1079
1141
|
{
|
|
1080
1142
|
napi_value value;
|
|
@@ -1091,21 +1153,55 @@ void CallData::PopOutArguments()
|
|
|
1091
1153
|
Napi::Value value = GetReferenceValue(env, out.ref);
|
|
1092
1154
|
RG_ASSERT(!value.IsEmpty());
|
|
1093
1155
|
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1156
|
+
switch (out.kind) {
|
|
1157
|
+
case OutArgument::Kind::Array: {
|
|
1158
|
+
RG_ASSERT(value.IsArray());
|
|
1159
|
+
|
|
1160
|
+
Napi::Array array(env, value);
|
|
1161
|
+
DecodeNormalArray(array, out.ptr, out.type);
|
|
1162
|
+
} break;
|
|
1163
|
+
|
|
1164
|
+
case OutArgument::Kind::Buffer: {
|
|
1165
|
+
RG_ASSERT(IsRawBuffer(value));
|
|
1166
|
+
|
|
1167
|
+
Span<uint8_t> buffer = GetRawBuffer(value);
|
|
1168
|
+
DecodeBuffer(buffer, out.ptr, out.type);
|
|
1169
|
+
} break;
|
|
1170
|
+
|
|
1171
|
+
case OutArgument::Kind::String: {
|
|
1172
|
+
Napi::Array array(env, value);
|
|
1173
|
+
|
|
1174
|
+
RG_ASSERT(array.IsArray());
|
|
1175
|
+
RG_ASSERT(array.Length() == 1);
|
|
1176
|
+
|
|
1177
|
+
Size len = strnlen((const char *)out.ptr, out.max_len);
|
|
1178
|
+
Napi::String str = Napi::String::New(env, (const char *)out.ptr, len);
|
|
1179
|
+
|
|
1180
|
+
array.Set(0u, str);
|
|
1181
|
+
} break;
|
|
1182
|
+
|
|
1183
|
+
case OutArgument::Kind::String16: {
|
|
1184
|
+
Napi::Array array(env, value);
|
|
1185
|
+
|
|
1186
|
+
RG_ASSERT(array.IsArray());
|
|
1187
|
+
RG_ASSERT(array.Length() == 1);
|
|
1188
|
+
|
|
1189
|
+
Size len = WideStringLength((const char16_t *)out.ptr, out.max_len);
|
|
1190
|
+
Napi::String str = Napi::String::New(env, (const char16_t *)out.ptr, len);
|
|
1191
|
+
|
|
1192
|
+
array.Set(0u, str);
|
|
1193
|
+
} break;
|
|
1194
|
+
|
|
1195
|
+
case OutArgument::Kind::Object: {
|
|
1196
|
+
Napi::Object obj = value.As<Napi::Object>();
|
|
1197
|
+
|
|
1198
|
+
if (CheckValueTag(instance, value, &MagicUnionMarker)) {
|
|
1199
|
+
MagicUnion *u = MagicUnion::Unwrap(obj);
|
|
1200
|
+
u->SetRaw(out.ptr);
|
|
1201
|
+
} else {
|
|
1202
|
+
DecodeObject(obj, out.ptr, out.type);
|
|
1203
|
+
}
|
|
1204
|
+
} break;
|
|
1109
1205
|
}
|
|
1110
1206
|
}
|
|
1111
1207
|
}
|
|
@@ -1131,6 +1227,7 @@ void *CallData::ReserveTrampoline(const FunctionInfo *proto, Napi::Function func
|
|
|
1131
1227
|
|
|
1132
1228
|
TrampolineInfo *trampoline = &shared.trampolines[idx];
|
|
1133
1229
|
|
|
1230
|
+
trampoline->instance = instance;
|
|
1134
1231
|
trampoline->proto = proto;
|
|
1135
1232
|
trampoline->func.Reset(func, 1);
|
|
1136
1233
|
trampoline->recv.Reset();
|
package/src/koffi/src/call.hh
CHANGED
|
@@ -37,9 +37,21 @@ struct BackRegisters;
|
|
|
37
37
|
// But on Windows i386, without it, the alignment may not be correct (compiler bug?).
|
|
38
38
|
class alignas(8) CallData {
|
|
39
39
|
struct OutArgument {
|
|
40
|
+
enum class Kind {
|
|
41
|
+
Array,
|
|
42
|
+
Buffer,
|
|
43
|
+
String,
|
|
44
|
+
String16,
|
|
45
|
+
Object
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
Kind kind;
|
|
49
|
+
|
|
40
50
|
napi_ref ref;
|
|
41
51
|
const uint8_t *ptr;
|
|
42
52
|
const TypeInfo *type;
|
|
53
|
+
|
|
54
|
+
Size max_len; // Only for indirect strings
|
|
43
55
|
};
|
|
44
56
|
|
|
45
57
|
Napi::Env env;
|
|
@@ -116,6 +128,7 @@ private:
|
|
|
116
128
|
bool PushBuffer(Span<const uint8_t> buffer, Size size, const TypeInfo *type, uint8_t *origin);
|
|
117
129
|
bool PushStringArray(Napi::Value value, const TypeInfo *type, uint8_t *origin);
|
|
118
130
|
bool PushPointer(Napi::Value value, const TypeInfo *type, int directions, void **out_ptr);
|
|
131
|
+
Size PushIndirectString(Napi::Array array, const TypeInfo *ref, uint8_t **out_ptr);
|
|
119
132
|
|
|
120
133
|
void PopOutArguments();
|
|
121
134
|
|
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -605,8 +605,10 @@ static Napi::Value EncodePointerDirection(const Napi::CallbackInfo &info, int di
|
|
|
605
605
|
if (!type)
|
|
606
606
|
return env.Null();
|
|
607
607
|
|
|
608
|
-
if (type->primitive != PrimitiveKind::Pointer
|
|
609
|
-
|
|
608
|
+
if (type->primitive != PrimitiveKind::Pointer &&
|
|
609
|
+
type->primitive != PrimitiveKind::String &&
|
|
610
|
+
type->primitive != PrimitiveKind::String16) {
|
|
611
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 type, expected pointer or string type", type->name);
|
|
610
612
|
return env.Null();
|
|
611
613
|
}
|
|
612
614
|
|
|
@@ -653,9 +655,9 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
|
|
|
653
655
|
const TypeInfo *src = ResolveType(info[named]);
|
|
654
656
|
if (!src)
|
|
655
657
|
return env.Null();
|
|
656
|
-
if (src->primitive != PrimitiveKind::
|
|
657
|
-
src->primitive != PrimitiveKind::
|
|
658
|
-
src->primitive != PrimitiveKind::
|
|
658
|
+
if (src->primitive != PrimitiveKind::Pointer &&
|
|
659
|
+
src->primitive != PrimitiveKind::String &&
|
|
660
|
+
src->primitive != PrimitiveKind::String16) {
|
|
659
661
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 type, expected pointer or string type", src->name);
|
|
660
662
|
return env.Null();
|
|
661
663
|
}
|
|
@@ -1652,6 +1654,7 @@ static Napi::Value RegisterCallback(const Napi::CallbackInfo &info)
|
|
|
1652
1654
|
|
|
1653
1655
|
TrampolineInfo *trampoline = &shared.trampolines[idx];
|
|
1654
1656
|
|
|
1657
|
+
trampoline->instance = instance;
|
|
1655
1658
|
trampoline->proto = type->ref.proto;
|
|
1656
1659
|
trampoline->func.Reset(func, 1);
|
|
1657
1660
|
if (!IsNullOrUndefined(recv)) {
|
|
@@ -1952,10 +1955,8 @@ InstanceData::~InstanceData()
|
|
|
1952
1955
|
for (int16_t idx = 0; idx < MaxTrampolines; idx++) {
|
|
1953
1956
|
TrampolineInfo *trampoline = &shared.trampolines[idx];
|
|
1954
1957
|
|
|
1955
|
-
if (trampoline->
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
if (trampoline->func.Env().GetInstanceData<InstanceData>() == this) {
|
|
1958
|
+
if (trampoline->instance == this) {
|
|
1959
|
+
trampoline->instance = nullptr;
|
|
1959
1960
|
trampoline->func.Reset();
|
|
1960
1961
|
trampoline->recv.Reset();
|
|
1961
1962
|
}
|
|
@@ -1982,8 +1983,10 @@ static Napi::Value CastValue(const Napi::CallbackInfo &info)
|
|
|
1982
1983
|
const TypeInfo *type = ResolveType(info[1]);
|
|
1983
1984
|
if (RG_UNLIKELY(!type))
|
|
1984
1985
|
return env.Null();
|
|
1985
|
-
if (type->primitive != PrimitiveKind::Pointer
|
|
1986
|
-
|
|
1986
|
+
if (type->primitive != PrimitiveKind::Pointer &&
|
|
1987
|
+
type->primitive != PrimitiveKind::String &&
|
|
1988
|
+
type->primitive != PrimitiveKind::String16) {
|
|
1989
|
+
ThrowError<Napi::TypeError>(env, "Only pointer or string types can be used for casting");
|
|
1987
1990
|
return env.Null();
|
|
1988
1991
|
}
|
|
1989
1992
|
|
package/src/koffi/src/ffi.hh
CHANGED
|
@@ -305,6 +305,8 @@ RG_STATIC_ASSERT(DefaultMaxAsyncCalls >= DefaultResidentAsyncPools);
|
|
|
305
305
|
RG_STATIC_ASSERT(MaxAsyncCalls >= DefaultMaxAsyncCalls);
|
|
306
306
|
|
|
307
307
|
struct TrampolineInfo {
|
|
308
|
+
InstanceData *instance;
|
|
309
|
+
|
|
308
310
|
const FunctionInfo *proto;
|
|
309
311
|
Napi::FunctionReference func;
|
|
310
312
|
Napi::Reference<Napi::Value> recv;
|
package/src/koffi/src/util.cc
CHANGED
package/src/koffi/src/util.hh
CHANGED
|
@@ -154,6 +154,8 @@ T GetNumber(Napi::Value value)
|
|
|
154
154
|
RG_UNREACHABLE();
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
Size WideStringLength(const char16_t *str16, Size max);
|
|
158
|
+
|
|
157
159
|
Napi::Object DecodeObject(Napi::Env env, const uint8_t *origin, const TypeInfo *type);
|
|
158
160
|
void DecodeObject(Napi::Object obj, const uint8_t *origin, const TypeInfo *type);
|
|
159
161
|
Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *type);
|
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# node-addon-api Changelog
|
|
2
2
|
|
|
3
|
+
## 2023-04-20 Version 6.1.0, @NickNaso
|
|
4
|
+
|
|
5
|
+
### Notable changes
|
|
6
|
+
|
|
7
|
+
#### API
|
|
8
|
+
|
|
9
|
+
- Enforce type checks on `Napi::Value::As()`.
|
|
10
|
+
- Added `Napi::TypeTaggable` class.
|
|
11
|
+
- Defined `NAPI_HAS_THREADS` to make TSFN available on Emscripten.
|
|
12
|
+
- Defined `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` and
|
|
13
|
+
`Napi::Buffer::NewOrCopy()` to handle the support for external buffers.
|
|
14
|
+
|
|
15
|
+
#### TEST
|
|
16
|
+
|
|
17
|
+
- Added tests for `Napi::Reference<T>` class.
|
|
18
|
+
- Added tests for copy/move semantics.
|
|
19
|
+
- Added tests for `Napi::RangeError` and `Napi::TypeError` class.
|
|
20
|
+
- Fixed inconsistent failure executing test suite.
|
|
21
|
+
- Added tests for `Napi::ObjectReference<T>` class.
|
|
22
|
+
- Added tests for `Napi::ObjectWrap<T>` class.
|
|
23
|
+
|
|
24
|
+
### Documentation
|
|
25
|
+
|
|
26
|
+
- Added documentation for `Napi::TypeTaggable`.
|
|
27
|
+
- Some minor fixes all over the documentation.
|
|
28
|
+
|
|
29
|
+
### Commits
|
|
30
|
+
|
|
31
|
+
- \[[`5adb896782`](https://github.com/nodejs/node-addon-api/commit/5adb896782)] - **src**: enforce type checks on Napi::Value::As() (#1281) (Chengzhong Wu)
|
|
32
|
+
- \[[`d9faac7ec2`](https://github.com/nodejs/node-addon-api/commit/d9faac7ec2)] - Fix exits/exists typo in docs for Env::AddCleanupHook() (#1306) (Mathias Stearn)
|
|
33
|
+
- \[[`164459ca03`](https://github.com/nodejs/node-addon-api/commit/164459ca03)] - **doc**: update class hierarchy for TypeTaggable (Gabriel Schulhof) [#1303](https://github.com/nodejs/node-addon-api/pull/1303)
|
|
34
|
+
- \[[`d01304437c`](https://github.com/nodejs/node-addon-api/commit/d01304437c)] - **src**: interject class TypeTaggable (Gabriel Schulhof) [#1298](https://github.com/nodejs/node-addon-api/pull/1298)
|
|
35
|
+
- \[[`d4942ccd4f`](https://github.com/nodejs/node-addon-api/commit/d4942ccd4f)] - **test**: Complete test coverage for Reference\<T> class (#1277) (Jack)
|
|
36
|
+
- \[[`a8ad7e7a7b`](https://github.com/nodejs/node-addon-api/commit/a8ad7e7a7b)] - **test**: Add tests for copy/move semantics (JckXia) [#1295](https://github.com/nodejs/node-addon-api/pull/1295)
|
|
37
|
+
- \[[`e484327344`](https://github.com/nodejs/node-addon-api/commit/e484327344)] - Add test coverage for typed and range err (#1280) (Jack)
|
|
38
|
+
- \[[`ebc7858593`](https://github.com/nodejs/node-addon-api/commit/ebc7858593)] - **test**: Update wait with a condition (#1297) (Jack)
|
|
39
|
+
- \[[`0b53d885f5`](https://github.com/nodejs/node-addon-api/commit/0b53d885f5)] - **src**: define `NAPI_HAS_THREADS` (toyobayashi) [#1283](https://github.com/nodejs/node-addon-api/pull/1283)
|
|
40
|
+
- \[[`464610babf`](https://github.com/nodejs/node-addon-api/commit/464610babf)] - **test**: complete objectRefs tests (JckXia) [#1274](https://github.com/nodejs/node-addon-api/pull/1274)
|
|
41
|
+
- \[[`b16c762a19`](https://github.com/nodejs/node-addon-api/commit/b16c762a19)] - **src**: handle no support for external buffers (legendecas) [#1273](https://github.com/nodejs/node-addon-api/pull/1273)
|
|
42
|
+
- \[[`61b8e28720`](https://github.com/nodejs/node-addon-api/commit/61b8e28720)] - **test**: Add test covg for obj wrap (#1269) (Jack)
|
|
43
|
+
|
|
3
44
|
## 2023-02-03 Version 6.0.0, @NickNaso
|
|
4
45
|
|
|
5
46
|
### Notable changes
|
|
@@ -23,6 +23,9 @@ Returns a new `Napi::ArrayBuffer` instance.
|
|
|
23
23
|
|
|
24
24
|
### New
|
|
25
25
|
|
|
26
|
+
> When `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` is defined, this method is not available.
|
|
27
|
+
> See [External Buffer][] for more information.
|
|
28
|
+
|
|
26
29
|
Wraps the provided external data into a new `Napi::ArrayBuffer` instance.
|
|
27
30
|
|
|
28
31
|
The `Napi::ArrayBuffer` instance does not assume ownership for the data and
|
|
@@ -48,6 +51,9 @@ Returns a new `Napi::ArrayBuffer` instance.
|
|
|
48
51
|
|
|
49
52
|
### New
|
|
50
53
|
|
|
54
|
+
> When `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` is defined, this method is not available.
|
|
55
|
+
> See [External Buffer][] for more information.
|
|
56
|
+
|
|
51
57
|
Wraps the provided external data into a new `Napi::ArrayBuffer` instance.
|
|
52
58
|
|
|
53
59
|
The `Napi::ArrayBuffer` instance does not assume ownership for the data and
|
|
@@ -74,6 +80,9 @@ Returns a new `Napi::ArrayBuffer` instance.
|
|
|
74
80
|
|
|
75
81
|
### New
|
|
76
82
|
|
|
83
|
+
> When `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` is defined, this method is not available.
|
|
84
|
+
> See [External Buffer][] for more information.
|
|
85
|
+
|
|
77
86
|
Wraps the provided external data into a new `Napi::ArrayBuffer` instance.
|
|
78
87
|
|
|
79
88
|
The `Napi::ArrayBuffer` instance does not assume ownership for the data and expects it
|
|
@@ -153,3 +162,4 @@ bool Napi::ArrayBuffer::IsDetached() const;
|
|
|
153
162
|
Returns `true` if this `ArrayBuffer` has been detached.
|
|
154
163
|
|
|
155
164
|
[`Napi::Object`]: ./object.md
|
|
165
|
+
[External Buffer]: ./external_buffer.md
|
|
@@ -22,6 +22,9 @@ Returns a new `Napi::Buffer` object.
|
|
|
22
22
|
|
|
23
23
|
### New
|
|
24
24
|
|
|
25
|
+
> When `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` is defined, this method is not available.
|
|
26
|
+
> See [External Buffer][] for more information.
|
|
27
|
+
|
|
25
28
|
Wraps the provided external data into a new `Napi::Buffer` object.
|
|
26
29
|
|
|
27
30
|
The `Napi::Buffer` object does not assume ownership for the data and expects it to be
|
|
@@ -47,6 +50,9 @@ Returns a new `Napi::Buffer` object.
|
|
|
47
50
|
|
|
48
51
|
### New
|
|
49
52
|
|
|
53
|
+
> When `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` is defined, this method is not available.
|
|
54
|
+
> See [External Buffer][] for more information.
|
|
55
|
+
|
|
50
56
|
Wraps the provided external data into a new `Napi::Buffer` object.
|
|
51
57
|
|
|
52
58
|
The `Napi::Buffer` object does not assume ownership for the data and expects it
|
|
@@ -72,6 +78,9 @@ Returns a new `Napi::Buffer` object.
|
|
|
72
78
|
|
|
73
79
|
### New
|
|
74
80
|
|
|
81
|
+
> When `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` is defined, this method is not available.
|
|
82
|
+
> See [External Buffer][] for more information.
|
|
83
|
+
|
|
75
84
|
Wraps the provided external data into a new `Napi::Buffer` object.
|
|
76
85
|
|
|
77
86
|
The `Napi::Buffer` object does not assume ownership for the data and expects it to be
|
|
@@ -98,6 +107,93 @@ static Napi::Buffer<T> Napi::Buffer::New(napi_env env,
|
|
|
98
107
|
|
|
99
108
|
Returns a new `Napi::Buffer` object.
|
|
100
109
|
|
|
110
|
+
### NewOrCopy
|
|
111
|
+
|
|
112
|
+
Wraps the provided external data into a new `Napi::Buffer` object. When the
|
|
113
|
+
[external buffer][] is not supported, allocates a new `Napi::Buffer` object and
|
|
114
|
+
copies the provided external data into it.
|
|
115
|
+
|
|
116
|
+
The `Napi::Buffer` object does not assume ownership for the data and expects it to be
|
|
117
|
+
valid for the lifetime of the object. Since the `Napi::Buffer` is subject to garbage
|
|
118
|
+
collection this overload is only suitable for data which is static and never
|
|
119
|
+
needs to be freed.
|
|
120
|
+
|
|
121
|
+
This factory method will not provide the caller with an opportunity to free the
|
|
122
|
+
data when the `Napi::Buffer` gets garbage-collected. If you need to free the
|
|
123
|
+
data retained by the `Napi::Buffer` object please use other variants of the
|
|
124
|
+
`Napi::Buffer::New` factory method that accept `Napi::Finalizer`, which is a
|
|
125
|
+
function that will be invoked when the `Napi::Buffer` object has been
|
|
126
|
+
destroyed.
|
|
127
|
+
|
|
128
|
+
```cpp
|
|
129
|
+
static Napi::Buffer<T> Napi::Buffer::NewOrCopy(napi_env env, T* data, size_t length);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
- `[in] env`: The environment in which to create the `Napi::Buffer` object.
|
|
133
|
+
- `[in] data`: The pointer to the external data to expose.
|
|
134
|
+
- `[in] length`: The number of `T` elements in the external data.
|
|
135
|
+
|
|
136
|
+
Returns a new `Napi::Buffer` object.
|
|
137
|
+
|
|
138
|
+
### NewOrCopy
|
|
139
|
+
|
|
140
|
+
Wraps the provided external data into a new `Napi::Buffer` object. When the
|
|
141
|
+
[external buffer][] is not supported, allocates a new `Napi::Buffer` object and
|
|
142
|
+
copies the provided external data into it and the `finalizeCallback` is invoked
|
|
143
|
+
immediately.
|
|
144
|
+
|
|
145
|
+
The `Napi::Buffer` object does not assume ownership for the data and expects it
|
|
146
|
+
to be valid for the lifetime of the object. The data can only be freed once the
|
|
147
|
+
`finalizeCallback` is invoked to indicate that the `Napi::Buffer` has been released.
|
|
148
|
+
|
|
149
|
+
```cpp
|
|
150
|
+
template <typename Finalizer>
|
|
151
|
+
static Napi::Buffer<T> Napi::Buffer::NewOrCopy(napi_env env,
|
|
152
|
+
T* data,
|
|
153
|
+
size_t length,
|
|
154
|
+
Finalizer finalizeCallback);
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
- `[in] env`: The environment in which to create the `Napi::Buffer` object.
|
|
158
|
+
- `[in] data`: The pointer to the external data to expose.
|
|
159
|
+
- `[in] length`: The number of `T` elements in the external data.
|
|
160
|
+
- `[in] finalizeCallback`: The function to be called when the `Napi::Buffer` is
|
|
161
|
+
destroyed. It must implement `operator()`, accept an Napi::Env, a `T*` (which is the
|
|
162
|
+
external data pointer), and return `void`.
|
|
163
|
+
|
|
164
|
+
Returns a new `Napi::Buffer` object.
|
|
165
|
+
|
|
166
|
+
### NewOrCopy
|
|
167
|
+
|
|
168
|
+
Wraps the provided external data into a new `Napi::Buffer` object. When the
|
|
169
|
+
[external buffer][] is not supported, allocates a new `Napi::Buffer` object and
|
|
170
|
+
copies the provided external data into it and the `finalizeCallback` is invoked
|
|
171
|
+
immediately.
|
|
172
|
+
|
|
173
|
+
The `Napi::Buffer` object does not assume ownership for the data and expects it to be
|
|
174
|
+
valid for the lifetime of the object. The data can only be freed once the
|
|
175
|
+
`finalizeCallback` is invoked to indicate that the `Napi::Buffer` has been released.
|
|
176
|
+
|
|
177
|
+
```cpp
|
|
178
|
+
template <typename Finalizer, typename Hint>
|
|
179
|
+
static Napi::Buffer<T> Napi::Buffer::NewOrCopy(napi_env env,
|
|
180
|
+
T* data,
|
|
181
|
+
size_t length,
|
|
182
|
+
Finalizer finalizeCallback,
|
|
183
|
+
Hint* finalizeHint);
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
- `[in] env`: The environment in which to create the `Napi::Buffer` object.
|
|
187
|
+
- `[in] data`: The pointer to the external data to expose.
|
|
188
|
+
- `[in] length`: The number of `T` elements in the external data.
|
|
189
|
+
- `[in] finalizeCallback`: The function to be called when the `Napi::Buffer` is
|
|
190
|
+
destroyed. It must implement `operator()`, accept an Napi::Env, a `T*` (which is the
|
|
191
|
+
external data pointer) and `Hint*`, and return `void`.
|
|
192
|
+
- `[in] finalizeHint`: The hint to be passed as the second parameter of the
|
|
193
|
+
finalize callback.
|
|
194
|
+
|
|
195
|
+
Returns a new `Napi::Buffer` object.
|
|
196
|
+
|
|
101
197
|
### Copy
|
|
102
198
|
|
|
103
199
|
Allocates a new `Napi::Buffer` object and copies the provided external data into it.
|
|
@@ -148,3 +244,4 @@ size_t Napi::Buffer::Length() const;
|
|
|
148
244
|
Returns the number of `T` elements in the external data.
|
|
149
245
|
|
|
150
246
|
[`Napi::Uint8Array`]: ./typed_array_of.md
|
|
247
|
+
[External Buffer]: ./external_buffer.md
|