koffi 1.3.2 → 1.3.5
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/CMakeLists.txt +27 -3
- package/ChangeLog.md +46 -14
- package/build/qemu/1.3.5/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_win32_x64.tar.gz +0 -0
- package/doc/_static/perf_linux_20220623.png +0 -0
- package/doc/_static/perf_linux_20220623_2.png +0 -0
- package/doc/_static/perf_windows_20220623.png +0 -0
- package/doc/_static/perf_windows_20220623_2.png +0 -0
- package/doc/benchmarks.md +40 -36
- package/doc/benchmarks.xlsx +0 -0
- package/doc/changes.md +2 -0
- package/doc/conf.py +10 -3
- package/doc/contribute.md +16 -0
- package/doc/dist/doctrees/benchmarks.doctree +0 -0
- package/doc/dist/doctrees/changes.doctree +0 -0
- package/doc/dist/doctrees/contribute.doctree +0 -0
- package/doc/dist/doctrees/environment.pickle +0 -0
- package/doc/dist/doctrees/functions.doctree +0 -0
- package/doc/dist/doctrees/index.doctree +0 -0
- package/doc/dist/doctrees/memory.doctree +0 -0
- package/doc/dist/doctrees/platforms.doctree +0 -0
- package/doc/dist/doctrees/start.doctree +0 -0
- package/doc/dist/doctrees/types.doctree +0 -0
- package/doc/dist/html/_sources/benchmarks.md.txt +40 -36
- package/doc/dist/html/_sources/changes.md.txt +2 -0
- package/doc/dist/html/_sources/contribute.md.txt +16 -0
- package/doc/dist/html/_sources/functions.md.txt +18 -14
- package/doc/dist/html/_sources/index.rst.txt +2 -1
- package/doc/dist/html/_sources/memory.md.txt +6 -3
- package/doc/dist/html/_sources/platforms.md.txt +2 -0
- package/doc/dist/html/_sources/start.md.txt +3 -3
- package/doc/dist/html/_sources/types.md.txt +10 -8
- package/doc/dist/html/_static/perf_linux_20220623.png +0 -0
- package/doc/dist/html/_static/perf_linux_20220623_2.png +0 -0
- package/doc/dist/html/_static/perf_windows_20220623.png +0 -0
- package/doc/dist/html/_static/perf_windows_20220623_2.png +0 -0
- package/doc/dist/html/_static/pygments.css +54 -54
- package/doc/dist/html/benchmarks.html +52 -20
- package/doc/dist/html/changes.html +391 -0
- package/doc/dist/html/contribute.html +24 -2
- package/doc/dist/html/functions.html +83 -84
- package/doc/dist/html/genindex.html +1 -0
- package/doc/dist/html/index.html +18 -3
- package/doc/dist/html/memory.html +11 -5
- package/doc/dist/html/objects.inv +0 -0
- package/doc/dist/html/platforms.html +3 -1
- package/doc/dist/html/search.html +1 -0
- package/doc/dist/html/searchindex.js +1 -1
- package/doc/dist/html/start.html +48 -47
- package/doc/dist/html/types.html +161 -159
- package/doc/functions.md +18 -14
- package/doc/index.rst +2 -1
- package/doc/memory.md +6 -3
- package/doc/platforms.md +2 -0
- package/doc/start.md +3 -3
- package/doc/types.md +10 -8
- package/package.json +2 -2
- package/qemu/qemu.js +1 -0
- package/qemu/registry/machines.json +6 -11
- package/src/abi_arm32.cc +9 -9
- package/src/abi_arm64.cc +9 -9
- package/src/abi_riscv64.cc +9 -9
- package/src/abi_x64_sysv.cc +9 -9
- package/src/abi_x64_win.cc +9 -9
- package/src/abi_x86.cc +9 -9
- package/src/call.cc +8 -7
- package/src/call.hh +6 -0
- package/src/ffi.cc +73 -22
- package/src/ffi.hh +11 -4
- package/src/parser.cc +1 -1
- package/src/util.hh +21 -1
- package/test/async.js +1 -1
- package/test/misc.c +20 -0
- package/test/sync.js +13 -3
- package/vendor/libcc/libcc.hh +1 -1
- package/build/qemu/1.3.2/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_win32_x64.tar.gz +0 -0
package/src/ffi.cc
CHANGED
|
@@ -43,7 +43,7 @@ namespace RG {
|
|
|
43
43
|
// Value does not matter, the tag system uses memory addresses
|
|
44
44
|
const int TypeInfoMarker = 0xDEADBEEF;
|
|
45
45
|
|
|
46
|
-
static bool ChangeMemorySize(Napi::Value value, Size *out_size)
|
|
46
|
+
static bool ChangeMemorySize(const char *name, Napi::Value value, Size *out_size)
|
|
47
47
|
{
|
|
48
48
|
const Size MinSize = Kibibytes(1);
|
|
49
49
|
const Size MaxSize = Mebibytes(16);
|
|
@@ -51,14 +51,16 @@ static bool ChangeMemorySize(Napi::Value value, Size *out_size)
|
|
|
51
51
|
Napi::Env env = value.Env();
|
|
52
52
|
|
|
53
53
|
if (!value.IsNumber()) {
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
55
|
+
|
|
56
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for '%2', expected number", GetValueType(instance, value), name);
|
|
57
|
+
return false;
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
int64_t size = value.As<Napi::Number>().Int64Value();
|
|
59
61
|
|
|
60
62
|
if (size < MinSize || size > MaxSize) {
|
|
61
|
-
ThrowError<Napi::Error>(env, "
|
|
63
|
+
ThrowError<Napi::Error>(env, "Setting '%1' must be between %2 and %3", name, FmtMemSize(MinSize), FmtMemSize(MaxSize));
|
|
62
64
|
return false;
|
|
63
65
|
}
|
|
64
66
|
|
|
@@ -66,6 +68,28 @@ static bool ChangeMemorySize(Napi::Value value, Size *out_size)
|
|
|
66
68
|
return true;
|
|
67
69
|
}
|
|
68
70
|
|
|
71
|
+
static bool ChangeAsyncLimit(const char *name, Napi::Value value, int max, int *out_limit)
|
|
72
|
+
{
|
|
73
|
+
Napi::Env env = value.Env();
|
|
74
|
+
|
|
75
|
+
if (!value.IsNumber()) {
|
|
76
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
77
|
+
|
|
78
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for '%2', expected number", GetValueType(instance, value), name);
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
int64_t n = value.As<Napi::Number>().Int64Value();
|
|
83
|
+
|
|
84
|
+
if (n < 0 || n > max) {
|
|
85
|
+
ThrowError<Napi::Error>(env, "Setting '%1' must be between 0 and %2", name, max);
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
*out_limit = (int)n;
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
|
|
69
93
|
static Napi::Value GetSetConfig(const Napi::CallbackInfo &info)
|
|
70
94
|
{
|
|
71
95
|
Napi::Env env = info.Env();
|
|
@@ -82,6 +106,13 @@ static Napi::Value GetSetConfig(const Napi::CallbackInfo &info)
|
|
|
82
106
|
return env.Null();
|
|
83
107
|
}
|
|
84
108
|
|
|
109
|
+
Size sync_stack_size = instance->sync_stack_size;
|
|
110
|
+
Size sync_heap_size = instance->sync_heap_size;
|
|
111
|
+
Size async_stack_size = instance->async_stack_size;
|
|
112
|
+
Size async_heap_size = instance->async_heap_size;
|
|
113
|
+
int resident_async_pools = instance->resident_async_pools;
|
|
114
|
+
int max_async_calls = resident_async_pools + instance->max_temporaries;
|
|
115
|
+
|
|
85
116
|
Napi::Object obj = info[0].As<Napi::Object>();
|
|
86
117
|
Napi::Array keys = obj.GetPropertyNames();
|
|
87
118
|
|
|
@@ -90,38 +121,40 @@ static Napi::Value GetSetConfig(const Napi::CallbackInfo &info)
|
|
|
90
121
|
Napi::Value value = obj[key];
|
|
91
122
|
|
|
92
123
|
if (key == "sync_stack_size") {
|
|
93
|
-
if (!ChangeMemorySize(value, &
|
|
124
|
+
if (!ChangeMemorySize(key.c_str(), value, &sync_stack_size))
|
|
94
125
|
return env.Null();
|
|
95
126
|
} else if (key == "sync_heap_size") {
|
|
96
|
-
if (!ChangeMemorySize(value, &
|
|
127
|
+
if (!ChangeMemorySize(key.c_str(), value, &sync_heap_size))
|
|
97
128
|
return env.Null();
|
|
98
129
|
} else if (key == "async_stack_size") {
|
|
99
|
-
if (!ChangeMemorySize(value, &
|
|
130
|
+
if (!ChangeMemorySize(key.c_str(), value, &async_stack_size))
|
|
100
131
|
return env.Null();
|
|
101
132
|
} else if (key == "async_heap_size") {
|
|
102
|
-
if (!ChangeMemorySize(value, &
|
|
133
|
+
if (!ChangeMemorySize(key.c_str(), value, &async_heap_size))
|
|
103
134
|
return env.Null();
|
|
104
135
|
} else if (key == "resident_async_pools") {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (!value.IsNumber()) {
|
|
108
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for resident_async_pools, expected number");
|
|
136
|
+
if (!ChangeAsyncLimit(key.c_str(), value, RG_LEN(instance->memories.data) - 1, &resident_async_pools))
|
|
109
137
|
return env.Null();
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
int64_t n = value.As<Napi::Number>().Int64Value();
|
|
113
|
-
|
|
114
|
-
if (n < 0 || n > RG_LEN(instance->memories.data)) {
|
|
115
|
-
ThrowError<Napi::Error>(env, "Parameter resident_async_pools must be between 0 and %1", RG_LEN(instance->memories.data));
|
|
138
|
+
} else if (key == "max_async_calls") {
|
|
139
|
+
if (!ChangeAsyncLimit(key.c_str(), value, MaxAsyncCalls, &max_async_calls))
|
|
116
140
|
return env.Null();
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
instance->resident_async_pools = (int)n;
|
|
120
141
|
} else {
|
|
121
142
|
ThrowError<Napi::Error>(env, "Unexpected config member '%1'", key.c_str());
|
|
122
143
|
return env.Null();
|
|
123
144
|
}
|
|
124
145
|
}
|
|
146
|
+
|
|
147
|
+
if (max_async_calls < resident_async_pools) {
|
|
148
|
+
ThrowError<Napi::Error>(env, "Setting max_async_calls must be >= to resident_async_pools");
|
|
149
|
+
return env.Null();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
instance->sync_stack_size = sync_stack_size;
|
|
153
|
+
instance->sync_heap_size = sync_heap_size;
|
|
154
|
+
instance->async_stack_size = async_stack_size;
|
|
155
|
+
instance->async_heap_size = async_heap_size;
|
|
156
|
+
instance->resident_async_pools = resident_async_pools;
|
|
157
|
+
instance->max_temporaries = max_async_calls - resident_async_pools;
|
|
125
158
|
}
|
|
126
159
|
|
|
127
160
|
Napi::Object obj = Napi::Object::New(env);
|
|
@@ -131,6 +164,7 @@ static Napi::Value GetSetConfig(const Napi::CallbackInfo &info)
|
|
|
131
164
|
obj.Set("async_stack_size", instance->async_stack_size);
|
|
132
165
|
obj.Set("async_heap_size", instance->async_heap_size);
|
|
133
166
|
obj.Set("resident_async_pools", instance->resident_async_pools);
|
|
167
|
+
obj.Set("max_async_calls", instance->resident_async_pools + instance->max_temporaries);
|
|
134
168
|
|
|
135
169
|
return obj;
|
|
136
170
|
}
|
|
@@ -616,6 +650,9 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
|
|
|
616
650
|
return mem;
|
|
617
651
|
}
|
|
618
652
|
|
|
653
|
+
if (RG_UNLIKELY(instance->temporaries >= instance->max_temporaries))
|
|
654
|
+
return nullptr;
|
|
655
|
+
|
|
619
656
|
InstanceMemory *mem = new InstanceMemory();
|
|
620
657
|
|
|
621
658
|
mem->stack.len = stack_size;
|
|
@@ -628,6 +665,11 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
|
|
|
628
665
|
#endif
|
|
629
666
|
RG_CRITICAL(mem->stack.ptr, "Failed to allocate %1 of memory", mem->stack.len);
|
|
630
667
|
|
|
668
|
+
#ifdef __OpenBSD__
|
|
669
|
+
// Make sure the SP points inside the MAP_STACK area, or (void) functions may crash on OpenBSD i386
|
|
670
|
+
mem->stack.len -= 16;
|
|
671
|
+
#endif
|
|
672
|
+
|
|
631
673
|
mem->heap.len = heap_size;
|
|
632
674
|
#ifdef _WIN32
|
|
633
675
|
mem->heap.ptr = (uint8_t *)VirtualAlloc(nullptr, mem->heap.len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
|
@@ -636,9 +678,13 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
|
|
|
636
678
|
#endif
|
|
637
679
|
RG_CRITICAL(mem->heap.ptr, "Failed to allocate %1 of memory", mem->heap.len);
|
|
638
680
|
|
|
681
|
+
mem->depth = 0;
|
|
682
|
+
|
|
639
683
|
if (instance->memories.len <= instance->resident_async_pools) {
|
|
640
684
|
instance->memories.Append(mem);
|
|
685
|
+
mem->temporary = false;
|
|
641
686
|
} else {
|
|
687
|
+
instance->temporaries++;
|
|
642
688
|
mem->temporary = true;
|
|
643
689
|
}
|
|
644
690
|
|
|
@@ -804,11 +850,15 @@ static Napi::Value TranslateAsyncCall(const Napi::CallbackInfo &info)
|
|
|
804
850
|
Napi::Function callback = info[(uint32_t)func->parameters.len].As<Napi::Function>();
|
|
805
851
|
|
|
806
852
|
if (!callback.IsFunction()) {
|
|
807
|
-
ThrowError<Napi::TypeError>(env, "Expected callback function as last
|
|
853
|
+
ThrowError<Napi::TypeError>(env, "Expected callback function as last argument, got %1", GetValueType(instance, callback));
|
|
808
854
|
return env.Null();
|
|
809
855
|
}
|
|
810
856
|
|
|
811
857
|
InstanceMemory *mem = AllocateMemory(instance, instance->async_stack_size, instance->async_heap_size);
|
|
858
|
+
if (RG_UNLIKELY(!mem)) {
|
|
859
|
+
ThrowError<Napi::Error>(env, "Too many asynchronous calls are running");
|
|
860
|
+
return env.Null();
|
|
861
|
+
}
|
|
812
862
|
AsyncCall *async = new AsyncCall(env, instance, func, mem, callback);
|
|
813
863
|
|
|
814
864
|
if (async->Prepare(info) && instance->debug) {
|
|
@@ -917,6 +967,7 @@ static Napi::Value LoadSharedLibrary(const Napi::CallbackInfo &info)
|
|
|
917
967
|
|
|
918
968
|
if (!instance->memories.len) {
|
|
919
969
|
AllocateMemory(instance, instance->sync_stack_size, instance->sync_heap_size);
|
|
970
|
+
RG_ASSERT(instance->memories.len);
|
|
920
971
|
}
|
|
921
972
|
|
|
922
973
|
// Load shared library
|
package/src/ffi.hh
CHANGED
|
@@ -21,10 +21,12 @@ namespace RG {
|
|
|
21
21
|
|
|
22
22
|
static const Size DefaultSyncStackSize = Mebibytes(1);
|
|
23
23
|
static const Size DefaultSyncHeapSize = Mebibytes(2);
|
|
24
|
-
static const Size DefaultAsyncStackSize = Kibibytes(
|
|
25
|
-
static const Size DefaultAsyncHeapSize =
|
|
24
|
+
static const Size DefaultAsyncStackSize = Kibibytes(256);
|
|
25
|
+
static const Size DefaultAsyncHeapSize = Kibibytes(512);
|
|
26
26
|
static const int DefaultResidentAsyncPools = 2;
|
|
27
|
+
static const int DefaultMaxAsyncCalls = 64;
|
|
27
28
|
|
|
29
|
+
static const int MaxAsyncCalls = 256;
|
|
28
30
|
static const Size MaxParameters = 32;
|
|
29
31
|
static const Size MaxOutParameters = 4;
|
|
30
32
|
static const Size MaxTrampolines = 16;
|
|
@@ -216,7 +218,8 @@ struct InstanceData {
|
|
|
216
218
|
bool debug;
|
|
217
219
|
uint64_t tag_lower;
|
|
218
220
|
|
|
219
|
-
LocalArray<InstanceMemory *,
|
|
221
|
+
LocalArray<InstanceMemory *, 9> memories;
|
|
222
|
+
int temporaries = 0;
|
|
220
223
|
|
|
221
224
|
TrampolineInfo trampolines[MaxTrampolines];
|
|
222
225
|
uint32_t free_trampolines = UINT32_MAX;
|
|
@@ -228,7 +231,11 @@ struct InstanceData {
|
|
|
228
231
|
Size async_stack_size = DefaultAsyncStackSize;
|
|
229
232
|
Size async_heap_size = DefaultAsyncHeapSize;
|
|
230
233
|
int resident_async_pools = DefaultResidentAsyncPools;
|
|
234
|
+
int max_temporaries = DefaultMaxAsyncCalls - DefaultResidentAsyncPools;
|
|
231
235
|
};
|
|
232
|
-
RG_STATIC_ASSERT(
|
|
236
|
+
RG_STATIC_ASSERT(DefaultResidentAsyncPools <= RG_LEN(InstanceData::memories.data) - 1);
|
|
237
|
+
RG_STATIC_ASSERT(DefaultMaxAsyncCalls >= DefaultResidentAsyncPools);
|
|
238
|
+
RG_STATIC_ASSERT(MaxAsyncCalls >= DefaultMaxAsyncCalls);
|
|
239
|
+
RG_STATIC_ASSERT(MaxTrampolines <= 16);
|
|
233
240
|
|
|
234
241
|
}
|
package/src/parser.cc
CHANGED
|
@@ -44,7 +44,7 @@ bool PrototypeParser::Parse(const char *str, FunctionInfo *out_func)
|
|
|
44
44
|
out_func->name = ParseIdentifier();
|
|
45
45
|
|
|
46
46
|
Consume("(");
|
|
47
|
-
if (offset < tokens.len && tokens[offset] != ")") {
|
|
47
|
+
if (offset < tokens.len && tokens[offset] != ")" && !Match("void")) {
|
|
48
48
|
for (;;) {
|
|
49
49
|
ParameterInfo param = {};
|
|
50
50
|
|
package/src/util.hh
CHANGED
|
@@ -89,7 +89,7 @@ static inline bool IsObject(Napi::Value value)
|
|
|
89
89
|
int GetTypedArrayType(const TypeInfo *type);
|
|
90
90
|
|
|
91
91
|
template <typename T>
|
|
92
|
-
T CopyNumber(
|
|
92
|
+
T CopyNumber(Napi::Value value)
|
|
93
93
|
{
|
|
94
94
|
RG_ASSERT(value.IsNumber() || value.IsBigInt());
|
|
95
95
|
|
|
@@ -105,6 +105,26 @@ T CopyNumber(const Napi::Value &value)
|
|
|
105
105
|
RG_UNREACHABLE();
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
static inline Napi::Value NewBigInt(Napi::Env env, int64_t value)
|
|
109
|
+
{
|
|
110
|
+
if (value <= 9007199254740992ll && value >= -9007199254740992ll) {
|
|
111
|
+
double d = (double)value;
|
|
112
|
+
return Napi::Number::New(env, d);
|
|
113
|
+
} else {
|
|
114
|
+
return Napi::BigInt::New(env, value);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
static inline Napi::Value NewBigInt(Napi::Env env, uint64_t value)
|
|
119
|
+
{
|
|
120
|
+
if (value <= 9007199254740992ull) {
|
|
121
|
+
double d = (double)value;
|
|
122
|
+
return Napi::Number::New(env, d);
|
|
123
|
+
} else {
|
|
124
|
+
return Napi::BigInt::New(env, value);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
108
128
|
int AnalyseFlat(const TypeInfo *type, FunctionRef<void(const TypeInfo *type, int offset, int count)> func);
|
|
109
129
|
|
|
110
130
|
int IsHFA(const TypeInfo *type, int min, int max);
|
package/test/async.js
CHANGED
|
@@ -51,7 +51,7 @@ async function test() {
|
|
|
51
51
|
let promises = [];
|
|
52
52
|
|
|
53
53
|
// Issue several async calls
|
|
54
|
-
for (let i = 0; i <
|
|
54
|
+
for (let i = 0; i < 32; i++) {
|
|
55
55
|
let p = new Promise((resolve, reject) => {
|
|
56
56
|
try {
|
|
57
57
|
ConcatenateToInt1.async(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7, (err, res) => {
|
package/test/misc.c
CHANGED
|
@@ -129,6 +129,26 @@ typedef struct IntContainer {
|
|
|
129
129
|
int len;
|
|
130
130
|
} IntContainer;
|
|
131
131
|
|
|
132
|
+
EXPORT int8_t GetMinusOne1(void)
|
|
133
|
+
{
|
|
134
|
+
return -1;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
EXPORT int16_t GetMinusOne2(void)
|
|
138
|
+
{
|
|
139
|
+
return -1;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
EXPORT int32_t GetMinusOne4(void)
|
|
143
|
+
{
|
|
144
|
+
return -1;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
EXPORT int64_t GetMinusOne8(void)
|
|
148
|
+
{
|
|
149
|
+
return -1;
|
|
150
|
+
}
|
|
151
|
+
|
|
132
152
|
EXPORT void FillPack1(int a, Pack1 *p)
|
|
133
153
|
{
|
|
134
154
|
p->a = a;
|
package/test/sync.js
CHANGED
|
@@ -122,6 +122,10 @@ async function test() {
|
|
|
122
122
|
let lib_filename = path.dirname(__filename) + '/build/misc' + koffi.extension;
|
|
123
123
|
let lib = koffi.load(lib_filename);
|
|
124
124
|
|
|
125
|
+
const GetMinusOne1 = lib.func('int8_t GetMinusOne1(void)');
|
|
126
|
+
const GetMinusOne2 = lib.func('int16_t GetMinusOne2(void)');
|
|
127
|
+
const GetMinusOne4 = lib.func('int32_t GetMinusOne4(void)');
|
|
128
|
+
const GetMinusOne8 = lib.func('int64_t GetMinusOne8(void)');
|
|
125
129
|
const FillPack1 = lib.func('FillPack1', 'void', ['int', koffi.out(koffi.pointer(Pack1))]);
|
|
126
130
|
const RetPack1 = lib.func('RetPack1', Pack1, ['int']);
|
|
127
131
|
const AddPack1 = lib.fastcall('AddPack1', 'void', ['int', koffi.inout(koffi.pointer(Pack1))]);
|
|
@@ -172,6 +176,12 @@ async function test() {
|
|
|
172
176
|
const FillRange = lib.func('void FillRange(int init, int step, _Out_ int *out, int len)');
|
|
173
177
|
const MultiplyIntegers = lib.func('void MultiplyIntegers(int multiplier, _Inout_ int *values, int len)');
|
|
174
178
|
|
|
179
|
+
// Simple signed value returns
|
|
180
|
+
assert.equal(GetMinusOne1(), -1);
|
|
181
|
+
assert.equal(GetMinusOne2(), -1);
|
|
182
|
+
assert.equal(GetMinusOne4(), -1);
|
|
183
|
+
assert.equal(GetMinusOne8(), -1);
|
|
184
|
+
|
|
175
185
|
// Simple tests with Pack1
|
|
176
186
|
{
|
|
177
187
|
let p = {};
|
|
@@ -250,9 +260,9 @@ async function test() {
|
|
|
250
260
|
|
|
251
261
|
// Many parameters
|
|
252
262
|
{
|
|
253
|
-
assert.equal(ConcatenateToInt1(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7),
|
|
254
|
-
assert.equal(ConcatenateToInt4(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7),
|
|
255
|
-
assert.equal(ConcatenateToInt8(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7),
|
|
263
|
+
assert.equal(ConcatenateToInt1(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687);
|
|
264
|
+
assert.equal(ConcatenateToInt4(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687);
|
|
265
|
+
assert.equal(ConcatenateToInt8(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687);
|
|
256
266
|
assert.equal(ConcatenateToStr1(5, 6, 1, 2, 3, 9, 4, 4, {i: 0, j: 6, k: 8}, 7), '561239440687');
|
|
257
267
|
assert.equal(ConcatenateToStr4(5, 6, 1, 2, 3, 9, 4, 4, {i: 0, j: 6, k: 8}, 7), '561239440687');
|
|
258
268
|
assert.equal(ConcatenateToStr8(5, 6, 1, 2, 3, 9, 4, 4, {i: 0, j: 6, k: 8}, 7), '561239440687');
|
package/vendor/libcc/libcc.hh
CHANGED
|
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
|