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.
Files changed (46) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/doc/misc.md +6 -0
  3. package/package.json +3 -16
  4. package/src/cnoke/LICENSE.txt +165 -0
  5. package/src/cnoke/README.md +97 -0
  6. package/src/cnoke/assets/FindCNoke.cmake +71 -0
  7. package/src/cnoke/assets/win_delay_hook.c +34 -0
  8. package/src/cnoke/cnoke.js +968 -0
  9. package/src/cnoke/package.json +25 -0
  10. package/src/koffi/build/2.3.2/koffi_darwin_arm64.tar.gz +0 -0
  11. package/src/koffi/build/2.3.2/koffi_darwin_x64.tar.gz +0 -0
  12. package/src/koffi/build/2.3.2/koffi_freebsd_arm64.tar.gz +0 -0
  13. package/src/koffi/build/2.3.2/koffi_freebsd_ia32.tar.gz +0 -0
  14. package/src/koffi/build/2.3.2/koffi_freebsd_x64.tar.gz +0 -0
  15. package/src/koffi/build/2.3.2/koffi_linux_arm32hf.tar.gz +0 -0
  16. package/src/koffi/build/2.3.2/koffi_linux_arm64.tar.gz +0 -0
  17. package/src/koffi/build/2.3.2/koffi_linux_ia32.tar.gz +0 -0
  18. package/src/koffi/build/2.3.2/koffi_linux_riscv64hf64.tar.gz +0 -0
  19. package/src/koffi/build/2.3.2/koffi_linux_x64.tar.gz +0 -0
  20. package/src/koffi/build/2.3.2/koffi_openbsd_ia32.tar.gz +0 -0
  21. package/src/koffi/build/2.3.2/koffi_openbsd_x64.tar.gz +0 -0
  22. package/src/koffi/build/2.3.2/koffi_win32_arm64.tar.gz +0 -0
  23. package/src/koffi/build/2.3.2/koffi_win32_ia32.tar.gz +0 -0
  24. package/src/koffi/build/2.3.2/koffi_win32_x64.tar.gz +0 -0
  25. package/src/koffi/src/call.cc +0 -4
  26. package/src/koffi/src/ffi.cc +89 -87
  27. package/src/koffi/src/ffi.hh +13 -7
  28. package/src/koffi/src/index.d.ts +10 -1
  29. package/src/koffi/src/parser.cc +12 -10
  30. package/src/koffi/src/util.cc +80 -35
  31. package/src/koffi/src/util.hh +1 -1
  32. package/src/koffi/build/2.3.1/koffi_darwin_arm64.tar.gz +0 -0
  33. package/src/koffi/build/2.3.1/koffi_darwin_x64.tar.gz +0 -0
  34. package/src/koffi/build/2.3.1/koffi_freebsd_arm64.tar.gz +0 -0
  35. package/src/koffi/build/2.3.1/koffi_freebsd_ia32.tar.gz +0 -0
  36. package/src/koffi/build/2.3.1/koffi_freebsd_x64.tar.gz +0 -0
  37. package/src/koffi/build/2.3.1/koffi_linux_arm32hf.tar.gz +0 -0
  38. package/src/koffi/build/2.3.1/koffi_linux_arm64.tar.gz +0 -0
  39. package/src/koffi/build/2.3.1/koffi_linux_ia32.tar.gz +0 -0
  40. package/src/koffi/build/2.3.1/koffi_linux_riscv64hf64.tar.gz +0 -0
  41. package/src/koffi/build/2.3.1/koffi_linux_x64.tar.gz +0 -0
  42. package/src/koffi/build/2.3.1/koffi_openbsd_ia32.tar.gz +0 -0
  43. package/src/koffi/build/2.3.1/koffi_openbsd_x64.tar.gz +0 -0
  44. package/src/koffi/build/2.3.1/koffi_win32_arm64.tar.gz +0 -0
  45. package/src/koffi/build/2.3.1/koffi_win32_ia32.tar.gz +0 -0
  46. package/src/koffi/build/2.3.1/koffi_win32_x64.tar.gz +0 -0
@@ -27,7 +27,7 @@ const TypeInfo *ResolveType(Napi::Value value, int *out_directions)
27
27
 
