From 2fdf7c8aaa12592d9b86060cfe1674f0b78680d9 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Mon, 6 Jun 2022 16:09:53 +0300 Subject: [PATCH 01/35] Rename CALLBACK defined in Windows headers --- src/function.cc | 36 ++++++++++++++++++------------------ src/function.h | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/function.cc b/src/function.cc index 00affdd..2363bae 100644 --- a/src/function.cc +++ b/src/function.cc @@ -165,14 +165,14 @@ bool FunctionInfo::Init() { call_parameters[i].direction = direction; - if (call_parameters[i].type == ParameterType::SKIP) + if (call_parameters[i].type == ParameterType::kSKIP) continue; // If there is an array length, this is an array int length_i = g_type_info_get_array_length (&type_info); if (tag == GI_TYPE_TAG_ARRAY && length_i >= 0) { - call_parameters[i].type = ParameterType::ARRAY; - call_parameters[length_i].type = ParameterType::SKIP; + call_parameters[i].type = ParameterType::kARRAY; + call_parameters[length_i].type = ParameterType::kSKIP; // If array length came before, we need to remove it from args count @@ -190,9 +190,9 @@ bool FunctionInfo::Init() { if (interface_type == GI_INFO_TYPE_CALLBACK) { if (IsDestroyNotify(interface_info)) { /* Skip GDestroyNotify if they appear before the respective callback */ - call_parameters[i].type = ParameterType::SKIP; + call_parameters[i].type = ParameterType::kSKIP; } else { - call_parameters[i].type = ParameterType::CALLBACK; + call_parameters[i].type = ParameterType::kCALLBACK; int destroy_i = g_arg_info_get_destroy(&arg_info); int closure_i = g_arg_info_get_closure(&arg_info); @@ -204,10 +204,10 @@ bool FunctionInfo::Init() { } if (destroy_i >= 0 && destroy_i < n_callable_args) - call_parameters[destroy_i].type = ParameterType::SKIP; + call_parameters[destroy_i].type = ParameterType::kSKIP; if (closure_i >= 0 && closure_i < n_callable_args) - call_parameters[closure_i].type = ParameterType::SKIP; + call_parameters[closure_i].type = ParameterType::kSKIP; if (destroy_i < i) { if (IsDirectionIn(call_parameters[destroy_i].direction)) @@ -271,7 +271,7 @@ bool FunctionInfo::TypeCheck (const Nan::FunctionCallbackInfo &arguments) for (int in_arg = 0, i = 0; i < n_callable_args; i++) { Parameter ¶m = call_parameters[i]; - if (param.type == ParameterType::SKIP) + if (param.type == ParameterType::kSKIP) continue; GIArgInfo arg_info; @@ -348,7 +348,7 @@ Local FunctionCall ( for (int in_arg = 0, i = 0; i < func->n_callable_args; i++) { Parameter& param = func->call_parameters[i]; - if (param.type == ParameterType::SKIP) + if (param.type == ParameterType::kSKIP) continue; GIArgInfo arg_info; @@ -357,7 +357,7 @@ Local FunctionCall ( g_arg_info_load_type (&arg_info, &type_info); GIDirection direction = g_arg_info_get_direction (&arg_info); - if (param.type == ParameterType::ARRAY) { + if (param.type == ParameterType::kARRAY) { GIArgInfo array_length_arg; GITypeInfo array_length_type; @@ -383,7 +383,7 @@ Local FunctionCall ( callable_arg_values[length_i].v_pointer = &len_param.data; } } - else if (param.type == ParameterType::CALLBACK) { + else if (param.type == ParameterType::kCALLBACK) { Callback *callback; ffi_closure *closure; @@ -402,12 +402,12 @@ Local FunctionCall ( int closure_i = g_arg_info_get_closure(&arg_info); if (destroy_i >= 0) { - g_assert (func->call_parameters[destroy_i].type == ParameterType::SKIP); + g_assert (func->call_parameters[destroy_i].type == ParameterType::kSKIP); callable_arg_values[destroy_i].v_pointer = callback ? (void*) Callback::DestroyNotify : NULL; } if (closure_i >= 0) { - g_assert (func->call_parameters[closure_i].type == ParameterType::SKIP); + g_assert (func->call_parameters[closure_i].type == ParameterType::kSKIP); callable_arg_values[closure_i].v_pointer = callback; } @@ -426,7 +426,7 @@ Local FunctionCall ( else /* (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) */ { // Callback GIArgument is filled above, for the rest... - if (param.type != ParameterType::CALLBACK) { + if (param.type != ParameterType::kCALLBACK) { // FIXME(handle failure here) FillArgument(&arg_info, &callable_arg_values[i], info[in_arg]); @@ -507,13 +507,13 @@ Local FunctionCall ( GIDirection direction = g_arg_info_get_direction (&arg_info); GITransfer transfer = g_arg_info_get_ownership_transfer (&arg_info); - if (param.type == ParameterType::ARRAY) { + if (param.type == ParameterType::kARRAY) { if (direction == GI_DIRECTION_INOUT || direction == GI_DIRECTION_OUT) FreeGIArgumentArray (&arg_type, (GIArgument*)arg_value.v_pointer, transfer, direction, param.length); else FreeGIArgumentArray (&arg_type, &arg_value, transfer, direction, param.length); } - else if (param.type == ParameterType::CALLBACK) { + else if (param.type == ParameterType::kCALLBACK) { Callback *callback = static_cast(func->call_parameters[i].data.v_pointer); g_assert(direction == GI_DIRECTION_IN); @@ -595,7 +595,7 @@ Local FunctionInfo::GetReturnValue ( if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) { - if (param.type == ParameterType::ARRAY) { + if (param.type == ParameterType::kARRAY) { int length_i = g_type_info_get_array_length(&arg_type); GIArgInfo length_arg; @@ -614,7 +614,7 @@ Local FunctionInfo::GetReturnValue ( ADD_RETURN (result) - } else if (param.type == ParameterType::NORMAL) { + } else if (param.type == ParameterType::kNORMAL) { if (IsPointerType(&arg_type) && g_arg_info_is_caller_allocates(&arg_info)) { void *pointer = &arg_value.v_pointer; diff --git a/src/function.h b/src/function.h index 37dd313..e6579d1 100644 --- a/src/function.h +++ b/src/function.h @@ -16,7 +16,7 @@ using v8::String; namespace GNodeJS { enum ParameterType { - NORMAL, ARRAY, SKIP, CALLBACK + kNORMAL, kARRAY, kSKIP, kCALLBACK }; struct Parameter { From 846fede9ba7f4006f1650aef1bdda53dc688280b Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Mon, 6 Jun 2022 16:11:41 +0300 Subject: [PATCH 02/35] Rename interface defined in Windows headers --- src/type.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/type.cc b/src/type.cc index 1b1ab03..081e038 100644 --- a/src/type.cc +++ b/src/type.cc @@ -256,13 +256,13 @@ GITypeTag GetStorageType (GITypeInfo *type_info) { GITypeTag type_tag = g_type_info_get_tag (type_info); if (type_tag == GI_TYPE_TAG_INTERFACE) { - GIBaseInfo *interface = g_type_info_get_interface (type_info); - GIInfoType interface_type = g_base_info_get_type (interface); + GIBaseInfo *iface = g_type_info_get_interface (type_info); + GIInfoType iface_type = g_base_info_get_type (iface); - if (interface_type == GI_INFO_TYPE_ENUM || interface_type == GI_INFO_TYPE_FLAGS) - type_tag = g_enum_info_get_storage_type ((GIEnumInfo *)interface); + if (iface_type == GI_INFO_TYPE_ENUM || iface_type == GI_INFO_TYPE_FLAGS) + type_tag = g_enum_info_get_storage_type ((GIEnumInfo *)iface); - g_base_info_unref (interface); + g_base_info_unref (iface); } return type_tag; From 5ac5d2967eb5ab1806bfc324c23d8f0ee591f230 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Mon, 6 Jun 2022 16:25:22 +0300 Subject: [PATCH 03/35] Reuse SET_PROTOTYPE method from util.h Fixes warning: SET_METHOD redefined --- src/modules/cairo/context.cc | 208 +++++++++++++++++------------------ 1 file changed, 102 insertions(+), 106 deletions(-) diff --git a/src/modules/cairo/context.cc b/src/modules/cairo/context.cc index e0e9761..553678e 100644 --- a/src/modules/cairo/context.cc +++ b/src/modules/cairo/context.cc @@ -1336,119 +1336,115 @@ NAN_METHOD(tagEnd) { } #endif -#define SET_METHOD(tpl, name) Nan::SetPrototypeMethod(tpl, #name, name) - static void AttachMethods(Local tpl) { - SET_METHOD(tpl, status); - SET_METHOD(tpl, save); - SET_METHOD(tpl, restore); - SET_METHOD(tpl, getTarget); - SET_METHOD(tpl, pushGroup); - SET_METHOD(tpl, pushGroupWithContent); - SET_METHOD(tpl, popGroup); - SET_METHOD(tpl, popGroupToSource); - SET_METHOD(tpl, getGroupTarget); - SET_METHOD(tpl, setSourceRgb); - SET_METHOD(tpl, setSourceRgba); - SET_METHOD(tpl, setSource); - SET_METHOD(tpl, setSourceSurface); - SET_METHOD(tpl, getSource); - SET_METHOD(tpl, setAntialias); - SET_METHOD(tpl, getAntialias); - SET_METHOD(tpl, getDashCount); - SET_METHOD(tpl, getDash); - SET_METHOD(tpl, setFillRule); - SET_METHOD(tpl, getFillRule); - SET_METHOD(tpl, setLineCap); - SET_METHOD(tpl, getLineCap); - SET_METHOD(tpl, setLineJoin); - SET_METHOD(tpl, getLineJoin); - SET_METHOD(tpl, setLineWidth); - SET_METHOD(tpl, getLineWidth); - SET_METHOD(tpl, setMiterLimit); - SET_METHOD(tpl, getMiterLimit); - SET_METHOD(tpl, setOperator); - SET_METHOD(tpl, getOperator); - SET_METHOD(tpl, setTolerance); - SET_METHOD(tpl, getTolerance); - SET_METHOD(tpl, clip); - SET_METHOD(tpl, clipPreserve); - SET_METHOD(tpl, clipExtents); - SET_METHOD(tpl, inClip); - SET_METHOD(tpl, resetClip); - SET_METHOD(tpl, copyClipRectangleList); - SET_METHOD(tpl, fill); - SET_METHOD(tpl, fillPreserve); - SET_METHOD(tpl, fillExtents); - SET_METHOD(tpl, inFill); - SET_METHOD(tpl, mask); - SET_METHOD(tpl, maskSurface); - SET_METHOD(tpl, paint); - SET_METHOD(tpl, paintWithAlpha); - SET_METHOD(tpl, stroke); - SET_METHOD(tpl, strokePreserve); - SET_METHOD(tpl, strokeExtents); - SET_METHOD(tpl, inStroke); - SET_METHOD(tpl, copyPage); - SET_METHOD(tpl, showPage); - SET_METHOD(tpl, getReferenceCount); - SET_METHOD(tpl, copyPath); - SET_METHOD(tpl, copyPathFlat); - SET_METHOD(tpl, appendPath); - SET_METHOD(tpl, hasCurrentPoint); - SET_METHOD(tpl, getCurrentPoint); - SET_METHOD(tpl, newPath); - SET_METHOD(tpl, newSubPath); - SET_METHOD(tpl, closePath); - SET_METHOD(tpl, arc); - SET_METHOD(tpl, arcNegative); - SET_METHOD(tpl, curveTo); - SET_METHOD(tpl, lineTo); - SET_METHOD(tpl, moveTo); - SET_METHOD(tpl, rectangle); - SET_METHOD(tpl, glyphPath); - SET_METHOD(tpl, textPath); - SET_METHOD(tpl, relCurveTo); - SET_METHOD(tpl, relLineTo); - SET_METHOD(tpl, relMoveTo); - SET_METHOD(tpl, pathExtents); - SET_METHOD(tpl, showText); - SET_METHOD(tpl, showGlyphs); - SET_METHOD(tpl, showTextGlyphs); - SET_METHOD(tpl, fontExtents); - SET_METHOD(tpl, textExtents); - SET_METHOD(tpl, glyphExtents); - SET_METHOD(tpl, selectFontFace); - SET_METHOD(tpl, setFontSize); - SET_METHOD(tpl, setFontMatrix); - SET_METHOD(tpl, getFontMatrix); - SET_METHOD(tpl, setFontOptions); - SET_METHOD(tpl, getFontOptions); - SET_METHOD(tpl, setFontFace); - SET_METHOD(tpl, getFontFace); - SET_METHOD(tpl, setScaledFont); - SET_METHOD(tpl, getScaledFont); - SET_METHOD(tpl, translate); - SET_METHOD(tpl, scale); - SET_METHOD(tpl, rotate); - SET_METHOD(tpl, transform); - SET_METHOD(tpl, setMatrix); - SET_METHOD(tpl, getMatrix); - SET_METHOD(tpl, identityMatrix); - SET_METHOD(tpl, userToDevice); - SET_METHOD(tpl, userToDeviceDistance); - SET_METHOD(tpl, deviceToUser); - SET_METHOD(tpl, deviceToUserDistance); + SET_PROTOTYPE_METHOD(tpl, status); + SET_PROTOTYPE_METHOD(tpl, save); + SET_PROTOTYPE_METHOD(tpl, restore); + SET_PROTOTYPE_METHOD(tpl, getTarget); + SET_PROTOTYPE_METHOD(tpl, pushGroup); + SET_PROTOTYPE_METHOD(tpl, pushGroupWithContent); + SET_PROTOTYPE_METHOD(tpl, popGroup); + SET_PROTOTYPE_METHOD(tpl, popGroupToSource); + SET_PROTOTYPE_METHOD(tpl, getGroupTarget); + SET_PROTOTYPE_METHOD(tpl, setSourceRgb); + SET_PROTOTYPE_METHOD(tpl, setSourceRgba); + SET_PROTOTYPE_METHOD(tpl, setSource); + SET_PROTOTYPE_METHOD(tpl, setSourceSurface); + SET_PROTOTYPE_METHOD(tpl, getSource); + SET_PROTOTYPE_METHOD(tpl, setAntialias); + SET_PROTOTYPE_METHOD(tpl, getAntialias); + SET_PROTOTYPE_METHOD(tpl, getDashCount); + SET_PROTOTYPE_METHOD(tpl, getDash); + SET_PROTOTYPE_METHOD(tpl, setFillRule); + SET_PROTOTYPE_METHOD(tpl, getFillRule); + SET_PROTOTYPE_METHOD(tpl, setLineCap); + SET_PROTOTYPE_METHOD(tpl, getLineCap); + SET_PROTOTYPE_METHOD(tpl, setLineJoin); + SET_PROTOTYPE_METHOD(tpl, getLineJoin); + SET_PROTOTYPE_METHOD(tpl, setLineWidth); + SET_PROTOTYPE_METHOD(tpl, getLineWidth); + SET_PROTOTYPE_METHOD(tpl, setMiterLimit); + SET_PROTOTYPE_METHOD(tpl, getMiterLimit); + SET_PROTOTYPE_METHOD(tpl, setOperator); + SET_PROTOTYPE_METHOD(tpl, getOperator); + SET_PROTOTYPE_METHOD(tpl, setTolerance); + SET_PROTOTYPE_METHOD(tpl, getTolerance); + SET_PROTOTYPE_METHOD(tpl, clip); + SET_PROTOTYPE_METHOD(tpl, clipPreserve); + SET_PROTOTYPE_METHOD(tpl, clipExtents); + SET_PROTOTYPE_METHOD(tpl, inClip); + SET_PROTOTYPE_METHOD(tpl, resetClip); + SET_PROTOTYPE_METHOD(tpl, copyClipRectangleList); + SET_PROTOTYPE_METHOD(tpl, fill); + SET_PROTOTYPE_METHOD(tpl, fillPreserve); + SET_PROTOTYPE_METHOD(tpl, fillExtents); + SET_PROTOTYPE_METHOD(tpl, inFill); + SET_PROTOTYPE_METHOD(tpl, mask); + SET_PROTOTYPE_METHOD(tpl, maskSurface); + SET_PROTOTYPE_METHOD(tpl, paint); + SET_PROTOTYPE_METHOD(tpl, paintWithAlpha); + SET_PROTOTYPE_METHOD(tpl, stroke); + SET_PROTOTYPE_METHOD(tpl, strokePreserve); + SET_PROTOTYPE_METHOD(tpl, strokeExtents); + SET_PROTOTYPE_METHOD(tpl, inStroke); + SET_PROTOTYPE_METHOD(tpl, copyPage); + SET_PROTOTYPE_METHOD(tpl, showPage); + SET_PROTOTYPE_METHOD(tpl, getReferenceCount); + SET_PROTOTYPE_METHOD(tpl, copyPath); + SET_PROTOTYPE_METHOD(tpl, copyPathFlat); + SET_PROTOTYPE_METHOD(tpl, appendPath); + SET_PROTOTYPE_METHOD(tpl, hasCurrentPoint); + SET_PROTOTYPE_METHOD(tpl, getCurrentPoint); + SET_PROTOTYPE_METHOD(tpl, newPath); + SET_PROTOTYPE_METHOD(tpl, newSubPath); + SET_PROTOTYPE_METHOD(tpl, closePath); + SET_PROTOTYPE_METHOD(tpl, arc); + SET_PROTOTYPE_METHOD(tpl, arcNegative); + SET_PROTOTYPE_METHOD(tpl, curveTo); + SET_PROTOTYPE_METHOD(tpl, lineTo); + SET_PROTOTYPE_METHOD(tpl, moveTo); + SET_PROTOTYPE_METHOD(tpl, rectangle); + SET_PROTOTYPE_METHOD(tpl, glyphPath); + SET_PROTOTYPE_METHOD(tpl, textPath); + SET_PROTOTYPE_METHOD(tpl, relCurveTo); + SET_PROTOTYPE_METHOD(tpl, relLineTo); + SET_PROTOTYPE_METHOD(tpl, relMoveTo); + SET_PROTOTYPE_METHOD(tpl, pathExtents); + SET_PROTOTYPE_METHOD(tpl, showText); + SET_PROTOTYPE_METHOD(tpl, showGlyphs); + SET_PROTOTYPE_METHOD(tpl, showTextGlyphs); + SET_PROTOTYPE_METHOD(tpl, fontExtents); + SET_PROTOTYPE_METHOD(tpl, textExtents); + SET_PROTOTYPE_METHOD(tpl, glyphExtents); + SET_PROTOTYPE_METHOD(tpl, selectFontFace); + SET_PROTOTYPE_METHOD(tpl, setFontSize); + SET_PROTOTYPE_METHOD(tpl, setFontMatrix); + SET_PROTOTYPE_METHOD(tpl, getFontMatrix); + SET_PROTOTYPE_METHOD(tpl, setFontOptions); + SET_PROTOTYPE_METHOD(tpl, getFontOptions); + SET_PROTOTYPE_METHOD(tpl, setFontFace); + SET_PROTOTYPE_METHOD(tpl, getFontFace); + SET_PROTOTYPE_METHOD(tpl, setScaledFont); + SET_PROTOTYPE_METHOD(tpl, getScaledFont); + SET_PROTOTYPE_METHOD(tpl, translate); + SET_PROTOTYPE_METHOD(tpl, scale); + SET_PROTOTYPE_METHOD(tpl, rotate); + SET_PROTOTYPE_METHOD(tpl, transform); + SET_PROTOTYPE_METHOD(tpl, setMatrix); + SET_PROTOTYPE_METHOD(tpl, getMatrix); + SET_PROTOTYPE_METHOD(tpl, identityMatrix); + SET_PROTOTYPE_METHOD(tpl, userToDevice); + SET_PROTOTYPE_METHOD(tpl, userToDeviceDistance); + SET_PROTOTYPE_METHOD(tpl, deviceToUser); + SET_PROTOTYPE_METHOD(tpl, deviceToUserDistance); #if CAIRO_VERSION_MAJOR >= 1 && CAIRO_VERSION_MINOR >= 16 - SET_METHOD(tpl, tagBegin); + SET_PROTOTYPE_METHOD(tpl, tagBegin); #endif #if CAIRO_VERSION_MAJOR >= 1 && CAIRO_VERSION_MINOR >= 16 - SET_METHOD(tpl, tagEnd); + SET_PROTOTYPE_METHOD(tpl, tagEnd); #endif } -#undef SET_METHOD - /* &info); From 53a35d4fc14ae1c0e76c1413fc215776901562e9 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Mon, 6 Jun 2022 17:12:44 +0300 Subject: [PATCH 04/35] Don't initialize array with a variable Fixes MSVC Error C2131 --- src/function.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/function.cc b/src/function.cc index 2363bae..ba73d82 100644 --- a/src/function.cc +++ b/src/function.cc @@ -1,4 +1,3 @@ - #include #include @@ -325,7 +324,7 @@ Local FunctionCall ( * and for error, if it can throw */ - GIArgument total_arg_values[func->n_total_args]; + GIArgument *total_arg_values = new GIArgument[func->n_total_args]; GIArgument *callable_arg_values; GError *error_stack = nullptr; @@ -340,7 +339,6 @@ Local FunctionCall ( if (func->can_throw) callable_arg_values[func->n_callable_args].v_pointer = error != NULL ? error : &error_stack; - /* * Second, allocate OUT-arguments and fill IN-arguments */ @@ -448,16 +446,17 @@ Local FunctionCall ( * Third, make the actual ffi_call */ - void *ffi_args[func->n_total_args]; + void **ffi_args = new void*[func->n_total_args]; for (int i = 0; i < func->n_total_args; i++) - ffi_args[i] = &total_arg_values[i]; - + ffi_args[i] = (void *)&total_arg_values[i]; GIArgument return_value_stack; ffi_call (&func->invoker.cif, FFI_FN (func->invoker.native_address), use_return_value ? return_value : &return_value_stack, ffi_args); + delete[] ffi_args; + /* * Fourth, convert the return value & OUT-arguments back to JS @@ -530,6 +529,8 @@ Local FunctionCall ( } } + delete[] total_arg_values; + return jsReturnValue; } From be1d42568755619849e7eaca9afc1c34d349b5f2 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Mon, 6 Jun 2022 17:38:17 +0300 Subject: [PATCH 05/35] Remove GCC attribute MSVC doesn't know At some point something like https://stackoverflow.com/questions/4226308/msvc-equivalent-of-attribute-warn-unused-result/22759336#22759336 should be used --- src/value.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/value.h b/src/value.h index a23ea6f..759b871 100644 --- a/src/value.h +++ b/src/value.h @@ -26,7 +26,7 @@ void FreeGIArgument (GITypeInfo *type_info, GIArgument *argument, GITran void FreeGIArgumentArray (GITypeInfo *type_info, GIArgument *arg, GITransfer transfer = GI_TRANSFER_EVERYTHING, GIDirection direction = GI_DIRECTION_OUT, long length = -1); bool CanConvertV8ToGIArgument (GITypeInfo *type_info, Local value, bool may_be_null); -bool V8ToGValue(GValue *gvalue, Local value, bool mustCopy = false) __attribute__((warn_unused_result)); +bool V8ToGValue(GValue *gvalue, Local value, bool mustCopy = false); Local GValueToV8(const GValue *gvalue, bool mustCopy = false); bool CanConvertV8ToGValue(GValue *gvalue, Local value); From 8dfeea3784c6663ff169b93ead39e8864fdc8bf7 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Mon, 6 Jun 2022 18:01:17 +0300 Subject: [PATCH 06/35] Replace uint with guint https://developer-old.gnome.org/gobject/stable/gobject-Closures.html#GClosureMarshal --- src/closure.cc | 2 +- src/closure.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/closure.cc b/src/closure.cc index 2d1ee36..39fbf53 100644 --- a/src/closure.cc +++ b/src/closure.cc @@ -123,7 +123,7 @@ void Closure::Execute(GICallableInfo *info, guint signal_id, void Closure::Marshal(GClosure *base, GValue *g_return_value, - uint n_param_values, + guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { diff --git a/src/closure.h b/src/closure.h index 19e621b..f1aae9b 100644 --- a/src/closure.h +++ b/src/closure.h @@ -35,7 +35,7 @@ struct Closure { static void Marshal(GClosure *closure, GValue *g_return_value, - uint argc, const GValue *g_argv, + guint argc, const GValue *g_argv, gpointer invocation_hint, gpointer marshal_data); From 25c562b2d39797c9b5a108736132e94ea9872842 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Mon, 6 Jun 2022 18:53:11 +0300 Subject: [PATCH 07/35] Move cflags & ldflags to Linux only --- binding.gyp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/binding.gyp b/binding.gyp index 6c47270..40623f8 100644 --- a/binding.gyp +++ b/binding.gyp @@ -39,21 +39,20 @@ "include_dirs" : [ " Date: Mon, 6 Jun 2022 19:40:53 +0300 Subject: [PATCH 08/35] Get rid of Darwin and force local node-pre-gyp --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index d282bac..06ba6c8 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,11 @@ "description": "GNOME Gtk+ bindings for NodeJS", "main": "lib/index.js", "scripts": { - "install": "if [ \"$(uname)\" = \"Darwin\" ] && [ \"$(which brew)\" != \"\" ]; then export PKG_CONFIG_PATH=$(brew --prefix libffi)/lib/pkgconfig; fi; node-pre-gyp install --fallback-to-build", + "install": "npx node-pre-gyp install --fallback-to-build", "test": "mocha tests/__run__.js", - "build": "node-pre-gyp build", - "build:full": "node-pre-gyp rebuild", - "configure": "node-pre-gyp configure --debug" + "build": "npx node-pre-gyp build", + "build:full": "npx node-pre-gyp rebuild", + "configure": "npx node-pre-gyp configure --debug" }, "repository": { "type": "git", From 8a880b9e3a8b9fb00d74258eceb3e80ce95b831a Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Mon, 6 Jun 2022 20:08:33 +0300 Subject: [PATCH 09/35] Replace NAN_EXPORT with Nan:Export Fixes gi.cc(373): error C3861: 'Export': identifier not found On Windows, for unclear reason the Nan namespace is lost for NAN_EXPORT(exports, RegisterClass) --- src/gi.cc | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/gi.cc b/src/gi.cc index f955e79..b897840 100644 --- a/src/gi.cc +++ b/src/gi.cc @@ -345,22 +345,22 @@ NAN_METHOD(RegisterVFunc) { void InitModule(Local exports, Local module, void *priv) { GNodeJS::AsyncCallEnvironment::Initialize(); - NAN_EXPORT(exports, Bootstrap); - NAN_EXPORT(exports, GetModuleCache); - NAN_EXPORT(exports, GetBaseClass); - NAN_EXPORT(exports, GetTypeSize); - NAN_EXPORT(exports, GetConstantValue); - NAN_EXPORT(exports, MakeBoxedClass); - NAN_EXPORT(exports, MakeObjectClass); - NAN_EXPORT(exports, MakeFunction); - NAN_EXPORT(exports, StructFieldGetter); - NAN_EXPORT(exports, StructFieldSetter); - NAN_EXPORT(exports, ObjectPropertyGetter); - NAN_EXPORT(exports, ObjectPropertySetter); - NAN_EXPORT(exports, StartLoop); - NAN_EXPORT(exports, GetLoopStack); - NAN_EXPORT(exports, RegisterClass); - NAN_EXPORT(exports, RegisterVFunc); + Nan::Export(exports, "Bootstrap", Bootstrap); + Nan::Export(exports, "GetModuleCache", GetModuleCache); + Nan::Export(exports, "GetBaseClass", GetBaseClass); + Nan::Export(exports, "GetTypeSize", GetTypeSize); + Nan::Export(exports, "GetConstantValue", GetConstantValue); + Nan::Export(exports, "MakeBoxedClass", MakeBoxedClass); + Nan::Export(exports, "MakeObjectClass", MakeObjectClass); + Nan::Export(exports, "MakeFunction", MakeFunction); + Nan::Export(exports, "StructFieldGetter", StructFieldGetter); + Nan::Export(exports, "StructFieldSetter", StructFieldSetter); + Nan::Export(exports, "ObjectPropertyGetter", ObjectPropertyGetter); + Nan::Export(exports, "ObjectPropertySetter", ObjectPropertySetter); + Nan::Export(exports, "StartLoop", StartLoop); + Nan::Export(exports, "GetLoopStack", GetLoopStack); + Nan::Export(exports, "RegisterClass", RegisterClass); + Nan::Export(exports, "RegisterVFunc", RegisterVFunc); Nan::Set(exports, UTF8("System"), GNodeJS::System::GetModule()); Nan::Set(exports, UTF8("Cairo"), GNodeJS::Cairo::GetModule()); From be2aca7561db8c21ec6a511aaca2521404563e57 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Mon, 6 Jun 2022 20:24:39 +0300 Subject: [PATCH 10/35] Don't call g_source_add_unix_fd on Windows --- src/loop.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/loop.cc b/src/loop.cc index 85bc0ba..63d757e 100644 --- a/src/loop.cc +++ b/src/loop.cc @@ -92,9 +92,14 @@ static GSourceFuncs uv_loop_source_funcs = { static GSource *loop_source_new (uv_loop_t *loop) { struct uv_loop_source *source = (struct uv_loop_source *) g_source_new (&uv_loop_source_funcs, sizeof (*source)); source->loop = loop; +#if OS_WINDOWS + // FIXME + // https://github.com/nodejs/node/issues/36015 +#else g_source_add_unix_fd (&source->source, uv_backend_fd (loop), (GIOCondition) (G_IO_IN | G_IO_OUT | G_IO_ERR)); +#endif return &source->source; } From c833cdd45052b244e0a635856dc72aa60785f6ce Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Tue, 7 Jun 2022 13:32:24 +0300 Subject: [PATCH 11/35] Add Windows build config --- binding.gyp | 21 +++++++++++++++++---- windows/make_include_extra.cmd | 22 ++++++++++++++++++++++ windows/make_include_extra.sh | 22 ++++++++++++++++++++++ 3 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 windows/make_include_extra.cmd create mode 100644 windows/make_include_extra.sh diff --git a/binding.gyp b/binding.gyp index 40623f8..e862a1e 100644 --- a/binding.gyp +++ b/binding.gyp @@ -70,16 +70,29 @@ }], ['OS == "win"', { "defines": [ - "uint=unsigned int", + "uint=uint32_t", + "ulong=uint64_t", "PLATFORM_WIN=1", ], "include_dirs": [ - "include", + # We don't want to include /msys64/mingw64/include directly + "nul +copy /y %SRC_DIR%\ffitarget.h %DST_DIR% >nul + +set FC_DIR=%DST_DIR%\fontconfig +if not exist %FC_DIR% mkdir %FC_DIR% +copy /y %SRC_DIR%\fontconfig\fcfreetype.h %FC_DIR% >nul +copy /y %SRC_DIR%\fontconfig\fcprivate.h %FC_DIR% >nul +copy /y %SRC_DIR%\fontconfig\fontconfig.h %FC_DIR% >nul + +echo %DST_DIR% diff --git a/windows/make_include_extra.sh b/windows/make_include_extra.sh new file mode 100644 index 0000000..42f568b --- /dev/null +++ b/windows/make_include_extra.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# It'a assumed MSYS2 is installed in C:\msys64 + +# To use inside "include_dirs" for 'OS == "win"' add: +# " Date: Tue, 7 Jun 2022 19:55:11 +0300 Subject: [PATCH 12/35] Fix Windows include path --- binding.gyp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/binding.gyp b/binding.gyp index e862a1e..79be2a8 100644 --- a/binding.gyp +++ b/binding.gyp @@ -76,9 +76,8 @@ ], "include_dirs": [ # We don't want to include /msys64/mingw64/include directly - " Date: Wed, 8 Jun 2022 17:35:49 +0300 Subject: [PATCH 13/35] Use g_free where appropriate Fixes segfault on Windows --- src/debug.cc | 4 ++-- src/value.cc | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/debug.cc b/src/debug.cc index 6538408..091b9f6 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -158,7 +158,7 @@ void print_callable_info (GICallableInfo *info) { g_callable_info_load_return_type(info, &return_info); auto typeName = GetTypeName(&return_info); printf("%s %s (", typeName, g_base_info_get_name(info)); - free(typeName); + g_free(typeName); int n_args = g_callable_info_get_n_args(info); for (int i = 0; i < n_args; i++) { @@ -168,7 +168,7 @@ void print_callable_info (GICallableInfo *info) { g_arg_info_load_type(&arg_info, &type_info); auto typeName = GetTypeName(&type_info); printf("%s %s", typeName, g_base_info_get_name(&arg_info)); - free(typeName); + g_free(typeName); if (i < n_args - 1) printf(", "); } diff --git a/src/value.cc b/src/value.cc index 041751b..35cb45b 100644 --- a/src/value.cc +++ b/src/value.cc @@ -648,14 +648,14 @@ gpointer V8ToGHash (GITypeInfo *type_info, Local value) { if (!V8ToGIArgument(key_type_info, &key_arg, key, false)) { char* message = g_strdup_printf("Couldn't convert key '%s'", *Nan::Utf8String(key)); Nan::ThrowError(message); - free(message); + g_free(message); goto item_error; } if (!V8ToGIArgument(value_type_info, &value_arg, value, false)) { char* message = g_strdup_printf("Couldn't convert value for key '%s'", *Nan::Utf8String(key)); Nan::ThrowError(message); - free(message); + g_free(message); goto item_error; } @@ -1333,7 +1333,7 @@ void FreeGIArgumentArray(GITypeInfo *type_info, GIArgument *arg, GITransfer tran switch (array_type) { case GI_ARRAY_TYPE_C: { - free(data); + g_free(data); break; } case GI_ARRAY_TYPE_ARRAY: From c4c90fe914ff08071d4a22c410e42b5643596187 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Thu, 9 Jun 2022 16:25:58 +0300 Subject: [PATCH 14/35] Add GitHub workflow for Windows --- .github/workflows/main.yaml | 38 +++++++++++++++++++ README.md | 9 ++++- binding.gyp | 36 +++++++++++------- windows/make_include_extra.cmd | 22 ----------- ...nclude_extra.sh => mingw_include_extra.sh} | 7 +--- windows/mingw_windows_path.sh | 5 +++ 6 files changed, 74 insertions(+), 43 deletions(-) delete mode 100644 windows/make_include_extra.cmd rename windows/{make_include_extra.sh => mingw_include_extra.sh} (66%) create mode 100644 windows/mingw_windows_path.sh diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 84846c2..21512d5 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -1,6 +1,44 @@ name: main on: [push, pull_request] jobs: + build-windows: + name: windows - nodejs ${{ matrix.node }} + runs-on: windows-latest + strategy: + matrix: + node: + - 12 + defaults: + run: + shell: msys2 {0} + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: 12 + - uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + update: true + install: git mingw-w64-x86_64-gtk3 mingw-w64-x86_64-gobject-introspection mingw-w64-x86_64-cairo + + - name: Install VS 2017 + shell: cmd + run: choco upgrade -y visualstudio2017-workload-vctools + + - name: Install & Build + run: | + ./windows/mingw_include_extra.sh + export PATH="$PATH:/c/hostedtoolcache/windows/node/12.22.12/x64" + export MINGW_WINDOWS_PATH=$(./windows/mingw_windows_path.sh) + npm config set msvs_version 2017 + npm install --build-from-source + + - name: Run initial test + run: | + export PATH="$PATH:/c/hostedtoolcache/windows/node/12.22.12/x64" + node tests/api.js + build: name: ${{ matrix.os }} - nodejs ${{ matrix.node }} runs-on: ${{ matrix.os }} diff --git a/README.md b/README.md index 3a3a3ad..e5c24b6 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Node-Gtk is a [gobject-introspection](https://gi.readthedocs.io/en/latest) libra use any introspected library, such as Gtk+, usable. It is similar in essence to [GJS](https://wiki.gnome.org/action/show/Projects/Gjs) or [PyGObject](https://pygobject.readthedocs.io). Please note this project is currently in a _beta_ state and is being developed. Any contributors willing to help will be welcomed. -Supported Node.js versions: **12**, **14**, **15**, **16** (other versions should work but are untested) +Supported Node.js versions: **12**, **14**, **15**, **16** (other versions should work but are untested) Pre-built binaries available for: **Linux**, **macOS** ### Table of contents @@ -218,6 +218,13 @@ cd ~/oss git clone https://github.com/romgrk/node-gtk cd node-gtk +# don't include /mingw64/include directly since it conflicts with +# Windows SDK headers. we copy needed headers to __extra__ directory: +./windows/mingw_include_extra.sh + +# if MSYS2 is NOT installed in C:/msys64 run: +export MINGW_WINDOWS_PATH=$(./windows/mingw_windows_path.sh) + # first run might take a while GYP_MSVS_VERSION=2015 npm install ``` diff --git a/binding.gyp b/binding.gyp index 79be2a8..7ecaa5c 100644 --- a/binding.gyp +++ b/binding.gyp @@ -74,24 +74,32 @@ "ulong=uint64_t", "PLATFORM_WIN=1", ], + "variables": { + # If MSYS2 is NOT installed in C:/msys64 run: + # $ export MINGW_WINDOWS_PATH=$(./windows/mingw_windows_path.sh) + # before compiling + "MINGW_PREFIX": "nul -copy /y %SRC_DIR%\ffitarget.h %DST_DIR% >nul - -set FC_DIR=%DST_DIR%\fontconfig -if not exist %FC_DIR% mkdir %FC_DIR% -copy /y %SRC_DIR%\fontconfig\fcfreetype.h %FC_DIR% >nul -copy /y %SRC_DIR%\fontconfig\fcprivate.h %FC_DIR% >nul -copy /y %SRC_DIR%\fontconfig\fontconfig.h %FC_DIR% >nul - -echo %DST_DIR% diff --git a/windows/make_include_extra.sh b/windows/mingw_include_extra.sh similarity index 66% rename from windows/make_include_extra.sh rename to windows/mingw_include_extra.sh index 42f568b..3063967 100644 --- a/windows/make_include_extra.sh +++ b/windows/mingw_include_extra.sh @@ -1,10 +1,5 @@ #!/bin/bash -# It'a assumed MSYS2 is installed in C:\msys64 - -# To use inside "include_dirs" for 'OS == "win"' add: -# " Date: Sat, 11 Jun 2022 17:18:44 +0300 Subject: [PATCH 15/35] Add Node.js 16 Windows build --- .github/workflows/main.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 21512d5..ce62c18 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -7,6 +7,7 @@ jobs: strategy: matrix: node: + - 16 - 12 defaults: run: From 002f0d1ec7dc520cc4a69a1a1a17cdcd527ee3d8 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Tue, 14 Jun 2022 19:06:29 +0300 Subject: [PATCH 16/35] Use appropriate Node.js version --- .github/workflows/main.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index ce62c18..e7f322c 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -16,10 +16,11 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: 12 + node-version: ${{ matrix.node }} - uses: msys2/setup-msys2@v2 with: msystem: MINGW64 + path-type: inherit update: true install: git mingw-w64-x86_64-gtk3 mingw-w64-x86_64-gobject-introspection mingw-w64-x86_64-cairo @@ -30,15 +31,12 @@ jobs: - name: Install & Build run: | ./windows/mingw_include_extra.sh - export PATH="$PATH:/c/hostedtoolcache/windows/node/12.22.12/x64" export MINGW_WINDOWS_PATH=$(./windows/mingw_windows_path.sh) npm config set msvs_version 2017 npm install --build-from-source - name: Run initial test - run: | - export PATH="$PATH:/c/hostedtoolcache/windows/node/12.22.12/x64" - node tests/api.js + run: node tests/api.js build: name: ${{ matrix.os }} - nodejs ${{ matrix.node }} From 8bd78afd22c7d8b39d78e816587ccd9e30883e65 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Mon, 20 Jun 2022 16:03:58 +0300 Subject: [PATCH 17/35] Ensure arg is zeroed Fixes some segfaults on Windows, like const val = new GObject.Value() val.init(GObject.TYPE_STRING) <- crash --- src/value.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/value.cc b/src/value.cc index 35cb45b..f413189 100644 --- a/src/value.cc +++ b/src/value.cc @@ -679,6 +679,8 @@ gpointer V8ToGHash (GITypeInfo *type_info, Local value) { bool V8ToGIArgument(GIBaseInfo *gi_info, GIArgument *arg, Local value) { GIInfoType type = g_base_info_get_type (gi_info); + memset(arg, 0, sizeof(GIArgument)); + switch (type) { case GI_INFO_TYPE_BOXED: case GI_INFO_TYPE_STRUCT: @@ -716,6 +718,8 @@ bool V8ToGIArgument(GIBaseInfo *gi_info, GIArgument *arg, Local value) { bool V8ToGIArgument(GITypeInfo *type_info, GIArgument *arg, Local value, bool may_be_null) { GITypeTag type_tag = g_type_info_get_tag (type_info); + memset(arg, 0, sizeof(GIArgument)); + if (value->IsUndefined () || value->IsNull ()) { arg->v_pointer = NULL; @@ -867,6 +871,8 @@ bool V8ToOutGIArgument(GITypeInfo *type_info, GIArgument *arg, Local valu */ GITypeTag type_tag = g_type_info_get_tag (type_info); + memset(arg, 0, sizeof(GIArgument)); + if (value->IsUndefined () || value->IsNull ()) { arg->v_pointer = NULL; From 858e1da6eabf6cd6277c0e36541a3bf0cf963b72 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Tue, 5 Jul 2022 12:56:56 +0300 Subject: [PATCH 18/35] Improve tests skipping --- tests/__run__.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/__run__.js b/tests/__run__.js index 98f9c97..9173a81 100644 --- a/tests/__run__.js +++ b/tests/__run__.js @@ -21,13 +21,15 @@ const watchdog = setTimeout(() => { }, 10 * 60 * 1000) watchdog.unref() -const skipPattern = process.argv +// usage: npx mocha [--skip=pat1[,pat2...]] [--skip=...] tests/__run__.js +const skipPatterns = process.argv .filter(a => a.startsWith('--skip=')) - .map(a => new RegExp(a.replace('--skip=', '')))[0] + .flatMap(a => a.replace('--skip=', '').split(',')) + .map(a => new RegExp(a)) files.forEach(file => { - if (skipPattern && skipPattern.test(file)) + if (skipPatterns.reduce((acc, pat) => acc || pat.test(file), false)) return it(file, function(done) { From 0c4d415489b977f690b55059d32d0716d1bed513 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Tue, 5 Jul 2022 16:36:54 +0300 Subject: [PATCH 19/35] Skip tests knows to fail on Windows --- .github/workflows/main.yaml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index e7f322c..707d563 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -36,7 +36,23 @@ jobs: npm install --build-from-source - name: Run initial test - run: node tests/api.js + run: | + npx mocha --skip=boxed__initialization \ + --skip=boxed__properties \ + --skip=callback \ + --skip=conversion__array \ + --skip=conversion__char \ + --skip=function_call__inout \ + --skip=gvalue \ + --skip=loop \ + --skip=register-class \ + --skip=require \ + --skip=signal.js \ + --skip=signal__non-introspected \ + --skip=object__non-introspected \ + --skip=object__property \ + --skip=union__fields \ + tests/__run__.js build: name: ${{ matrix.os }} - nodejs ${{ matrix.node }} From 67d8e9b6ae516e1dc0f0af2b108686cf3415ea98 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Tue, 5 Jul 2022 16:50:09 +0300 Subject: [PATCH 20/35] Install gstreamer and libsoop to Windows --- .github/workflows/main.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 707d563..b496074 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -22,7 +22,7 @@ jobs: msystem: MINGW64 path-type: inherit update: true - install: git mingw-w64-x86_64-gtk3 mingw-w64-x86_64-gobject-introspection mingw-w64-x86_64-cairo + install: git mingw-w64-x86_64-gtk3 mingw-w64-x86_64-gobject-introspection mingw-w64-x86_64-cairo mingw-w64-x86_64-gstreamer mingw-w64-x86_64-libsoup - name: Install VS 2017 shell: cmd From bd8bf10478e35b1f810c14cd8363f61a93b73412 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Tue, 5 Jul 2022 17:38:10 +0300 Subject: [PATCH 21/35] Fix require test on Windows --- .github/workflows/main.yaml | 1 - tests/require.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index b496074..c8f5851 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -46,7 +46,6 @@ jobs: --skip=gvalue \ --skip=loop \ --skip=register-class \ - --skip=require \ --skip=signal.js \ --skip=signal__non-introspected \ --skip=object__non-introspected \ diff --git a/tests/require.js b/tests/require.js index 965978f..fb5ab3e 100644 --- a/tests/require.js +++ b/tests/require.js @@ -59,7 +59,7 @@ describe('gi.require() works for all modules', async () => { function testRequire(module, i, modules) { return new Promise((resolve, reject) => { - const modulePath = path.join(__dirname, '..') + const modulePath = path.posix.join(__dirname, '..') const cmd = `node -e "const gi = require('${modulePath}'); gi.require('${module.name}', '${module.version}')"` const options = { maxBuffer: 10 * 1024 * 1024, From a1e0f72660d4d493ac6025fcf83ce91be7e40f35 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Thu, 7 Jul 2022 16:40:31 +0300 Subject: [PATCH 22/35] Don't free something that is not zero terminated Fixes some crases on Windows. Fixes 5 tests --- .github/workflows/main.yaml | 11 +++-------- src/value.cc | 13 ++++++++++++- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index c8f5851..ee77c17 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -35,21 +35,16 @@ jobs: npm config set msvs_version 2017 npm install --build-from-source - - name: Run initial test + - name: Run tests run: | - npx mocha --skip=boxed__initialization \ - --skip=boxed__properties \ - --skip=callback \ + npx mocha --skip=callback \ --skip=conversion__array \ --skip=conversion__char \ - --skip=function_call__inout \ --skip=gvalue \ - --skip=loop \ + --skip=object__non-introspected \ --skip=register-class \ --skip=signal.js \ --skip=signal__non-introspected \ - --skip=object__non-introspected \ - --skip=object__property \ --skip=union__fields \ tests/__run__.js diff --git a/src/value.cc b/src/value.cc index f413189..073a4a0 100644 --- a/src/value.cc +++ b/src/value.cc @@ -1339,7 +1339,18 @@ void FreeGIArgumentArray(GITypeInfo *type_info, GIArgument *arg, GITransfer tran switch (array_type) { case GI_ARRAY_TYPE_C: { - g_free(data); +#if OS_WINDOWS + bool isZeroTerminated = g_type_info_is_zero_terminated (type_info); + if (isZeroTerminated) { + g_free (data); + } else { + // Freeing something that is non-zero terminated + // crashes on Windows. + // TODO: Investigate what it is + } +#else + g_free (data); +#endif break; } case GI_ARRAY_TYPE_ARRAY: From 3ba64dac10b7be6c3b6a9205a0ad68f0de1ce610 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Thu, 7 Jul 2022 17:07:07 +0300 Subject: [PATCH 23/35] Ensure allocated memory is zeroed Fixes 1 test on Windows --- .github/workflows/main.yaml | 1 - src/function.cc | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index ee77c17..e37e019 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -39,7 +39,6 @@ jobs: run: | npx mocha --skip=callback \ --skip=conversion__array \ - --skip=conversion__char \ --skip=gvalue \ --skip=object__non-introspected \ --skip=register-class \ diff --git a/src/function.cc b/src/function.cc index ba73d82..5063cb6 100644 --- a/src/function.cc +++ b/src/function.cc @@ -324,7 +324,7 @@ Local FunctionCall ( * and for error, if it can throw */ - GIArgument *total_arg_values = new GIArgument[func->n_total_args]; + GIArgument *total_arg_values = new GIArgument[func->n_total_args](); GIArgument *callable_arg_values; GError *error_stack = nullptr; @@ -446,11 +446,11 @@ Local FunctionCall ( * Third, make the actual ffi_call */ - void **ffi_args = new void*[func->n_total_args]; + void **ffi_args = new void*[func->n_total_args](); for (int i = 0; i < func->n_total_args; i++) ffi_args[i] = (void *)&total_arg_values[i]; - GIArgument return_value_stack; + GIArgument return_value_stack = {0}; ffi_call (&func->invoker.cif, FFI_FN (func->invoker.native_address), use_return_value ? return_value : &return_value_stack, ffi_args); From 93ce7e45c43f7ac98c1be1b03d76a1199da02b52 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Thu, 7 Jul 2022 17:28:13 +0300 Subject: [PATCH 24/35] GType is gsize, not gulong GType is gsize is 8 bytes gulong is 8 bytes on Linux and 4 bytes Windows Fixes some segfaults on Windows Fixes 3 tests on Windows --- .github/workflows/main.yaml | 3 --- src/value.cc | 12 ++++++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index e37e019..57a1fde 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -39,10 +39,7 @@ jobs: run: | npx mocha --skip=callback \ --skip=conversion__array \ - --skip=gvalue \ --skip=object__non-introspected \ - --skip=register-class \ - --skip=signal.js \ --skip=signal__non-introspected \ --skip=union__fields \ tests/__run__.js diff --git a/src/value.cc b/src/value.cc index 073a4a0..cdd84d3 100644 --- a/src/value.cc +++ b/src/value.cc @@ -68,8 +68,8 @@ Local GIArgumentToV8(GITypeInfo *type_info, GIArgument *arg, long length, case GI_TYPE_TAG_UINT64: return New (arg->v_uint64); - case GI_TYPE_TAG_GTYPE: /* c++: gulong */ - return v8::BigInt::NewFromUnsigned(Isolate::GetCurrent(), arg->v_ulong); + case GI_TYPE_TAG_GTYPE: /* c++: gsize */ + return v8::BigInt::NewFromUnsigned(Isolate::GetCurrent(), arg->v_size); case GI_TYPE_TAG_UNICHAR: { @@ -780,9 +780,9 @@ bool V8ToGIArgument(GITypeInfo *type_info, GIArgument *arg, Local value, break; case GI_TYPE_TAG_GTYPE: if (value->IsBigInt()) - arg->v_ulong = value.As()->Uint64Value(); + arg->v_size = value.As()->Uint64Value(); else - arg->v_ulong = Nan::To (value).ToChecked(); + arg->v_size = Nan::To (value).ToChecked(); break; case GI_TYPE_TAG_UTF8: @@ -926,9 +926,9 @@ bool V8ToOutGIArgument(GITypeInfo *type_info, GIArgument *arg, Local valu break; case GI_TYPE_TAG_GTYPE: if (value->IsBigInt()) - *(gulong*)arg->v_pointer = value.As()->Uint64Value(); + *(gsize*)arg->v_pointer = value.As()->Uint64Value(); else - *(gulong*)arg->v_pointer = Nan::To (value).ToChecked(); + *(gsize*)arg->v_pointer = Nan::To (value).ToChecked(); break; case GI_TYPE_TAG_UTF8: From e00de6988e69c3e6803fb0cf61c1cc152d165a30 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Thu, 7 Jul 2022 18:33:51 +0300 Subject: [PATCH 25/35] Get rid of platform specific uint and ulong --- binding.gyp | 2 -- src/callback.cc | 17 ++++++++--------- src/closure.cc | 8 ++++---- src/closure.h | 2 +- src/gobject.cc | 10 +++++----- src/value.cc | 10 +++++----- 6 files changed, 23 insertions(+), 26 deletions(-) diff --git a/binding.gyp b/binding.gyp index 7ecaa5c..fed88c2 100644 --- a/binding.gyp +++ b/binding.gyp @@ -70,8 +70,6 @@ }], ['OS == "win"', { "defines": [ - "uint=uint32_t", - "ulong=uint64_t", "PLATFORM_WIN=1", ], "variables": { diff --git a/src/callback.cc b/src/callback.cc index 7dd55b1..8655c3c 100644 --- a/src/callback.cc +++ b/src/callback.cc @@ -22,7 +22,7 @@ using Nan::TryCatch; namespace GNodeJS { -static uint callbackLevel = 0; +static guint callbackLevel = 0; static GSList* notifiedCallbacks = NULL; static Local GetSelfInstance(GIArgument **args) { @@ -91,10 +91,10 @@ void Callback::Execute (GIArgument *result, GIArgument **args, Callback *callbac /* Skip the object instance in first place */ int args_offset = isVFunc ? 1 : 0; - uint n_native_args = (uint) g_callable_info_get_n_args(callback->info); - uint n_return_values = 1; + guint n_native_args = (guint) g_callable_info_get_n_args(callback->info); + guint n_return_values = 1; - uint primitive_out_arguments_mask = 0; + guint primitive_out_arguments_mask = 0; #ifndef __linux__ Local* js_args = new Local[n_native_args]; @@ -102,7 +102,7 @@ void Callback::Execute (GIArgument *result, GIArgument **args, Callback *callbac Local js_args[n_native_args]; #endif - for (uint i = 0; i < n_native_args; i++) { + for (auto i = 0; i < n_native_args; i++) { GIArgInfo arg_info; GITypeInfo arg_type; g_callable_info_load_arg (callback->info, i, &arg_info); @@ -144,12 +144,11 @@ void Callback::Execute (GIArgument *result, GIArgument **args, Callback *callbac auto jsReturnValue = maybeReturnValue.ToLocalChecked(); auto jsRealReturnValue = jsReturnValue; Local jsReturnArray; - uint returnIndex = 0; + guint returnIndex = 0; bool success; bool isOutPrimitive; - uint n_js_return_values = n_return_values - (hasVoidReturn ? 1 : 0); + guint n_js_return_values = n_return_values - (hasVoidReturn ? 1 : 0); - uint i; GIArgInfo arg_info; GITypeInfo arg_type; @@ -172,7 +171,7 @@ void Callback::Execute (GIArgument *result, GIArgument **args, Callback *callbac else jsRealReturnValue = Nan::Get(jsReturnArray, returnIndex++).ToLocalChecked(); - for (i = 0; i < n_native_args; i++) { + for (auto i = 0; i < n_native_args; i++) { isOutPrimitive = (primitive_out_arguments_mask & (1 << i)) != 0; if (!isOutPrimitive) continue; diff --git a/src/closure.cc b/src/closure.cc index 39fbf53..20813b2 100644 --- a/src/closure.cc +++ b/src/closure.cc @@ -35,7 +35,7 @@ GClosure *Closure::New (Local function, GICallableInfo* info, guint si void Closure::Execute(GICallableInfo *info, guint signal_id, const Nan::Persistent &persFn, - GValue *g_return_value, uint n_param_values, + GValue *g_return_value, guint n_param_values, const GValue *param_values) { Nan::HandleScope scope; auto func = Nan::New(persFn); @@ -45,7 +45,7 @@ void Closure::Execute(GICallableInfo *info, guint signal_id, g_signal_query(signal_id, &signal_query); // We don't pass the implicit instance as first argument - uint n_js_args = n_param_values - 1; + auto n_js_args = n_param_values - 1; #ifndef __linux__ Local* js_args = new Local[n_js_args]; @@ -58,7 +58,7 @@ void Closure::Execute(GICallableInfo *info, guint signal_id, GIArgument argument; GIArgInfo arg_info; GITypeInfo type_info; - for (uint i = 1; i < n_param_values; i++) { + for (auto i = 1; i < n_param_values; i++) { memcpy(&argument, ¶m_values[i].data[0], sizeof(GIArgument)); g_callable_info_load_arg(info, i - 1, &arg_info); g_arg_info_load_type(&arg_info, &type_info); @@ -76,7 +76,7 @@ void Closure::Execute(GICallableInfo *info, guint signal_id, } } else { /* CallableInfo is not available: use GValueToV8 */ - for (uint i = 1; i < n_param_values; i++) { + for (auto i = 1; i < n_param_values; i++) { bool mustCopy = true; if (signal_query.signal_id) { diff --git a/src/closure.h b/src/closure.h index f1aae9b..792f8c9 100644 --- a/src/closure.h +++ b/src/closure.h @@ -30,7 +30,7 @@ struct Closure { static void Execute(GICallableInfo *info, guint signal_id, const Nan::Persistent &persFn, - GValue *g_return_value, uint n_param_values, + GValue *g_return_value, guint n_param_values, const GValue *param_values); static void Marshal(GClosure *closure, diff --git a/src/gobject.cc b/src/gobject.cc index caa2341..586d041 100644 --- a/src/gobject.cc +++ b/src/gobject.cc @@ -350,7 +350,7 @@ NAN_METHOD(SignalConnect) { guint signalId; GQuark detail; GClosure *gclosure; - ulong handler_id; + gulong handler_id; const char *signalName = *Nan::Utf8String (TO_STRING (info[0])); if (!g_signal_parse_name(signalName, gtype, &signalId, &detail, FALSE)) { @@ -390,7 +390,7 @@ NAN_METHOD(SignalDisconnect) { } gpointer instance = static_cast(gobject); - ulong handler_id = TO_LONG (info[0]); + gulong handler_id = TO_LONG (info[0]); g_signal_handler_disconnect (instance, handler_id); info.GetReturnValue().Set((double)handler_id); @@ -447,7 +447,7 @@ NAN_METHOD(SignalEmit) { g_value_set_object(&args[0], gobject); failed = false; - for (uint i = 0; i < signal_query.n_params; i++) { + for (auto i = 0; i < signal_query.n_params; i++) { GValue *gvalue = &args[i + 1]; g_value_init(gvalue, signal_query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE); @@ -470,7 +470,7 @@ NAN_METHOD(SignalEmit) { } } - for (uint i = 0; i < argc; i++) { + for (auto i = 0; i < argc; i++) { g_value_unset(&args[i]); } } @@ -490,7 +490,7 @@ NAN_METHOD(GObjectToString) { char *className = *Nan::Utf8String(self->GetConstructorName()); void *address = self->GetAlignedPointerFromInternalField(0); - char *str = g_strdup_printf("[%s:%s %#zx]", typeName, className, (unsigned long)address); + char *str = g_strdup_printf("[%s:%s %#zx]", typeName, className, (size_t)address); info.GetReturnValue().Set(UTF8(str)); g_free(str); diff --git a/src/value.cc b/src/value.cc index cdd84d3..9a22d92 100644 --- a/src/value.cc +++ b/src/value.cc @@ -349,7 +349,7 @@ Local ArrayToV8 (GITypeInfo *type_info, void* data, long length) { if (length != -1 && i >= length) break; - void** pointer = (void**)((ulong)data + i * item_size); + void** pointer = (void**)((size_t)data + i * item_size); memcpy(&value, pointer, item_size); if (length == -1 && isZero(value, item_type_info)) @@ -466,7 +466,7 @@ static void *V8ArrayToCArray(GITypeInfo *type_info, Local value) { GIArgument arg; if (V8ToGIArgument(element_info, &arg, value, true)) { - void* pointer = (void*)((ulong)result + i * element_size); + void* pointer = (void*)((size_t)result + i * element_size); memcpy(pointer, &arg, element_size); } else { WARN("couldnt convert value: %s", *Nan::Utf8String(TO_STRING (value))); @@ -474,7 +474,7 @@ static void *V8ArrayToCArray(GITypeInfo *type_info, Local value) { } if (isZeroTerminated) { - void* pointer = (void*)((ulong)result + length * element_size); + void* pointer = (void*)((size_t)result + length * element_size); memset(pointer, 0, element_size); } @@ -495,7 +495,7 @@ static void *V8TypedArrayToCArray(GITypeInfo *type_info, Local value) { array->CopyContents(result, length); if (isZeroTerminated) { - void* pointer = (void*)((ulong)result + length * element_size); + void* pointer = (void*)((size_t)result + length * element_size); memset(pointer, 0, element_size); } @@ -1320,7 +1320,7 @@ void FreeGIArgumentArray(GITypeInfo *type_info, GIArgument *arg, GITransfer tran for (int i = 0; i < length; i++) { GIArgument item; - memcpy (&item, (void*)((ulong)data + element_size * i), sizeof (GIArgument)); + memcpy (&item, (void*)((size_t)data + element_size * i), sizeof (GIArgument)); FreeGIArgument (element_info, &item, item_transfer, direction); } From 08a0eef769c9d667a7fb163e0d00013a3ab1ee0f Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Thu, 7 Jul 2022 18:45:11 +0300 Subject: [PATCH 26/35] Use specific types to mute warnings on Linux --- src/callback.cc | 4 ++-- src/closure.cc | 4 ++-- src/gobject.cc | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/callback.cc b/src/callback.cc index 8655c3c..273bd42 100644 --- a/src/callback.cc +++ b/src/callback.cc @@ -102,7 +102,7 @@ void Callback::Execute (GIArgument *result, GIArgument **args, Callback *callbac Local js_args[n_native_args]; #endif - for (auto i = 0; i < n_native_args; i++) { + for (guint i = 0; i < n_native_args; i++) { GIArgInfo arg_info; GITypeInfo arg_type; g_callable_info_load_arg (callback->info, i, &arg_info); @@ -171,7 +171,7 @@ void Callback::Execute (GIArgument *result, GIArgument **args, Callback *callbac else jsRealReturnValue = Nan::Get(jsReturnArray, returnIndex++).ToLocalChecked(); - for (auto i = 0; i < n_native_args; i++) { + for (guint i = 0; i < n_native_args; i++) { isOutPrimitive = (primitive_out_arguments_mask & (1 << i)) != 0; if (!isOutPrimitive) continue; diff --git a/src/closure.cc b/src/closure.cc index 20813b2..4b5bc73 100644 --- a/src/closure.cc +++ b/src/closure.cc @@ -58,7 +58,7 @@ void Closure::Execute(GICallableInfo *info, guint signal_id, GIArgument argument; GIArgInfo arg_info; GITypeInfo type_info; - for (auto i = 1; i < n_param_values; i++) { + for (guint i = 1; i < n_param_values; i++) { memcpy(&argument, ¶m_values[i].data[0], sizeof(GIArgument)); g_callable_info_load_arg(info, i - 1, &arg_info); g_arg_info_load_type(&arg_info, &type_info); @@ -76,7 +76,7 @@ void Closure::Execute(GICallableInfo *info, guint signal_id, } } else { /* CallableInfo is not available: use GValueToV8 */ - for (auto i = 1; i < n_param_values; i++) { + for (guint i = 1; i < n_param_values; i++) { bool mustCopy = true; if (signal_query.signal_id) { diff --git a/src/gobject.cc b/src/gobject.cc index 586d041..1476df9 100644 --- a/src/gobject.cc +++ b/src/gobject.cc @@ -447,7 +447,7 @@ NAN_METHOD(SignalEmit) { g_value_set_object(&args[0], gobject); failed = false; - for (auto i = 0; i < signal_query.n_params; i++) { + for (guint i = 0; i < signal_query.n_params; i++) { GValue *gvalue = &args[i + 1]; g_value_init(gvalue, signal_query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE); @@ -470,7 +470,7 @@ NAN_METHOD(SignalEmit) { } } - for (auto i = 0; i < argc; i++) { + for (guint i = 0; i < argc; i++) { g_value_unset(&args[i]); } } From 4d64179ea9579fd009b84e3f3441ee4d92c08627 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Fri, 8 Jul 2022 15:58:17 +0300 Subject: [PATCH 27/35] Fix union__fields.js test on Windows Number.MAX_SAFE_INTEGER is 8 bytes, but vInt is gulong 4 bytes on Windows and 8 bytes on Linux --- .github/workflows/main.yaml | 1 - tests/union__fields.js | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 57a1fde..c46f285 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -41,7 +41,6 @@ jobs: --skip=conversion__array \ --skip=object__non-introspected \ --skip=signal__non-introspected \ - --skip=union__fields \ tests/__run__.js build: diff --git a/tests/union__fields.js b/tests/union__fields.js index 886270b..d8300a4 100644 --- a/tests/union__fields.js +++ b/tests/union__fields.js @@ -15,8 +15,8 @@ const tk = new GLib.TokenValue() * get/set works */ { - tk.vInt = Number.MAX_SAFE_INTEGER - const result = tk.vInt + tk.vInt64 = Number.MAX_SAFE_INTEGER + const result = tk.vInt64 console.log('Result:', result) common.assert(result === Number.MAX_SAFE_INTEGER) } From 0f034179d3f2a3a9ddc5d7195324ddeee921d075 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Fri, 8 Jul 2022 17:04:20 +0300 Subject: [PATCH 28/35] Cleanup --- .github/workflows/main.yaml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index c46f285..4eee31c 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -22,7 +22,13 @@ jobs: msystem: MINGW64 path-type: inherit update: true - install: git mingw-w64-x86_64-gtk3 mingw-w64-x86_64-gobject-introspection mingw-w64-x86_64-cairo mingw-w64-x86_64-gstreamer mingw-w64-x86_64-libsoup + install: | + git \ + mingw-w64-x86_64-gobject-introspection \ + mingw-w64-x86_64-gtk3 \ + mingw-w64-x86_64-cairo \ + mingw-w64-x86_64-gstreamer \ + mingw-w64-x86_64-libsoup - name: Install VS 2017 shell: cmd @@ -37,7 +43,8 @@ jobs: - name: Run tests run: | - npx mocha --skip=callback \ + npx mocha \ + --skip=callback \ --skip=conversion__array \ --skip=object__non-introspected \ --skip=signal__non-introspected \ From b4f1d7b8aa52b7b21b00240fcd7ff5f798311b97 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Fri, 8 Jul 2022 17:10:17 +0300 Subject: [PATCH 29/35] Cleanup #2 --- .github/workflows/main.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 4eee31c..a20e089 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -23,11 +23,11 @@ jobs: path-type: inherit update: true install: | - git \ - mingw-w64-x86_64-gobject-introspection \ - mingw-w64-x86_64-gtk3 \ - mingw-w64-x86_64-cairo \ - mingw-w64-x86_64-gstreamer \ + git + mingw-w64-x86_64-gobject-introspection + mingw-w64-x86_64-gtk3 + mingw-w64-x86_64-cairo + mingw-w64-x86_64-gstreamer mingw-w64-x86_64-libsoup - name: Install VS 2017 From 8e80dc9573efa08b913695ef0cd23284a5f7e6c2 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Fri, 8 Jul 2022 18:24:35 +0300 Subject: [PATCH 30/35] Install gstreamer plugins Fixes 1 test on Windows --- .github/workflows/main.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index a20e089..95d1cfb 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -28,6 +28,8 @@ jobs: mingw-w64-x86_64-gtk3 mingw-w64-x86_64-cairo mingw-w64-x86_64-gstreamer + mingw-w64-x86_64-gst-plugins-good + mingw-w64-x86_64-gst-plugins-bad mingw-w64-x86_64-libsoup - name: Install VS 2017 @@ -46,7 +48,6 @@ jobs: npx mocha \ --skip=callback \ --skip=conversion__array \ - --skip=object__non-introspected \ --skip=signal__non-introspected \ tests/__run__.js From 0d4520403c84c7734bc76a4f1d560580ecd3365a Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Fri, 8 Jul 2022 18:41:06 +0300 Subject: [PATCH 31/35] Partially enable conversion__array.js on Windows See comment in code --- .github/workflows/main.yaml | 1 - tests/conversion__array.js | 9 ++++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 95d1cfb..f92ba92 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -47,7 +47,6 @@ jobs: run: | npx mocha \ --skip=callback \ - --skip=conversion__array \ --skip=signal__non-introspected \ tests/__run__.js diff --git a/tests/conversion__array.js b/tests/conversion__array.js index c7acb4f..5e3c4a0 100644 --- a/tests/conversion__array.js +++ b/tests/conversion__array.js @@ -51,7 +51,14 @@ describe('OUT-array (zero-terminated, of strings)', () => { expect(alternates, [ 'special' ]) }) -describe('OUT-array (zero-terminated, of guint8)', () => { + +// The below test fails on Windows with: +// Error: Failed to dup() in child process (Bad file descriptor) +// ... +// at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) +// at node:internal/main/run_main_module:17:47 + +process.platform !== 'win32' && describe('OUT-array (zero-terminated, of guint8)', () => { const cmd = 'echo foo' const result = glib.spawnCommandLineSync(cmd) From 5835ddd9a4d15517a9f95782d49bcbadc9b32d7b Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Sun, 10 Jul 2022 18:04:04 +0300 Subject: [PATCH 32/35] Fix generator --- src/modules/cairo/generator.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/modules/cairo/generator.js b/src/modules/cairo/generator.js index 7ba4610..a7bd58b 100644 --- a/src/modules/cairo/generator.js +++ b/src/modules/cairo/generator.js @@ -521,8 +521,6 @@ function getReturn(fn, outArguments) { function getAttachMethods(name, functions) { return unindent(` - #define SET_METHOD(tpl, name) Nan::SetPrototypeMethod(tpl, #name, name) - static void AttachMethods(Local tpl) { ${functions.map(fn => (fn.attributes.version ? (() => { @@ -533,12 +531,10 @@ function getAttachMethods(name, functions) { (micro ? 'CAIRO_VERSION_MICRO >= ' + micro : undefined), ].filter(Boolean).join(' && ') + '\n ' })() : '') - + `SET_METHOD(tpl, ${getJSName(fn.name)});` + + `SET_PROTOTYPE_METHOD(tpl, ${getJSName(fn.name)});` + (fn.attributes.version ? '\n #endif' : '') ).join('\n ')} } - - #undef SET_METHOD `) } From 56335f82387011ecb590a8bffe88e35c7cb27d02 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Sun, 10 Jul 2022 18:16:06 +0300 Subject: [PATCH 33/35] Replace malloc/calloc with g_malloc On Windows g_free memory allocated with malloc/calloc crashes --- src/boxed.cc | 6 +++--- src/function.cc | 2 +- src/value.cc | 21 ++++++++------------- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/boxed.cc b/src/boxed.cc index e03b288..795ed1a 100644 --- a/src/boxed.cc +++ b/src/boxed.cc @@ -183,7 +183,7 @@ static void BoxedConstructor(const Nan::FunctionCallbackInfo &info) { boxed = g_boxed_copy (gtype, boxed); } else if ((size = Boxed::GetSize(gi_info)) != 0) { - void *boxedCopy = malloc(size); + void *boxedCopy = g_malloc(size); memcpy(boxedCopy, boxed, size); boxed = boxedCopy; } @@ -223,7 +223,7 @@ static void BoxedConstructor(const Nan::FunctionCallbackInfo &info) { boxed = return_value.v_pointer; } else if ((size = Boxed::GetSize(gi_info)) != 0) { - boxed = calloc(1, size); + boxed = g_malloc0(size); } else { Nan::ThrowError("Boxed allocation failed: no constructor found"); @@ -267,7 +267,7 @@ static void BoxedDestroyed(const Nan::WeakCallbackInfo &info) { } else if (box->size != 0) { // Allocated in ./function.cc @ AllocateArgument - free(box->data); + g_free(box->data); } else if (box->data != NULL) { /* diff --git a/src/function.cc b/src/function.cc index 5063cb6..e9a0a19 100644 --- a/src/function.cc +++ b/src/function.cc @@ -55,7 +55,7 @@ static void* AllocateArgument (GIBaseInfo *arg_info) { GIBaseInfo* base_info = g_type_info_get_interface (&arg_type); size_t size = Boxed::GetSize (base_info); - void* pointer = calloc(1, size); + void* pointer = g_malloc0(size); g_base_info_unref(base_info); return pointer; diff --git a/src/value.cc b/src/value.cc index 9a22d92..03a9dd4 100644 --- a/src/value.cc +++ b/src/value.cc @@ -458,7 +458,7 @@ static void *V8ArrayToCArray(GITypeInfo *type_info, Local value) { GITypeInfo* element_info = g_type_info_get_param_type (type_info, 0); gsize element_size = GetTypeSize(element_info); - void *result = malloc(element_size * (length + (isZeroTerminated ? 1 : 0))); + void *result = g_malloc0(element_size * (length + (isZeroTerminated ? 1 : 0))); for (int i = 0; i < length; i++) { auto value = Nan::Get(array, i).ToLocalChecked(); @@ -474,6 +474,9 @@ static void *V8ArrayToCArray(GITypeInfo *type_info, Local value) { } if (isZeroTerminated) { + // TODO: + // Since g_malloc0 above already zeros the memory + // it's better to assert the last element is zero void* pointer = (void*)((size_t)result + length * element_size); memset(pointer, 0, element_size); } @@ -490,11 +493,14 @@ static void *V8TypedArrayToCArray(GITypeInfo *type_info, Local value) { GITypeInfo* element_info = g_type_info_get_param_type (type_info, 0); gsize element_size = GetTypeSize(element_info); - void *result = malloc(element_size * (length + (isZeroTerminated ? 1 : 0))); + void *result = g_malloc0(element_size * (length + (isZeroTerminated ? 1 : 0))); array->CopyContents(result, length); if (isZeroTerminated) { + // TODO: + // Since g_malloc0 above already zeros the memory + // it's better to assert the last element is zero void* pointer = (void*)((size_t)result + length * element_size); memset(pointer, 0, element_size); } @@ -1339,18 +1345,7 @@ void FreeGIArgumentArray(GITypeInfo *type_info, GIArgument *arg, GITransfer tran switch (array_type) { case GI_ARRAY_TYPE_C: { -#if OS_WINDOWS - bool isZeroTerminated = g_type_info_is_zero_terminated (type_info); - if (isZeroTerminated) { - g_free (data); - } else { - // Freeing something that is non-zero terminated - // crashes on Windows. - // TODO: Investigate what it is - } -#else g_free (data); -#endif break; } case GI_ARRAY_TYPE_ARRAY: From 6f35acd1395a67986287d2f28b72e74f370655ac Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Tue, 12 Jul 2022 21:16:59 +0300 Subject: [PATCH 34/35] Revert double-space --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e5c24b6..bc2ecdf 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Node-Gtk is a [gobject-introspection](https://gi.readthedocs.io/en/latest) libra use any introspected library, such as Gtk+, usable. It is similar in essence to [GJS](https://wiki.gnome.org/action/show/Projects/Gjs) or [PyGObject](https://pygobject.readthedocs.io). Please note this project is currently in a _beta_ state and is being developed. Any contributors willing to help will be welcomed. -Supported Node.js versions: **12**, **14**, **15**, **16** (other versions should work but are untested) +Supported Node.js versions: **12**, **14**, **15**, **16** (other versions should work but are untested) Pre-built binaries available for: **Linux**, **macOS** ### Table of contents From 5363f2779a075d9b090a8917c972a161207eb2b9 Mon Sep 17 00:00:00 2001 From: Dmitry Klionsky Date: Tue, 12 Jul 2022 21:31:01 +0300 Subject: [PATCH 35/35] Heap allocation on non-Linux only --- src/function.cc | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/function.cc b/src/function.cc index e9a0a19..b00b9a0 100644 --- a/src/function.cc +++ b/src/function.cc @@ -324,7 +324,12 @@ Local FunctionCall ( * and for error, if it can throw */ - GIArgument *total_arg_values = new GIArgument[func->n_total_args](); + #ifndef __linux__ + GIArgument *total_arg_values = new GIArgument[func->n_total_args](); + #else + GIArgument total_arg_values[func->n_total_args]; + #endif + GIArgument *callable_arg_values; GError *error_stack = nullptr; @@ -446,7 +451,12 @@ Local FunctionCall ( * Third, make the actual ffi_call */ - void **ffi_args = new void*[func->n_total_args](); + #ifndef __linux__ + void **ffi_args = new void*[func->n_total_args](); + #else + void *ffi_args[func->n_total_args]; + #endif + for (int i = 0; i < func->n_total_args; i++) ffi_args[i] = (void *)&total_arg_values[i]; @@ -455,7 +465,9 @@ Local FunctionCall ( ffi_call (&func->invoker.cif, FFI_FN (func->invoker.native_address), use_return_value ? return_value : &return_value_stack, ffi_args); - delete[] ffi_args; + #ifndef __linux__ + delete[] ffi_args; + #endif /* @@ -529,7 +541,9 @@ Local FunctionCall ( } } - delete[] total_arg_values; + #ifndef __linux__ + delete[] total_arg_values; + #endif return jsReturnValue; }