koffi 1.1.1 → 1.1.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/CMakeLists.txt CHANGED
@@ -23,6 +23,9 @@ if(MSVC)
23
23
  else()
24
24
  add_compile_options(-Wall -Wextra -Wno-missing-field-initializers
25
25
  -Wno-unused-parameter -Wno-class-memaccess)
26
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
27
+ add_compile_options(-Wno-unknown-warning-option)
28
+ endif()
26
29
  endif()
27
30
 
28
31
  # ---- Koffi ----
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koffi",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Fast and simple FFI (foreign function interface) for Node.js",
5
5
  "keywords": [
6
6
  "foreign",
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "license": "AGPL-3.0",
26
26
  "dependencies": {
27
- "cnoke": "^1.0.7"
27
+ "cnoke": "^1.0.9"
28
28
  },
29
29
  "devDependencies": {
30
30
  "chalk": "^4.1.2",
package/src/call.cc CHANGED
@@ -252,8 +252,8 @@ bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t
252
252
  return false;
253
253
  }
254
254
 
255
- Napi::Object obj = value.As<Napi::Object>();
256
- if (!PushObject(obj, member.type, dest, realign))
255
+ Napi::Object obj2 = value.As<Napi::Object>();
256
+ if (!PushObject(obj2, member.type, dest, realign))
257
257
  return false;
258
258
  } break;
259
259
  case PrimitiveKind::Array: {
@@ -292,15 +292,15 @@ bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t
292
292
  return true;
293
293
  }
294
294
 