28
28
  if (value.IsString()) {
29
29
  std::string str = value.As<Napi::String>();
30
- const TypeInfo *type = ResolveType(instance, str.c_str(), out_directions);
30
+ const TypeInfo *type = ResolveType(env, str.c_str(), out_directions);
31
31
 
32
32
  if (!type) {
33
33
  ThrowError<Napi::TypeError>(env, "Unknown or invalid type name '%1'", str.c_str());
@@ -53,47 +53,81 @@ const TypeInfo *ResolveType(Napi::Value value, int *out_directions)
53
53
  }
54
54
  }
55
55
 
56
- const TypeInfo *ResolveType(InstanceData *instance, Span<const char> str, int *out_directions)
56
+ static inline bool IsIdentifierStart(char c)
57
57
  {
58
- Span<const char> remain = TrimStr(str);
58
+ return IsAsciiAlpha(c) || c == '_';
59
+ }
60
+
61
+ static inline bool IsIdentifierChar(char c)
62
+ {
63
+ return IsAsciiAlphaOrDigit(c) || c == '_';
64
+ }
65
+
66
+ const TypeInfo *ResolveType(Napi::Env env, Span<const char> str, int *out_directions)
67
+ {
68
+ InstanceData *instance = env.GetInstanceData<InstanceData>();
59
69
 
60
70
  int indirect = 0;
61
- bool dispose = false;
71
+ uint8_t disposables = 0;
62
72
 
63
- while (remain.len >= 6 && StartsWith(remain, "const") && IsAsciiWhite(remain[5])) {
64
- remain = remain.Take(6, remain.len - 6);
65
- remain = TrimStr(remain);
73
+ // Skip initial const qualifiers
74
+ while (str.len >= 6 && StartsWith(str, "const") && IsAsciiWhite(str[5])) {
75
+ str = str.Take(6, str.len - 6);
76
+ str = TrimStr(str);
66
77
  }
67
- if (remain.len && remain[remain.len - 1] == '!') {
68
- dispose = true;
78
+ str = TrimStr(str);
79
+
80
+ Span<const char> remain = str;
69
81
 
70
- remain = remain.Take(0, remain.len - 1);
82
+ // Consume one or more identifiers (e.g. unsigned int)
83
+ for (;;) {
71
84
  remain = TrimStr(remain);
85
+
86
+ if (!remain.len || !IsIdentifierStart(remain[0]))
87
+ break;
88
+
89
+ do {
90
+ remain.ptr++;
91
+ remain.len--;
92
+ } while (remain.len && IsIdentifierChar(remain[0]));
72
93
  }
94
+
95
+ Span<const char> name = TrimStr(MakeSpan(str.ptr, remain.ptr - str.ptr));
96
+
97
+ // Consume pointer indirections
73
98
  while (remain.len) {
74
- if (remain[remain.len - 1] == '*') {
75
- remain = remain.Take(0, remain.len - 1);
99
+ if (remain[0] == '*') {
100
+ remain = remain.Take(1, remain.len - 1);
76
101
  indirect++;
77
- } else if (remain.len >= 6 && EndsWith(remain, "const") && IsAsciiWhite(remain[remain.len - 6])) {
78
- remain = remain.Take(0, remain.len - 6);
102
+
103
+ if (RG_UNLIKELY(indirect) >= RG_SIZE(disposables) * 8) {
104
+ ThrowError<Napi::Error>(env, "Too many pointer indirections");
105
+ return nullptr;
106
+ }
107
+ } else if (remain[0] == '!') {
108
+ remain = remain.Take(1, remain.len - 1);
109
+ disposables |= (1u << indirect);
110
+ } else if (remain.len >= 6 && StartsWith(remain, "const") && !IsIdentifierStart(remain[6])) {
111
+ remain = remain.Take(6, remain.len - 6);
79
112
  } else {
80
113
  break;
81
114
  }
115
+
82
116
  remain = TrimStr(remain);
83
117
  }
84
118
 
85
- const TypeInfo *type = instance->types_map.FindValue(remain, nullptr);
119
+ const TypeInfo *type = instance->types_map.FindValue(name, nullptr);
86
120
 
87
121
  if (!type) {
88
122
  // Try with cleaned up spaces
89
- if (remain.len < 256) {
123
+ if (name.len < 256) {
90
124
  LocalArray<char, 256> buf;
91
- for (Size i = 0; i < remain.len; i++) {
92
- char c = remain[i];
125
+ for (Size i = 0; i < name.len; i++) {
126
+ char c = name[i];
93
127
 
94
128
  if (IsAsciiWhite(c)) {
95
129
  buf.Append(' ');
96
- while (++i < remain.len && IsAsciiWhite(remain[i]));
130
+ while (++i < name.len && IsAsciiWhite(name[i]));
97
131
  i--;
98
132
  } else {
99
133
  buf.Append(c);
@@ -107,25 +141,36 @@ const TypeInfo *ResolveType(InstanceData *instance, Span<const char> str, int *o
107
141
  return nullptr;
108
142
  }
109
143
 
110
- if (indirect) {
111
- type = MakePointerType(instance, type, indirect);
112
- RG_ASSERT(type);
113
- }
144
+ for (int i = 0;; i++) {
145
+ if (disposables & (1u << i)) {
146
+ if (RG_UNLIKELY(type->primitive != PrimitiveKind::Pointer &&
147
+ type->primitive != PrimitiveKind::String &&
148
+ type->primitive != PrimitiveKind::String16)) {
149
+ ThrowError<Napi::Error>(env, "Cannot create disposable type for non-pointer");
150
+ return nullptr;
151
+ }
114
152
 
115
- if (dispose) {
116
- if (type->primitive != PrimitiveKind::String &&
117
- type->primitive != PrimitiveKind::String16 &&
118
- indirect != 1)
119
- return nullptr;
153
+ TypeInfo *copy = instance->types.AppendDefault();
120
154
 
121
- TypeInfo *copy = instance->types.AppendDefault();
155
+ memcpy((void *)copy, (const void *)type, RG_SIZE(*type));
156
+ copy->name = "<anonymous>";
157
+ copy->members.allocator = GetNullAllocator();
122
158
 
123
- memcpy((void *)copy, (const void *)type, RG_SIZE(*type));
124
- copy->name = "<anonymous>";
125
- copy->members.allocator = GetNullAllocator();
126
- copy->dispose = [](Napi::Env, const TypeInfo *, const void *ptr) { free((void *)ptr); };
159
+ copy->dispose = [](Napi::Env env, const TypeInfo *, const void *ptr) {
160
+ InstanceData *instance = env.GetInstanceData<InstanceData>();
127
161
 
128
- type = copy;
162
+ free((void *)ptr);
163
+ instance->stats.disposed++;
164
+ };
165
+
166
+ type = copy;
167
+ }
168
+
169
+ if (i >= indirect)
170
+ break;
171
+
172
+ type = MakePointerType(instance, type);
173
+ RG_ASSERT(type);
129
174
  }
130
175
 
131
176
  if (out_directions) {
@@ -174,7 +219,7 @@ static const TypeInfo *MakeArrayType(InstanceData *instance, const TypeInfo *ref
174
219
  TypeInfo::ArrayHint hint, bool insert)
175
220
  {
176
221
  RG_ASSERT(len > 0);
177
- RG_ASSERT(len <= instance->max_type_size / ref->size);
222
+ RG_ASSERT(len <= instance->config.max_type_size / ref->size);
178
223
 
179
224
  TypeInfo *type = instance->types.AppendDefault();
180
225
 
@@ -54,7 +54,7 @@ static inline bool IsRegularSize(Size size, Size max)
54
54
  }
55
55
 
56
56
  const TypeInfo *ResolveType(Napi::Value value, int *out_directions = nullptr);
57
- const TypeInfo *ResolveType(InstanceData *instance, Span<const char> str, int *out_directions = nullptr);
57
+ const TypeInfo *ResolveType(Napi::Env env, Span<const char> str, int *out_directions = nullptr);
58
58
 
59
59
  const TypeInfo *MakePointerType(InstanceData *instance, const TypeInfo *ref, int count = 1);
60
60
  const TypeInfo *MakeArrayType(InstanceData *instance, const TypeInfo *ref, Size len);