koffi 2.3.15 → 2.3.17
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 +18 -0
- package/build/2.3.17/koffi_darwin_arm64/koffi.node +0 -0
- package/build/2.3.17/koffi_darwin_x64/koffi.node +0 -0
- package/build/2.3.17/koffi_freebsd_arm64/koffi.node +0 -0
- package/build/2.3.17/koffi_freebsd_ia32/koffi.node +0 -0
- package/build/2.3.17/koffi_freebsd_x64/koffi.node +0 -0
- package/build/2.3.17/koffi_linux_arm32hf/koffi.node +0 -0
- package/build/2.3.17/koffi_linux_arm64/koffi.node +0 -0
- package/build/2.3.17/koffi_linux_ia32/koffi.node +0 -0
- package/build/2.3.17/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/build/2.3.17/koffi_linux_x64/koffi.node +0 -0
- package/build/2.3.17/koffi_openbsd_ia32/koffi.node +0 -0
- package/build/2.3.17/koffi_openbsd_x64/koffi.node +0 -0
- package/build/2.3.17/koffi_win32_arm64/koffi.exp +0 -0
- package/build/2.3.17/koffi_win32_arm64/koffi.lib +0 -0
- package/build/2.3.17/koffi_win32_arm64/koffi.node +0 -0
- package/build/{2.3.15 → 2.3.17}/koffi_win32_ia32/koffi.exp +0 -0
- package/build/{2.3.15 → 2.3.17}/koffi_win32_ia32/koffi.lib +0 -0
- package/build/2.3.17/koffi_win32_ia32/koffi.node +0 -0
- package/build/{2.3.15 → 2.3.17}/koffi_win32_x64/koffi.exp +0 -0
- package/build/{2.3.15/koffi_win32_arm64 → 2.3.17/koffi_win32_x64}/koffi.lib +0 -0
- package/build/2.3.17/koffi_win32_x64/koffi.node +0 -0
- package/package.json +2 -2
- package/src/cnoke/cnoke.js +1 -1
- package/src/cnoke/package.json +1 -1
- package/src/cnoke/src/builder.js +2 -2
- package/src/koffi/CMakeLists.txt +4 -0
- package/src/koffi/src/call.cc +118 -24
- package/src/koffi/src/call.hh +13 -0
- package/src/koffi/src/ffi.cc +30 -21
- package/src/koffi/src/util.cc +1 -1
- package/src/koffi/src/util.hh +2 -0
- package/build/2.3.15/koffi_darwin_arm64/koffi.node +0 -0
- package/build/2.3.15/koffi_darwin_x64/koffi.node +0 -0
- package/build/2.3.15/koffi_freebsd_arm64/koffi.node +0 -0
- package/build/2.3.15/koffi_freebsd_ia32/koffi.node +0 -0
- package/build/2.3.15/koffi_freebsd_x64/koffi.node +0 -0
- package/build/2.3.15/koffi_linux_arm32hf/koffi.node +0 -0
- package/build/2.3.15/koffi_linux_arm64/koffi.node +0 -0
- package/build/2.3.15/koffi_linux_ia32/koffi.node +0 -0
- package/build/2.3.15/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/build/2.3.15/koffi_linux_x64/koffi.node +0 -0
- package/build/2.3.15/koffi_openbsd_ia32/koffi.node +0 -0
- package/build/2.3.15/koffi_openbsd_x64/koffi.node +0 -0
- package/build/2.3.15/koffi_win32_arm64/koffi.exp +0 -0
- package/build/2.3.15/koffi_win32_arm64/koffi.node +0 -0
- package/build/2.3.15/koffi_win32_ia32/koffi.node +0 -0
- package/build/2.3.15/koffi_win32_x64/koffi.lib +0 -0
- package/build/2.3.15/koffi_win32_x64/koffi.node +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,24 @@
|
|
|
4
4
|
|
|
5
5
|
### Koffi 2.3
|
|
6
6
|
|
|
7
|
+
#### Koffi 2.3.17
|
|
8
|
+
|
|
9
|
+
**Main changes:**
|
|
10
|
+
|
|
11
|
+
- Allow strings for input `void *`, `int8_t *` and `int16_t *` pointer arguments
|
|
12
|
+
- Support using `[string]` (single-element string arrays) for polymorphic input/output arguments
|
|
13
|
+
|
|
14
|
+
#### Koffi 2.3.16
|
|
15
|
+
|
|
16
|
+
**Main changes:**
|
|
17
|
+
|
|
18
|
+
- Fix Windows ARM64 build to work with official Node.js version
|
|
19
|
+
- Compile Windows builds with Visual Studio 2022 17.5.3
|
|
20
|
+
|
|
21
|
+
**Other changes:**
|
|
22
|
+
|
|
23
|
+
- Support null in `koffi.free()` and `koffi.address()`
|
|
24
|
+
|
|
7
25
|
#### Koffi 2.3.15
|
|
8
26
|
|
|
9
27
|
**Main changes:**
|
|
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
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
package/src/cnoke/cnoke.js
CHANGED
|
@@ -155,7 +155,7 @@ Options:
|
|
|
155
155
|
(default: ${cnoke.DefaultOptions.mode})
|
|
156
156
|
-D, --debug Shortcut for --config Debug
|
|
157
157
|
|
|
158
|
-
--prebuild Use prebuilt
|
|
158
|
+
--prebuild Use prebuilt binary if available
|
|
159
159
|
|
|
160
160
|
-a, --arch <ARCH> Change architecture and ABI
|
|
161
161
|
(default: ${cnoke.determine_arch()})
|
package/src/cnoke/package.json
CHANGED
package/src/cnoke/src/builder.js
CHANGED
|
@@ -103,7 +103,7 @@ function Builder(config = {}) {
|
|
|
103
103
|
let basename = `node-v${runtime_version}-headers.tar.gz`;
|
|
104
104
|
let urls = [
|
|
105
105
|
`https://nodejs.org/dist/v${runtime_version}/${basename}`,
|
|
106
|
-
`https://unofficial-builds.nodejs.org/download/release/v${runtime_version}/${basename}`
|
|
106
|
+
// `https://unofficial-builds.nodejs.org/download/release/v${runtime_version}/${basename}`
|
|
107
107
|
];
|
|
108
108
|
let destname = `${cache_dir}/${basename}`;
|
|
109
109
|
|
|
@@ -130,7 +130,7 @@ function Builder(config = {}) {
|
|
|
130
130
|
if (!fs.existsSync(destname)) {
|
|
131
131
|
let urls = [
|
|
132
132
|
`https://nodejs.org/dist/v${runtime_version}/${dirname}/node.lib`,
|
|
133
|
-
`https://unofficial-builds.nodejs.org/download/release/v${runtime_version}/${dirname}/node.lib`
|
|
133
|
+
// `https://unofficial-builds.nodejs.org/download/release/v${runtime_version}/${dirname}/node.lib`
|
|
134
134
|
];
|
|
135
135
|
await tools.download_http(urls, destname);
|
|
136
136
|
}
|
package/src/koffi/CMakeLists.txt
CHANGED
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
# OTHER DEALINGS IN THE SOFTWARE.
|
|
21
21
|
|
|
22
22
|
cmake_minimum_required(VERSION 3.6)
|
|
23
|
+
cmake_policy(SET CMP0091 NEW)
|
|
24
|
+
|
|
23
25
|
project(koffi C CXX ASM)
|
|
24
26
|
|
|
25
27
|
include(CheckCXXCompilerFlag)
|
|
@@ -58,6 +60,8 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
|
58
60
|
# CMAKE_SYSTEM_PROCESSOR is wrong on Windows ARM64
|
|
59
61
|
|
|
60
62
|
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch|arm" OR CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64" OR CMAKE_OSX_ARCHITECTURES MATCHES "arm")
|
|
63
|
+
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded)
|
|
64
|
+
|
|
61
65
|
if(WIN32)
|
|
62
66
|
get_filename_component(cl_dir "${CMAKE_CXX_COMPILER}" DIRECTORY)
|
|
63
67
|
file(TO_CMAKE_PATH "${cl_dir}/armasm64.exe" asm_compiler)
|
package/src/koffi/src/call.cc
CHANGED
|
@@ -147,7 +147,7 @@ bool CallData::PushString(Napi::Value value, int directions, const char **out_st
|
|
|
147
147
|
{
|
|
148
148
|
if (value.IsString()) {
|
|
149
149
|
if (RG_UNLIKELY(directions & 2)) {
|
|
150
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
|
|
150
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, value));
|
|
151
151
|
return false;
|
|
152
152
|
}
|
|
153
153
|
|
|
@@ -200,6 +200,7 @@ bool CallData::PushString(Napi::Value value, int directions, const char **out_st
|
|
|
200
200
|
napi_status status = napi_create_reference(env, array, 1, &out->ref);
|
|
201
201
|
RG_ASSERT(status == napi_ok);
|
|
202
202
|
|
|
203
|
+
out->kind = OutArgument::Kind::Array;
|
|
203
204
|
out->ptr = (const uint8_t *)*out_str;
|
|
204
205
|
out->type = type;
|
|
205
206
|
}
|
|
@@ -301,6 +302,7 @@ bool CallData::PushString16(Napi::Value value, int directions, const char16_t **
|
|
|
301
302
|
napi_status status = napi_create_reference(env, array, 1, &out->ref);
|
|
302
303
|
RG_ASSERT(status == napi_ok);
|
|
303
304
|
|
|
305
|
+
out->kind = OutArgument::Kind::Array;
|
|
304
306
|
out->ptr = (const uint8_t *)*out_str16;
|
|
305
307
|
out->type = type;
|
|
306
308
|
}
|
|
@@ -973,6 +975,9 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
973
975
|
case napi_object: {
|
|
974
976
|
uint8_t *ptr = nullptr;
|
|
975
977
|
|
|
978
|
+
OutArgument::Kind out_kind;
|
|
979
|
+
Size out_max_len = -1;
|
|
980
|
+
|
|
976
981
|
if (value.IsArray()) {
|
|
977
982
|
if (RG_UNLIKELY(!type->ref.type->size)) {
|
|
978
983
|
ThrowError<Napi::TypeError>(env, "Cannot pass %1 value to void *, use koffi.as()",
|
|
@@ -981,17 +986,25 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
981
986
|
}
|
|
982
987
|
|
|
983
988
|
Napi::Array array = value.As<Napi::Array>();
|
|
989
|
+
Size len = PushIndirectString(array, type->ref.type, &ptr);
|
|
984
990
|
|
|
985
|
-
|
|
986
|
-
|
|
991
|
+
if (len >= 0) {
|
|
992
|
+
out_kind = (type->ref.type->size == 2) ? OutArgument::Kind::String16 : OutArgument::Kind::String;
|
|
993
|
+
out_max_len = len;
|
|
994
|
+
} else {
|
|
995
|
+
Size len = (Size)array.Length();
|
|
996
|
+
Size size = len * type->ref.type->size;
|
|
987
997
|
|
|
988
|
-
|
|
998
|
+
ptr = AllocHeap(size, 16);
|
|
989
999
|
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
1000
|
+
if (directions & 1) {
|
|
1001
|
+
if (!PushNormalArray(array, len, type, ptr))
|
|
1002
|
+
return false;
|
|
1003
|
+
} else {
|
|
1004
|
+
memset_safe(ptr, 0, size);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
out_kind = OutArgument::Kind::Array;
|
|
995
1008
|
}
|
|
996
1009
|
} else if (IsRawBuffer(value)) {
|
|
997
1010
|
Span<uint8_t> buffer = GetRawBuffer(value);
|
|
@@ -1006,6 +1019,8 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
1006
1019
|
ptr = buffer.ptr;
|
|
1007
1020
|
directions = 1;
|
|
1008
1021
|
}
|
|
1022
|
+
|
|
1023
|
+
out_kind = OutArgument::Kind::Buffer;
|
|
1009
1024
|
} else if (RG_LIKELY(type->ref.type->primitive == PrimitiveKind::Record ||
|
|
1010
1025
|
type->ref.type->primitive == PrimitiveKind::Union)) {
|
|
1011
1026
|
if (RG_UNLIKELY(!type->ref.type->size)) {
|
|
@@ -1031,6 +1046,8 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
1031
1046
|
|
|
1032
1047
|
memset_safe(ptr, 0, type->size);
|
|
1033
1048
|
}
|
|
1049
|
+
|
|
1050
|
+
out_kind = OutArgument::Kind::Object;
|
|
1034
1051
|
} else {
|
|
1035
1052
|
goto unexpected;
|
|
1036
1053
|
}
|
|
@@ -1041,14 +1058,36 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
1041
1058
|
napi_status status = napi_create_reference(env, value, 1, &out->ref);
|
|
1042
1059
|
RG_ASSERT(status == napi_ok);
|
|
1043
1060
|
|
|
1061
|
+
out->kind = out_kind;
|
|
1044
1062
|
out->ptr = ptr;
|
|
1045
1063
|
out->type = type->ref.type;
|
|
1064
|
+
out->max_len = out_max_len;
|
|
1046
1065
|
}
|
|
1047
1066
|
|
|
1048
1067
|
*out_ptr = ptr;
|
|
1049
1068
|
return true;
|
|
1050
1069
|
} break;
|
|
1051
1070
|
|
|
1071
|
+
case napi_string: {
|
|
1072
|
+
RG_ASSERT(type->primitive == PrimitiveKind::Pointer);
|
|
1073
|
+
|
|
1074
|
+
if (RG_UNLIKELY(directions & 2))
|
|
1075
|
+
goto unexpected;
|
|
1076
|
+
|
|
1077
|
+
if (type->ref.type == instance->void_type) {
|
|
1078
|
+
PushStringValue(value, (const char **)out_ptr);
|
|
1079
|
+
return true;
|
|
1080
|
+
} else if (type->ref.type->primitive == PrimitiveKind::Int8) {
|
|
1081
|
+
PushStringValue(value, (const char **)out_ptr);
|
|
1082
|
+
return true;
|
|
1083
|
+
} else if (type->ref.type->primitive == PrimitiveKind::Int16) {
|
|
1084
|
+
PushString16Value(value, (const char16_t **)out_ptr);
|
|
1085
|
+
return true;
|
|
1086
|
+
} else {
|
|
1087
|
+
goto unexpected;
|
|
1088
|
+
}
|
|
1089
|
+
} break;
|
|
1090
|
+
|
|
1052
1091
|
case napi_number: {
|
|
1053
1092
|
Napi::Number number = value.As<Napi::Number>();
|
|
1054
1093
|
intptr_t ptr = (intptr_t)number.Int32Value();
|
|
@@ -1075,6 +1114,27 @@ unexpected:
|
|
|
1075
1114
|
return false;
|
|
1076
1115
|
}
|
|
1077
1116
|
|
|
1117
|
+
Size CallData::PushIndirectString(Napi::Array array, const TypeInfo *ref, uint8_t **out_ptr)
|
|
1118
|
+
{
|
|
1119
|
+
if (array.Length() != 1)
|
|
1120
|
+
return -1;
|
|
1121
|
+
|
|
1122
|
+
Napi::Value value = array[0u];
|
|
1123
|
+
|
|
1124
|
+
if (!value.IsString())
|
|
1125
|
+
return -1;
|
|
1126
|
+
|
|
1127
|
+
if (ref == instance->void_type) {
|
|
1128
|
+
return PushStringValue(value, (const char **)out_ptr);
|
|
1129
|
+
} else if (ref->primitive == PrimitiveKind::Int8) {
|
|
1130
|
+
return PushStringValue(value, (const char **)out_ptr);
|
|
1131
|
+
} else if (ref->primitive == PrimitiveKind::Int16) {
|
|
1132
|
+
return PushString16Value(value, (const char16_t **)out_ptr);
|
|
1133
|
+
} else {
|
|
1134
|
+
return -1;
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1078
1138
|
static inline Napi::Value GetReferenceValue(Napi::Env env, napi_ref ref)
|
|
1079
1139
|
{
|
|
1080
1140
|
napi_value value;
|
|
@@ -1091,21 +1151,55 @@ void CallData::PopOutArguments()
|
|
|
1091
1151
|
Napi::Value value = GetReferenceValue(env, out.ref);
|
|
1092
1152
|
RG_ASSERT(!value.IsEmpty());
|
|
1093
1153
|
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1154
|
+
switch (out.kind) {
|
|
1155
|
+
case OutArgument::Kind::Array: {
|
|
1156
|
+
RG_ASSERT(value.IsArray());
|
|
1157
|
+
|
|
1158
|
+
Napi::Array array(env, value);
|
|
1159
|
+
DecodeNormalArray(array, out.ptr, out.type);
|
|
1160
|
+
} break;
|
|
1161
|
+
|
|
1162
|
+
case OutArgument::Kind::Buffer: {
|
|
1163
|
+
RG_ASSERT(IsRawBuffer(value));
|
|
1164
|
+
|
|
1165
|
+
Span<uint8_t> buffer = GetRawBuffer(value);
|
|
1166
|
+
DecodeBuffer(buffer, out.ptr, out.type);
|
|
1167
|
+
} break;
|
|
1168
|
+
|
|
1169
|
+
case OutArgument::Kind::String: {
|
|
1170
|
+
Napi::Array array(env, value);
|
|
1171
|
+
|
|
1172
|
+
RG_ASSERT(array.IsArray());
|
|
1173
|
+
RG_ASSERT(array.Length() == 1);
|
|
1174
|
+
|
|
1175
|
+
Size len = strnlen((const char *)out.ptr, out.max_len);
|
|
1176
|
+
Napi::String str = Napi::String::New(env, (const char *)out.ptr, len);
|
|
1177
|
+
|
|
1178
|
+
array.Set(0u, str);
|
|
1179
|
+
} break;
|
|
1180
|
+
|
|
1181
|
+
case OutArgument::Kind::String16: {
|
|
1182
|
+
Napi::Array array(env, value);
|
|
1183
|
+
|
|
1184
|
+
RG_ASSERT(array.IsArray());
|
|
1185
|
+
RG_ASSERT(array.Length() == 1);
|
|
1186
|
+
|
|
1187
|
+
Size len = WideStringLength((const char16_t *)out.ptr, out.max_len);
|
|
1188
|
+
Napi::String str = Napi::String::New(env, (const char16_t *)out.ptr, len);
|
|
1189
|
+
|
|
1190
|
+
array.Set(0u, str);
|
|
1191
|
+
} break;
|
|
1192
|
+
|
|
1193
|
+
case OutArgument::Kind::Object: {
|
|
1194
|
+
Napi::Object obj = value.As<Napi::Object>();
|
|
1195
|
+
|
|
1196
|
+
if (CheckValueTag(instance, value, &MagicUnionMarker)) {
|
|
1197
|
+
MagicUnion *u = MagicUnion::Unwrap(obj);
|
|
1198
|
+
u->SetRaw(out.ptr);
|
|
1199
|
+
} else {
|
|
1200
|
+
DecodeObject(obj, out.ptr, out.type);
|
|
1201
|
+
}
|
|
1202
|
+
} break;
|
|
1109
1203
|
}
|
|
1110
1204
|
}
|
|
1111
1205
|
}
|
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
|
}
|
|
@@ -723,18 +725,25 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
|
|
|
723
725
|
return WrapType(env, instance, type);
|
|
724
726
|
}
|
|
725
727
|
|
|
726
|
-
static inline bool
|
|
728
|
+
static inline bool GetExternalPointer(Napi::Env env, Napi::Value value, void **out_ptr)
|
|
727
729
|
{
|
|
728
730
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
729
731
|
|
|
730
|
-
if (
|
|
731
|
-
|
|
732
|
-
|
|
732
|
+
if (IsNullOrUndefined(value)) {
|
|
733
|
+
*out_ptr = 0;
|
|
734
|
+
return true;
|
|
735
|
+
} else if (value.IsExternal() && !CheckValueTag(instance, value, &TypeInfoMarker) &&
|
|
736
|
+
!CheckValueTag(instance, value, &CastMarker) &&
|
|
737
|
+
!CheckValueTag(instance, value, &MagicUnionMarker)) {
|
|
738
|
+
Napi::External<void> external = value.As<Napi::External<void>>();
|
|
739
|
+
void *ptr = external.Data();
|
|
740
|
+
|
|
741
|
+
*out_ptr = ptr;
|
|
742
|
+
return true;
|
|
743
|
+
} else {
|
|
733
744
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected external pointer", GetValueType(instance, value));
|
|
734
745
|
return false;
|
|
735
746
|
}
|
|
736
|
-
|
|
737
|
-
return true;
|
|
738
747
|
}
|
|
739
748
|
|
|
740
749
|
static Napi::Value CallFree(const Napi::CallbackInfo &info)
|
|
@@ -745,11 +754,10 @@ static Napi::Value CallFree(const Napi::CallbackInfo &info)
|
|
|
745
754
|
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
|
|
746
755
|
return env.Null();
|
|
747
756
|
}
|
|
748
|
-
if (!CheckExternalPointer(env, info[0]))
|
|
749
|
-
return env.Null();
|
|
750
757
|
|
|
751
|
-
|
|
752
|
-
|
|
758
|
+
void *ptr = nullptr;
|
|
759
|
+
if (!GetExternalPointer(env, info[0], &ptr))
|
|
760
|
+
return env.Null();
|
|
753
761
|
|
|
754
762
|
free(ptr);
|
|
755
763
|
|
|
@@ -1976,8 +1984,10 @@ static Napi::Value CastValue(const Napi::CallbackInfo &info)
|
|
|
1976
1984
|
const TypeInfo *type = ResolveType(info[1]);
|
|
1977
1985
|
if (RG_UNLIKELY(!type))
|
|
1978
1986
|
return env.Null();
|
|
1979
|
-
if (type->primitive != PrimitiveKind::Pointer
|
|
1980
|
-
|
|
1987
|
+
if (type->primitive != PrimitiveKind::Pointer &&
|
|
1988
|
+
type->primitive != PrimitiveKind::String &&
|
|
1989
|
+
type->primitive != PrimitiveKind::String16) {
|
|
1990
|
+
ThrowError<Napi::TypeError>(env, "Only pointer or string types can be used for casting");
|
|
1981
1991
|
return env.Null();
|
|
1982
1992
|
}
|
|
1983
1993
|
|
|
@@ -2030,11 +2040,10 @@ static Napi::Value GetPointerAddress(const Napi::CallbackInfo &info)
|
|
|
2030
2040
|
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
|
|
2031
2041
|
return env.Null();
|
|
2032
2042
|
}
|
|
2033
|
-
if (!CheckExternalPointer(env, info[0]))
|
|
2034
|
-
return env.Null();
|
|
2035
2043
|
|
|
2036
|
-
|
|
2037
|
-
|
|
2044
|
+
void *ptr = nullptr;
|
|
2045
|
+
if (!GetExternalPointer(env, info[0], &ptr))
|
|
2046
|
+
return env.Null();
|
|
2038
2047
|
|
|
2039
2048
|
uint64_t ptr64 = (uint64_t)(uintptr_t)ptr;
|
|
2040
2049
|
Napi::BigInt bigint = Napi::BigInt::New(env, ptr64);
|
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);
|
|
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
|
|
Binary file
|
|
Binary file
|