295
- bool CallData::PushArray(const Napi::Value &value, const TypeInfo *type, uint8_t *dest, int16_t realign)
295
+ bool CallData::PushArray(const Napi::Value &obj, const TypeInfo *type, uint8_t *dest, int16_t realign)
296
296
  {
297
- RG_ASSERT(value.IsArray() || value.IsTypedArray() || value.IsString());
297
+ RG_ASSERT(obj.IsArray() || obj.IsTypedArray() || obj.IsString());
298
298
  RG_ASSERT(type->primitive == PrimitiveKind::Array);
299
299
 
300
300
  uint32_t len = type->size / type->ref->size;
301
301
 
302
- if (value.IsArray()) {
303
- Napi::Array array = value.As<Napi::Array>();
302
+ if (obj.IsArray()) {
303
+ Napi::Array array = obj.As<Napi::Array>();
304
304
 
305
305
  if (RG_UNLIKELY(array.Length() != len)) {
306
306
  ThrowError<Napi::Error>(env, "Expected array of length %1, got %2", len, array.Length());
@@ -407,15 +407,15 @@ bool CallData::PushArray(const Napi::Value &value, const TypeInfo *type, uint8_t
407
407
  } break;
408
408
  case PrimitiveKind::Record: {
409
409
  PUSH_ARRAY(IsObject(value), "object", {
410
- Napi::Object obj = value.As<Napi::Object>();
411
- if (!PushObject(obj, type->ref, dest, realign))
410
+ Napi::Object obj2 = value.As<Napi::Object>();
411
+ if (!PushObject(obj2, type->ref, dest, realign))
412
412
  return false;
413
413
  });
414
414
  } break;
415
415
  case PrimitiveKind::Array: {
416
416
  PUSH_ARRAY(value.IsArray() || value.IsTypedArray() || value.IsString(), "array", {
417
- Napi::Object array = value.As<Napi::Array>();
418
- if (!PushArray(array, type->ref, dest, realign))
417
+ Napi::Object array2 = value.As<Napi::Array>();
418
+ if (!PushArray(array2, type->ref, dest, realign))
419
419
  return false;
420
420
  });
421
421
  } break;
@@ -434,8 +434,8 @@ bool CallData::PushArray(const Napi::Value &value, const TypeInfo *type, uint8_t
434
434
  }
435
435
 
436
436
  #undef PUSH_ARRAY
437
- } else if (value.IsTypedArray()) {
438
- Napi::TypedArray array = value.As<Napi::TypedArray>();
437
+ } else if (obj.IsTypedArray()) {
438
+ Napi::TypedArray array = obj.As<Napi::TypedArray>();
439
439
  const uint8_t *buf = (const uint8_t *)array.ArrayBuffer().Data();
440
440
 
441
441
  if (RG_UNLIKELY(array.ElementLength() != len)) {
@@ -469,23 +469,23 @@ bool CallData::PushArray(const Napi::Value &value, const TypeInfo *type, uint8_t
469
469
 
470
470
  dest += type->ref->size;
471
471
  }
472
- } else if (value.IsString()) {
473
- size_t len = 0;
472
+ } else if (obj.IsString()) {
473
+ size_t encoded = 0;
474
474
 
475
475
  if (type->ref->primitive == PrimitiveKind::Int8 || type->ref->primitive == PrimitiveKind::UInt8) {
476
- napi_status status = napi_get_value_string_utf8(env, value, (char *)dest, type->size, &len);
476
+ napi_status status = napi_get_value_string_utf8(env, obj, (char *)dest, type->size, &encoded);
477
477
  RG_ASSERT(status == napi_ok);
478
478
  } else if (type->ref->primitive == PrimitiveKind::Int16 || type->ref->primitive == PrimitiveKind::UInt16) {
479
- napi_status status = napi_get_value_string_utf16(env, value, (char16_t *)dest, type->size / 2, &len);
479
+ napi_status status = napi_get_value_string_utf16(env, obj, (char16_t *)dest, type->size / 2, &encoded);
480
480
  RG_ASSERT(status == napi_ok);
481
481
 
482
- len *= 2;
482
+ encoded *= 2;
483
483
  } else {
484
484
  ThrowError<Napi::TypeError>(env, "Strings cannot be converted to %1 array", type->ref->name);
485
485
  return false;
486
486
  }
487
487
 
488
- memset_safe(dest + len, 0, type->size - len);
488
+ memset_safe(dest + encoded, 0, type->size - encoded);
489
489
  } else {
490
490
  RG_UNREACHABLE();
491
491
  }
package/src/call.hh CHANGED
@@ -78,7 +78,7 @@ private:
78
78
  const char *PushString(const Napi::Value &value);
79
79
  const char16_t *PushString16(const Napi::Value &value);
80
80
  bool PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t *dest, int16_t realign = 0);
81
- bool PushArray(const Napi::Value &value, const TypeInfo *type, uint8_t *dest, int16_t realign = 0);
81
+ bool PushArray(const Napi::Value &obj, const TypeInfo *type, uint8_t *dest, int16_t realign = 0);
82
82
 
83
83
  void PopObject(Napi::Object obj, const uint8_t *src, const TypeInfo *type, int16_t realign = 0);
84
84
  Napi::Object PopObject(const uint8_t *src, const TypeInfo *type, int16_t realign = 0);
package/src/ffi.cc CHANGED
@@ -653,9 +653,13 @@ static Napi::Value FindLibraryFunction(const Napi::CallbackInfo &info, CallConve
653
653
  if (!ParseClassicFunction(env, info[0u].As<Napi::String>(), info[1u], info[2u].As<Napi::Array>(), func))
654
654
  return env.Null();
655
655
  } else if (info.Length() >= 1) {
656
- PrototypeParser parser(env);
656
+ if (!info[0].IsString()) {
657
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for prototype, expected string", GetValueType(instance, info[0]));
658
+ return env.Null();
659
+ }
657
660
 
658
- if (!parser.Parse(info[0u].As<Napi::String>(), func))
661
+ std::string proto = info[0u].As<Napi::String>();
662
+ if (!ParsePrototype(env, proto.c_str(), func))
659
663
  return env.Null();
660
664
  } else {
661
665
  ThrowError<Napi::TypeError>(env, "Expected 1 or 3 arguments, not %1", info.Length());
@@ -957,7 +961,6 @@ static void SetExports(Napi::Env env, Func func)
957
961
  func("out", Napi::Function::New(env, MarkOut));
958
962
  func("inout", Napi::Function::New(env, MarkInOut));
959
963
 
960
- func("internal", Napi::Boolean::New(env, true));
961
964
  #if defined(_WIN32)
962
965
  func("extension", Napi::String::New(env, ".dll"));
963
966
  #elif defined(__APPLE__)
@@ -1009,6 +1012,7 @@ static void InitInternal(v8::Local<v8::Object> target, v8::Local<v8::Value>,
1009
1012
  FillRandomSafe(&instance->tag_lower, RG_SIZE(instance->tag_lower));
1010
1013
 
1011
1014
  SetExports(env_napi, [&](const char *name, Napi::Value value) { SetValue(env, target, name, value); });
1015
+ SetValue(env, target, "internal", Napi::Boolean::New(env_cxx, true));
1012
1016
  }
1013
1017
 
1014
1018
  #else
@@ -1024,6 +1028,7 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
1024
1028
  FillRandomSafe(&instance->tag_lower, RG_SIZE(instance->tag_lower));
1025
1029
 
1026
1030
  SetExports(env, [&](const char *name, Napi::Value value) { exports.Set(name, value); });
1031
+ exports.Set("internal", Napi::Boolean::New(env, false));
1027
1032
 
1028
1033
  return exports;
1029
1034
  }
package/src/parser.cc CHANGED
@@ -19,34 +19,27 @@
19
19
 
20
20
  namespace RG {
21
21
 
22
- bool PrototypeParser::Parse(Napi::String proto, FunctionInfo *func)
22
+ bool PrototypeParser::Parse(const char *str, FunctionInfo *out_func)
23
23
  {
24
- if (!proto.IsString()) {
25
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for prototype, expected string", GetValueType(instance, proto));
26
- return false;
27
- }
28
-
29
- std::string hold = proto;
30
-
31
24
  tokens.Clear();
32
25
  offset = 0;
33
26
  valid = true;
34
27
 
35
- Tokenize(hold.c_str());
28
+ Tokenize(str);
36
29
 
37
- func->ret.type = ParseType();
38
- if (func->ret.type->primitive == PrimitiveKind::Array) {
30
+ out_func->ret.type = ParseType();
31
+ if (out_func->ret.type->primitive == PrimitiveKind::Array) {
39
32
  MarkError("You are not allowed to directly return C arrays");
40
33
  return false;
41
34
  }
42
35
  if (Match("__cdecl")) {
43
- func->convention = CallConvention::Cdecl;
36
+ out_func->convention = CallConvention::Cdecl;
44
37
  } else if (Match("__stdcall")) {
45
- func->convention = CallConvention::Stdcall;
38
+ out_func->convention = CallConvention::Stdcall;
46
39
  } else if (Match("__fastcall")) {
47
- func->convention = CallConvention::Fastcall;
40
+ out_func->convention = CallConvention::Fastcall;
48
41
  }
49
- func->name = ParseIdentifier();
42
+ out_func->name = ParseIdentifier();
50
43
 
51
44
  Consume("(");
52
45
  if (offset < tokens.len && tokens[offset] != ")") {
@@ -54,7 +47,7 @@ bool PrototypeParser::Parse(Napi::String proto, FunctionInfo *func)
54
47
  ParameterInfo param = {};
55
48
 
56
49
  if (Match("...")) {
57
- func->variadic = true;
50
+ out_func->variadic = true;
58
51
  break;
59
52
  }
60
53
 
@@ -83,18 +76,18 @@ bool PrototypeParser::Parse(Napi::String proto, FunctionInfo *func)
83
76
 
84
77
  offset += (offset < tokens.len && IsIdentifier(tokens[offset]));
85
78
 
86
- if (func->parameters.len >= MaxParameters) {
79
+ if (out_func->parameters.len >= MaxParameters) {
87
80
  MarkError("Functions cannot have more than %1 parameters", MaxParameters);
88
81
  return false;
89
82
  }
90
- if ((param.directions & 2) && ++func->out_parameters >= MaxOutParameters) {
83
+ if ((param.directions & 2) && ++out_func->out_parameters >= MaxOutParameters) {
91
84
  MarkError("Functions cannot have more than out %1 parameters", MaxOutParameters);
92
85
  return false;
93
86
  }
94
87
 
95
- param.offset = func->parameters.len;
88
+ param.offset = out_func->parameters.len;
96
89
 
97
- func->parameters.Append(param);
90
+ out_func->parameters.Append(param);
98
91
 
99
92
  if (offset >= tokens.len || tokens[offset] != ",")
100
93
  break;
@@ -125,6 +118,17 @@ void PrototypeParser::Tokenize(const char *str)
125
118
  Span<const char> tok = MakeSpan(str + i, j - i);
126
119
  tokens.Append(tok);
127
120
 
121
+ i = j - 1;
122
+ } else if (IsAsciiDigit(c)) {
123
+ Size j = i;
124
+ while (str[++j] && IsAsciiDigit(str[j]));
125
+ if (str[j] == '.') {
126
+ while (str[++j] && IsAsciiDigit(str[j]));
127
+ }
128
+
129
+ Span<const char> tok = MakeSpan(str + i, j - i);
130
+ tokens.Append(tok);
131
+
128
132
  i = j - 1;
129
133
  } else if (c == '.' && str[i + 1] == '.' && str[i + 2] == '.') {
130
134
  tokens.Append("...");
@@ -250,4 +254,10 @@ bool PrototypeParser::IsIdentifier(Span<const char> tok) const
250
254
  return IsAsciiAlpha(tok[0]) || tok[0] == '_';
251
255
  }
252
256
 
257
+ bool ParsePrototype(Napi::Env env, const char *str, FunctionInfo *out_func)
258
+ {
259
+ PrototypeParser parser(env);
260
+ return parser.Parse(str, out_func);
261
+ }
262
+
253
263
  }
package/src/parser.hh CHANGED
@@ -36,7 +36,7 @@ class PrototypeParser {
36
36
  public:
37
37
  PrototypeParser(Napi::Env env) : env(env), instance(env.GetInstanceData<InstanceData>()) {}
38
38
 
39
- bool Parse(Napi::String proto, FunctionInfo *func);
39
+ bool Parse(const char *str, FunctionInfo *out_func);
40
40
 
41
41
  private:
42
42
  void Tokenize(const char *str);
@@ -60,4 +60,6 @@ private:
60
60
  }
61
61
  };
62
62
 
63
+ bool ParsePrototype(Napi::Env env, const char *str, FunctionInfo *out_func);
64
+
63
65
  }