koffi 2.3.1 → 2.3.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.
- package/CHANGELOG.md +13 -0
- package/doc/misc.md +6 -0
- package/package.json +3 -16
- package/src/cnoke/LICENSE.txt +165 -0
- package/src/cnoke/README.md +97 -0
- package/src/cnoke/assets/FindCNoke.cmake +71 -0
- package/src/cnoke/assets/win_delay_hook.c +34 -0
- package/src/cnoke/cnoke.js +968 -0
- package/src/cnoke/package.json +25 -0
- package/src/koffi/build/2.3.2/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.2/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.2/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.2/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.2/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.2/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.3.2/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.2/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.2/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.3.2/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.2/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.2/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.2/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.2/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.2/koffi_win32_x64.tar.gz +0 -0
- package/src/koffi/src/call.cc +0 -4
- package/src/koffi/src/ffi.cc +89 -87
- package/src/koffi/src/ffi.hh +13 -7
- package/src/koffi/src/index.d.ts +10 -1
- package/src/koffi/src/parser.cc +12 -10
- package/src/koffi/src/util.cc +80 -35
- package/src/koffi/src/util.hh +1 -1
- package/src/koffi/build/2.3.1/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.1/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.1/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.1/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.1/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.1/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.3.1/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.1/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.1/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.3.1/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.1/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.1/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.1/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.1/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.1/koffi_win32_x64.tar.gz +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cnoke",
|
|
3
|
+
"version": "3.2.2",
|
|
4
|
+
"description": "Build native Node addons based on CMake, without extra dependency",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"native",
|
|
7
|
+
"addon",
|
|
8
|
+
"cmake",
|
|
9
|
+
"c",
|
|
10
|
+
"c++"
|
|
11
|
+
],
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/Koromix/rygel.git"
|
|
15
|
+
},
|
|
16
|
+
"author": "Niels Martignène <niels.martignene@protonmail.com>",
|
|
17
|
+
"bin": "cnoke.js",
|
|
18
|
+
"license": "LGPL-3.0",
|
|
19
|
+
"files": [
|
|
20
|
+
"cnoke.js",
|
|
21
|
+
"LICENSE.txt",
|
|
22
|
+
"README.md",
|
|
23
|
+
"assets"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
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/src/koffi/src/call.cc
CHANGED
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -122,13 +122,8 @@ static Napi::Value GetSetConfig(const Napi::CallbackInfo &info)
|
|
|
122
122
|
return env.Null();
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
Size async_stack_size = instance->async_stack_size;
|
|
128
|
-
Size async_heap_size = instance->async_heap_size;
|
|
129
|
-
int resident_async_pools = instance->resident_async_pools;
|
|
130
|
-
int max_async_calls = resident_async_pools + instance->max_temporaries;
|
|
131
|
-
Size max_type_size = instance->max_type_size;
|
|
125
|
+
decltype(instance->config) new_config = instance->config;
|
|
126
|
+
int max_async_calls = new_config.resident_async_pools + new_config.max_temporaries;
|
|
132
127
|
|
|
133
128
|
Napi::Object obj = info[0].As<Napi::Object>();
|
|
134
129
|
Napi::Array keys = obj.GetPropertyNames();
|
|
@@ -138,25 +133,25 @@ static Napi::Value GetSetConfig(const Napi::CallbackInfo &info)
|
|
|
138
133
|
Napi::Value value = obj[key];
|
|
139
134
|
|
|
140
135
|
if (key == "sync_stack_size") {
|
|
141
|
-
if (!ChangeMemorySize(key.c_str(), value, &sync_stack_size))
|
|
136
|
+
if (!ChangeMemorySize(key.c_str(), value, &new_config.sync_stack_size))
|
|
142
137
|
return env.Null();
|
|
143
138
|
} else if (key == "sync_heap_size") {
|
|
144
|
-
if (!ChangeMemorySize(key.c_str(), value, &sync_heap_size))
|
|
139
|
+
if (!ChangeMemorySize(key.c_str(), value, &new_config.sync_heap_size))
|
|
145
140
|
return env.Null();
|
|
146
141
|
} else if (key == "async_stack_size") {
|
|
147
|
-
if (!ChangeMemorySize(key.c_str(), value, &async_stack_size))
|
|
142
|
+
if (!ChangeMemorySize(key.c_str(), value, &new_config.async_stack_size))
|
|
148
143
|
return env.Null();
|
|
149
144
|
} else if (key == "async_heap_size") {
|
|
150
|
-
if (!ChangeMemorySize(key.c_str(), value, &async_heap_size))
|
|
145
|
+
if (!ChangeMemorySize(key.c_str(), value, &new_config.async_heap_size))
|
|
151
146
|
return env.Null();
|
|
152
147
|
} else if (key == "resident_async_pools") {
|
|
153
|
-
if (!ChangeAsyncLimit(key.c_str(), value, RG_LEN(instance->memories.data) - 1, &resident_async_pools))
|
|
148
|
+
if (!ChangeAsyncLimit(key.c_str(), value, RG_LEN(instance->memories.data) - 1, &new_config.resident_async_pools))
|
|
154
149
|
return env.Null();
|
|
155
150
|
} else if (key == "max_async_calls") {
|
|
156
151
|
if (!ChangeAsyncLimit(key.c_str(), value, MaxAsyncCalls, &max_async_calls))
|
|
157
152
|
return env.Null();
|
|
158
153
|
} else if (key == "max_type_size") {
|
|
159
|
-
if (!ChangeSize(key.c_str(), value, 32, Mebibytes(512), &max_type_size))
|
|
154
|
+
if (!ChangeSize(key.c_str(), value, 32, Mebibytes(512), &new_config.max_type_size))
|
|
160
155
|
return env.Null();
|
|
161
156
|
} else {
|
|
162
157
|
ThrowError<Napi::Error>(env, "Unexpected config member '%1'", key.c_str());
|
|
@@ -164,29 +159,36 @@ static Napi::Value GetSetConfig(const Napi::CallbackInfo &info)
|
|
|
164
159
|
}
|
|
165
160
|
}
|
|
166
161
|
|
|
167
|
-
if (max_async_calls < resident_async_pools) {
|
|
162
|
+
if (max_async_calls < new_config.resident_async_pools) {
|
|
168
163
|
ThrowError<Napi::Error>(env, "Setting max_async_calls must be >= to resident_async_pools");
|
|
169
164
|
return env.Null();
|
|
170
165
|
}
|
|
171
166
|
|
|
172
|
-
|
|
173
|
-
instance->
|
|
174
|
-
instance->async_stack_size = async_stack_size;
|
|
175
|
-
instance->async_heap_size = async_heap_size;
|
|
176
|
-
instance->resident_async_pools = resident_async_pools;
|
|
177
|
-
instance->max_temporaries = max_async_calls - resident_async_pools;
|
|
178
|
-
instance->max_type_size = max_type_size;
|
|
167
|
+
new_config.max_temporaries = max_async_calls - new_config.resident_async_pools;
|
|
168
|
+
instance->config = new_config;
|
|
179
169
|
}
|
|
180
170
|
|
|
181
171
|
Napi::Object obj = Napi::Object::New(env);
|
|
182
172
|
|
|
183
|
-
obj.Set("sync_stack_size", instance->sync_stack_size);
|
|
184
|
-
obj.Set("sync_heap_size", instance->sync_heap_size);
|
|
185
|
-
obj.Set("async_stack_size", instance->async_stack_size);
|
|
186
|
-
obj.Set("async_heap_size", instance->async_heap_size);
|
|
187
|
-
obj.Set("resident_async_pools", instance->resident_async_pools);
|
|
188
|
-
obj.Set("max_async_calls", instance->resident_async_pools + instance->max_temporaries);
|
|
189
|
-
obj.Set("max_type_size", instance->max_type_size);
|
|
173
|
+
obj.Set("sync_stack_size", instance->config.sync_stack_size);
|
|
174
|
+
obj.Set("sync_heap_size", instance->config.sync_heap_size);
|
|
175
|
+
obj.Set("async_stack_size", instance->config.async_stack_size);
|
|
176
|
+
obj.Set("async_heap_size", instance->config.async_heap_size);
|
|
177
|
+
obj.Set("resident_async_pools", instance->config.resident_async_pools);
|
|
178
|
+
obj.Set("max_async_calls", instance->config.resident_async_pools + instance->config.max_temporaries);
|
|
179
|
+
obj.Set("max_type_size", instance->config.max_type_size);
|
|
180
|
+
|
|
181
|
+
return obj;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
static Napi::Value GetStats(const Napi::CallbackInfo &info)
|
|
185
|
+
{
|
|
186
|
+
Napi::Env env = info.Env();
|
|
187
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
188
|
+
|
|
189
|
+
Napi::Object obj = Napi::Object::New(env);
|
|
190
|
+
|
|
191
|
+
obj.Set("disposed", instance->stats.disposed);
|
|
190
192
|
|
|
191
193
|
return obj;
|
|
192
194
|
}
|
|
@@ -197,6 +199,14 @@ static inline bool CheckAlignment(int64_t align)
|
|
|
197
199
|
return valid;
|
|
198
200
|
}
|
|
199
201
|
|
|
202
|
+
static inline Napi::External<TypeInfo> WrapType(Napi::Env env, InstanceData *instance, const TypeInfo *type)
|
|
203
|
+
{
|
|
204
|
+
Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, (TypeInfo *)type);
|
|
205
|
+
SetValueTag(instance, external, &TypeInfoMarker);
|
|
206
|
+
|
|
207
|
+
return external;
|
|
208
|
+
}
|
|
209
|
+
|
|
200
210
|
static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
201
211
|
{
|
|
202
212
|
Napi::Env env = info.Env();
|
|
@@ -277,7 +287,7 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
277
287
|
size = member.offset + member.type->size;
|
|
278
288
|
type->align = std::max(type->align, align);
|
|
279
289
|
|
|
280
|
-
if (size > instance->max_type_size) {
|
|
290
|
+
if (size > instance->config.max_type_size) {
|
|
281
291
|
ThrowError<Napi::Error>(env, "Struct '%1' size is too high (max = %2)", type->name, FmtMemSize(size));
|
|
282
292
|
return env.Null();
|
|
283
293
|
}
|
|
@@ -312,10 +322,7 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
312
322
|
}
|
|
313
323
|
err_guard.Disable();
|
|
314
324
|
|
|
315
|
-
|
|
316
|
-
SetValueTag(instance, external, &TypeInfoMarker);
|
|
317
|
-
|
|
318
|
-
return external;
|
|
325
|
+
return WrapType(env, instance, type);
|
|
319
326
|
}
|
|
320
327
|
|
|
321
328
|
static Napi::Value CreatePaddedStructType(const Napi::CallbackInfo &info)
|
|
@@ -363,10 +370,7 @@ static Napi::Value CreateOpaqueType(const Napi::CallbackInfo &info)
|
|
|
363
370
|
}
|
|
364
371
|
err_guard.Disable();
|
|
365
372
|
|
|
366
|
-
|
|
367
|
-
SetValueTag(instance, external, &TypeInfoMarker);
|
|
368
|
-
|
|
369
|
-
return external;
|
|
373
|
+
return WrapType(env, instance, type);
|
|
370
374
|
}
|
|
371
375
|
|
|
372
376
|
static Napi::Value CreatePointerType(const Napi::CallbackInfo &info)
|
|
@@ -436,10 +440,7 @@ static Napi::Value CreatePointerType(const Napi::CallbackInfo &info)
|
|
|
436
440
|
type = copy;
|
|
437
441
|
}
|
|
438
442
|
|
|
439
|
-
|
|
440
|
-
SetValueTag(instance, external, &TypeInfoMarker);
|
|
441
|
-
|
|
442
|
-
return external;
|
|
443
|
+
return WrapType(env, instance, type);
|
|
443
444
|
}
|
|
444
445
|
|
|
445
446
|
static Napi::Value EncodePointerDirection(const Napi::CallbackInfo &info, int directions)
|
|
@@ -463,13 +464,10 @@ static Napi::Value EncodePointerDirection(const Napi::CallbackInfo &info, int di
|
|
|
463
464
|
return env.Null();
|
|
464
465
|
}
|
|
465
466
|
|
|
466
|
-
//
|
|
467
|
-
TypeInfo *marked = (TypeInfo *)((uint8_t *)type + directions - 1);
|
|
468
|
-
|
|
469
|
-
Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, marked);
|
|
470
|
-
SetValueTag(instance, external, &TypeInfoMarker);
|
|
467
|
+
// Embed direction in unused pointer bits
|
|
468
|
+
const TypeInfo *marked = (const TypeInfo *)((uint8_t *)type + directions - 1);
|
|
471
469
|
|
|
472
|
-
return
|
|
470
|
+
return WrapType(env, instance, marked);
|
|
473
471
|
}
|
|
474
472
|
|
|
475
473
|
static Napi::Value MarkIn(const Napi::CallbackInfo &info)
|
|
@@ -543,10 +541,16 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
|
|
|
543
541
|
};
|
|
544
542
|
|
|
545
543
|
ref.Call(self, RG_LEN(args), args);
|
|
544
|
+
instance->stats.disposed++;
|
|
546
545
|
};
|
|
547
546
|
dispose_func = func;
|
|
548
547
|
} else {
|
|
549
|
-
dispose = [](Napi::Env, const TypeInfo *, const void *ptr) {
|
|
548
|
+
dispose = [](Napi::Env env, const TypeInfo *, const void *ptr) {
|
|
549
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
550
|
+
|
|
551
|
+
free((void *)ptr);
|
|
552
|
+
instance->stats.disposed++;
|
|
553
|
+
};
|
|
550
554
|
}
|
|
551
555
|
|
|
552
556
|
TypeInfo *type = instance->types.AppendDefault();
|
|
@@ -570,10 +574,7 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
|
|
|
570
574
|
}
|
|
571
575
|
err_guard.Disable();
|
|
572
576
|
|
|
573
|
-
|
|
574
|
-
SetValueTag(instance, external, &TypeInfoMarker);
|
|
575
|
-
|
|
576
|
-
return external;
|
|
577
|
+
return WrapType(env, instance, type);
|
|
577
578
|
}
|
|
578
579
|
|
|
579
580
|
static Napi::Value CallFree(const Napi::CallbackInfo &info)
|
|
@@ -582,7 +583,7 @@ static Napi::Value CallFree(const Napi::CallbackInfo &info)
|
|
|
582
583
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
583
584
|
|
|
584
585
|
if (info.Length() < 1) {
|
|
585
|
-
ThrowError<Napi::TypeError>(env, "Expected 1
|
|
586
|
+
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
|
|
586
587
|
return env.Null();
|
|
587
588
|
}
|
|
588
589
|
if (!info[0].IsExternal() || CheckValueTag(instance, info[0], &TypeInfoMarker)) {
|
|
@@ -621,8 +622,8 @@ static Napi::Value CreateArrayType(const Napi::CallbackInfo &info)
|
|
|
621
622
|
ThrowError<Napi::TypeError>(env, "Array length must be positive and non-zero");
|
|
622
623
|
return env.Null();
|
|
623
624
|
}
|
|
624
|
-
if (len > instance->max_type_size / ref->size) {
|
|
625
|
-
ThrowError<Napi::TypeError>(env, "Array length is too high (max = %1)", instance->max_type_size / ref->size);
|
|
625
|
+
if (len > instance->config.max_type_size / ref->size) {
|
|
626
|
+
ThrowError<Napi::TypeError>(env, "Array length is too high (max = %1)", instance->config.max_type_size / ref->size);
|
|
626
627
|
return env.Null();
|
|
627
628
|
}
|
|
628
629
|
|
|
@@ -658,10 +659,7 @@ static Napi::Value CreateArrayType(const Napi::CallbackInfo &info)
|
|
|
658
659
|
type = MakeArrayType(instance, ref, len);
|
|
659
660
|
}
|
|
660
661
|
|
|
661
|
-
|
|
662
|
-
SetValueTag(instance, external, &TypeInfoMarker);
|
|
663
|
-
|
|
664
|
-
return external;
|
|
662
|
+
return WrapType(env, instance, type);
|
|
665
663
|
}
|
|
666
664
|
|
|
667
665
|
static bool ParseClassicFunction(Napi::Env env, Napi::String name, Napi::Value ret,
|
|
@@ -786,10 +784,7 @@ static Napi::Value CreateCallbackType(const Napi::CallbackInfo &info)
|
|
|
786
784
|
|
|
787
785
|
instance->types_map.Set(type->name, type);
|
|
788
786
|
|
|
789
|
-
|
|
790
|
-
SetValueTag(instance, external, &TypeInfoMarker);
|
|
791
|
-
|
|
792
|
-
return external;
|
|
787
|
+
return WrapType(env, instance, type);
|
|
793
788
|
}
|
|
794
789
|
|
|
795
790
|
static Napi::Value CreateTypeAlias(const Napi::CallbackInfo &info)
|
|
@@ -821,10 +816,7 @@ static Napi::Value CreateTypeAlias(const Napi::CallbackInfo &info)
|
|
|
821
816
|
return env.Null();
|
|
822
817
|
}
|
|
823
818
|
|
|
824
|
-
|
|
825
|
-
SetValueTag(instance, external, &TypeInfoMarker);
|
|
826
|
-
|
|
827
|
-
return external;
|
|
819
|
+
return WrapType(env, instance, type);
|
|
828
820
|
}
|
|
829
821
|
|
|
830
822
|
static Napi::Value GetTypeSize(const Napi::CallbackInfo &info)
|
|
@@ -907,10 +899,7 @@ static Napi::Value GetResolvedType(const Napi::CallbackInfo &info)
|
|
|
907
899
|
if (!type)
|
|
908
900
|
return env.Null();
|
|
909
901
|
|
|
910
|
-
|
|
911
|
-
SetValueTag(instance, external, &TypeInfoMarker);
|
|
912
|
-
|
|
913
|
-
return external;
|
|
902
|
+
return WrapType(env, instance, type);
|
|
914
903
|
}
|
|
915
904
|
|
|
916
905
|
static Napi::Value GetTypeDefinition(const Napi::CallbackInfo &info)
|
|
@@ -934,6 +923,7 @@ static Napi::Value GetTypeDefinition(const Napi::CallbackInfo &info)
|
|
|
934
923
|
defn.Set("primitive", PrimitiveKindNames[(int)type->primitive]);
|
|
935
924
|
defn.Set("size", Napi::Number::New(env, (double)type->size));
|
|
936
925
|
defn.Set("alignment", Napi::Number::New(env, (double)type->align));
|
|
926
|
+
defn.Set("disposable", Napi::Boolean::New(env, !!type->dispose));
|
|
937
927
|
|
|
938
928
|
switch (type->primitive) {
|
|
939
929
|
case PrimitiveKind::Void:
|
|
@@ -964,10 +954,8 @@ static Napi::Value GetTypeDefinition(const Napi::CallbackInfo &info)
|
|
|
964
954
|
defn.Set("length", Napi::Number::New(env, (double)len));
|
|
965
955
|
} [[fallthrough]];
|
|
966
956
|
case PrimitiveKind::Pointer: {
|
|
967
|
-
Napi::
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
defn.Set("ref", external);
|
|
957
|
+
Napi::Value value = WrapType(env, instance, type->ref.type);
|
|
958
|
+
defn.Set("ref", value);
|
|
971
959
|
} break;
|
|
972
960
|
case PrimitiveKind::Record: {
|
|
973
961
|
Napi::Object members = Napi::Object::New(env);
|
|
@@ -975,11 +963,8 @@ static Napi::Value GetTypeDefinition(const Napi::CallbackInfo &info)
|
|
|
975
963
|
for (const RecordMember &member: type->members) {
|
|
976
964
|
Napi::Object obj = Napi::Object::New(env);
|
|
977
965
|
|
|
978
|
-
Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, (TypeInfo *)member.type);
|
|
979
|
-
SetValueTag(instance, external, &TypeInfoMarker);
|
|
980
|
-
|
|
981
966
|
obj.Set("name", member.name);
|
|
982
|
-
obj.Set("type",
|
|
967
|
+
obj.Set("type", WrapType(env, instance, member.type));
|
|
983
968
|
obj.Set("offset", member.offset);
|
|
984
969
|
|
|
985
970
|
members.Set(member.name, obj);
|
|
@@ -1007,7 +992,7 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
|
|
|
1007
992
|
return mem;
|
|
1008
993
|
}
|
|
1009
994
|
|
|
1010
|
-
if (RG_UNLIKELY(instance->temporaries >= instance->max_temporaries))
|
|
995
|
+
if (RG_UNLIKELY(instance->temporaries >= instance->config.max_temporaries))
|
|
1011
996
|
return nullptr;
|
|
1012
997
|
|
|
1013
998
|
InstanceMemory *mem = new InstanceMemory();
|
|
@@ -1065,7 +1050,7 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
|
|
|
1065
1050
|
|
|
1066
1051
|
mem->depth = 0;
|
|
1067
1052
|
|
|
1068
|
-
if (instance->memories.len <= instance->resident_async_pools) {
|
|
1053
|
+
if (instance->memories.len <= instance->config.resident_async_pools) {
|
|
1069
1054
|
instance->memories.Append(mem);
|
|
1070
1055
|
mem->temporary = false;
|
|
1071
1056
|
} else {
|
|
@@ -1256,7 +1241,7 @@ static Napi::Value TranslateAsyncCall(const Napi::CallbackInfo &info)
|
|
|
1256
1241
|
return env.Null();
|
|
1257
1242
|
}
|
|
1258
1243
|
|
|
1259
|
-
InstanceMemory *mem = AllocateMemory(instance, instance->async_stack_size, instance->async_heap_size);
|
|
1244
|
+
InstanceMemory *mem = AllocateMemory(instance, instance->config.async_stack_size, instance->config.async_heap_size);
|
|
1260
1245
|
if (RG_UNLIKELY(!mem)) {
|
|
1261
1246
|
ThrowError<Napi::Error>(env, "Too many asynchronous calls are running");
|
|
1262
1247
|
return env.Null();
|
|
@@ -1350,6 +1335,23 @@ static Napi::Value FindLibraryFunction(const Napi::CallbackInfo &info, CallConve
|
|
|
1350
1335
|
wrapper.Set("async", async);
|
|
1351
1336
|
}
|
|
1352
1337
|
|
|
1338
|
+
// Create info object
|
|
1339
|
+
{
|
|
1340
|
+
Napi::Object meta = Napi::Object::New(env);
|
|
1341
|
+
Napi::Array arguments = Napi::Array::New(env, func->parameters.len);
|
|
1342
|
+
|
|
1343
|
+
meta.Set("name", Napi::String::New(env, func->name));
|
|
1344
|
+
meta.Set("arguments", arguments);
|
|
1345
|
+
meta.Set("result", WrapType(env, instance, func->ret.type));
|
|
1346
|
+
|
|
1347
|
+
for (Size i = 0; i < func->parameters.len; i++) {
|
|
1348
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
1349
|
+
arguments.Set((uint32_t)i, WrapType(env, instance, param.type));
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
wrapper.Set("info", meta);
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1353
1355
|
return wrapper;
|
|
1354
1356
|
}
|
|
1355
1357
|
|
|
@@ -1368,7 +1370,7 @@ static Napi::Value LoadSharedLibrary(const Napi::CallbackInfo &info)
|
|
|
1368
1370
|
}
|
|
1369
1371
|
|
|
1370
1372
|
if (!instance->memories.len) {
|
|
1371
|
-
AllocateMemory(instance, instance->sync_stack_size, instance->sync_heap_size);
|
|
1373
|
+
AllocateMemory(instance, instance->config.sync_stack_size, instance->config.sync_heap_size);
|
|
1372
1374
|
RG_ASSERT(instance->memories.len);
|
|
1373
1375
|
}
|
|
1374
1376
|
|
|
@@ -1591,8 +1593,7 @@ static void RegisterPrimitiveType(Napi::Env env, Napi::Object map, std::initiali
|
|
|
1591
1593
|
type->ref.marker = marker;
|
|
1592
1594
|
}
|
|
1593
1595
|
|
|
1594
|
-
Napi::
|
|
1595
|
-
SetValueTag(instance, external, &TypeInfoMarker);
|
|
1596
|
+
Napi::Value wrapper = WrapType(env, instance, type);
|
|
1596
1597
|
|
|
1597
1598
|
for (const char *name: names) {
|
|
1598
1599
|
bool inserted;
|
|
@@ -1600,7 +1601,7 @@ static void RegisterPrimitiveType(Napi::Env env, Napi::Object map, std::initiali
|
|
|
1600
1601
|
RG_ASSERT(inserted);
|
|
1601
1602
|
|
|
1602
1603
|
if (!EndsWith(name, "*")) {
|
|
1603
|
-
map.Set(name,
|
|
1604
|
+
map.Set(name, wrapper);
|
|
1604
1605
|
}
|
|
1605
1606
|
}
|
|
1606
1607
|
}
|
|
@@ -1974,7 +1975,7 @@ extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, Bac
|
|
|
1974
1975
|
Napi::Env env = trampoline->func.Env();
|
|
1975
1976
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
1976
1977
|
|
|
1977
|
-
InstanceMemory *mem = AllocateMemory(instance, instance->async_stack_size, instance->async_heap_size);
|
|
1978
|
+
InstanceMemory *mem = AllocateMemory(instance, instance->config.async_stack_size, instance->config.async_heap_size);
|
|
1978
1979
|
if (RG_UNLIKELY(!mem)) {
|
|
1979
1980
|
ThrowError<Napi::Error>(env, "Too many asynchronous calls are running");
|
|
1980
1981
|
return;
|
|
@@ -1993,6 +1994,7 @@ template <typename Func>
|
|
|
1993
1994
|
static void SetExports(Napi::Env env, Func func)
|
|
1994
1995
|
{
|
|
1995
1996
|
func("config", Napi::Function::New(env, GetSetConfig));
|
|
1997
|
+
func("stats", Napi::Function::New(env, GetStats));
|
|
1996
1998
|
|
|
1997
1999
|
func("struct", Napi::Function::New(env, CreatePaddedStructType));
|
|
1998
2000
|
func("pack", Napi::Function::New(env, CreatePackedStructType));
|
package/src/koffi/src/ffi.hh
CHANGED
|
@@ -264,13 +264,19 @@ struct InstanceData {
|
|
|
264
264
|
|
|
265
265
|
BlockAllocator str_alloc;
|
|
266
266
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
267
|
+
struct {
|
|
268
|
+
Size sync_stack_size = DefaultSyncStackSize;
|
|
269
|
+
Size sync_heap_size = DefaultSyncHeapSize;
|
|
270
|
+
Size async_stack_size = DefaultAsyncStackSize;
|
|
271
|
+
Size async_heap_size = DefaultAsyncHeapSize;
|
|
272
|
+
int resident_async_pools = DefaultResidentAsyncPools;
|
|
273
|
+
int max_temporaries = DefaultMaxAsyncCalls - DefaultResidentAsyncPools;
|
|
274
|
+
Size max_type_size = DefaultMaxTypeSize;
|
|
275
|
+
} config;
|
|
276
|
+
|
|
277
|
+
struct {
|
|
278
|
+
int64_t disposed = 0;
|
|
279
|
+
} stats;
|
|
274
280
|
};
|
|
275
281
|
RG_STATIC_ASSERT(DefaultResidentAsyncPools <= RG_LEN(InstanceData::memories.data) - 1);
|
|
276
282
|
RG_STATIC_ASSERT(DefaultMaxAsyncCalls >= DefaultResidentAsyncPools);
|
package/src/koffi/src/index.d.ts
CHANGED
|
@@ -25,11 +25,19 @@ declare module 'koffi' {
|
|
|
25
25
|
primitive: string;
|
|
26
26
|
size: number;
|
|
27
27
|
alignment: number;
|
|
28
|
+
disposable: boolean;
|
|
28
29
|
length: number;
|
|
29
30
|
ref: IKoffiCType;
|
|
30
31
|
members: Record<string, { name: string, type: IKoffiCType, offset: number }>;
|
|
31
32
|
};
|
|
32
|
-
type KoffiFunction = Function & {
|
|
33
|
+
type KoffiFunction = Function & {
|
|
34
|
+
async: Function;
|
|
35
|
+
info: {
|
|
36
|
+
name: string,
|
|
37
|
+
arguments: IKoffiCType[],
|
|
38
|
+
result: IKoffiCType
|
|
39
|
+
};
|
|
40
|
+
};
|
|
33
41
|
|
|
34
42
|
export interface IKoffiLib {
|
|
35
43
|
func(definition: string): KoffiFunction;
|
|
@@ -92,4 +100,5 @@ declare module 'koffi' {
|
|
|
92
100
|
|
|
93
101
|
export function config(): Record<string, unknown>;
|
|
94
102
|
export function config(cfg: Record<string, unknown>): Record<string, unknown>;
|
|
103
|
+
export function stats(): Record<string, unknown>;
|
|
95
104
|
}
|
package/src/koffi/src/parser.cc
CHANGED
|
@@ -141,34 +141,36 @@ const TypeInfo *PrototypeParser::ParseType()
|
|
|
141
141
|
|
|
142
142
|
if (offset >= tokens.len) {
|
|
143
143
|
MarkError("Unexpected end of prototype, expected type");
|
|
144
|
-
return instance->
|
|
144
|
+
return instance->void_type;
|
|
145
145
|
} else if (!IsIdentifier(tokens[offset])) {
|
|
146
146
|
MarkError("Unexpected token '%1', expected type", tokens[offset]);
|
|
147
|
-
return instance->
|
|
147
|
+
return instance->void_type;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
while (offset < tokens.len &&
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
offset
|
|
150
|
+
while (++offset < tokens.len && IsIdentifier(tokens[offset]));
|
|
151
|
+
offset--;
|
|
152
|
+
while (++offset < tokens.len && (tokens[offset] == '*' ||
|
|
153
|
+
tokens[offset] == '!' ||
|
|
154
|
+
tokens[offset] == "const"));
|
|
155
|
+
offset--;
|
|
156
156
|
|
|
157
157
|
while (offset >= start) {
|
|
158
158
|
Span<const char> str = MakeSpan(tokens[start].ptr, tokens[offset].end() - tokens[start].ptr);
|
|
159
|
-
const TypeInfo *type = ResolveType(
|
|
159
|
+
const TypeInfo *type = ResolveType(env, str);
|
|
160
160
|
|
|
161
161
|
if (type) {
|
|
162
162
|
offset++;
|
|
163
163
|
return type;
|
|
164
164
|
}
|
|
165
|
+
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
166
|
+
return instance->void_type;
|
|
165
167
|
|
|
166
168
|
offset--;
|
|
167
169
|
}
|
|
168
170
|
offset = start;
|
|
169
171
|
|
|
170
172
|
MarkError("Unknown or invalid type name '%1'", tokens[offset]);
|
|
171
|
-
return instance->
|
|
173
|
+
return instance->void_type;
|
|
172
174
|
}
|
|
173
175
|
|
|
174
176
|
const char *PrototypeParser::ParseIdentifier()
|