node-gtk 3.0.0 → 4.0.0

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.
@@ -28,8 +28,12 @@ void FontExtents::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) {
28
28
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
29
29
  tpl->SetClassName(Nan::New("CairoFontExtents").ToLocalChecked());
30
30
 
31
- // Prototype
32
- Local<ObjectTemplate> proto = tpl->PrototypeTemplate();
31
+ // Accessors and indexed handlers must be installed on the instance
32
+ // template, not the prototype: in V8 14 property callbacks expose only
33
+ // HolderV2() (the holder). An accessor on the prototype would hand the
34
+ // callback the prototype object, which has no internal field, and
35
+ // Nan::ObjectWrap::Unwrap would abort. The instance carries the field.
36
+ Local<ObjectTemplate> proto = tpl->InstanceTemplate();
33
37
  SetProtoAccessor(proto, UTF8("ascent"), GetAscent, SetAscent, tpl);
34
38
  SetProtoAccessor(proto, UTF8("descent"), GetDescent, SetDescent, tpl);
35
39
  SetProtoAccessor(proto, UTF8("height"), GetHeight, SetHeight, tpl);
@@ -133,7 +133,7 @@ function getSource(fn) {
133
133
  })() : '' }
134
134
  NAN_METHOD(${getJSName(fn.name)}) {
135
135
  auto self = info.This();
136
- auto ${selfArgument.name} = (${getTypeName(selfArgument.type)}) self->GetAlignedPointerFromInternalField (0);
136
+ auto ${selfArgument.name} = (${getTypeName(selfArgument.type)}) Nan::GetInternalFieldPointer(self, 0);
137
137
  ${inArguments.length > 0 ? `
138
138
  // in-arguments
139
139
  ${inArguments.map(getInArgumentSource).join('\n ')}
@@ -28,8 +28,12 @@ void Glyph::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) {
28
28
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
29
29
  tpl->SetClassName(Nan::New("CairoGlyph").ToLocalChecked());
30
30
 
31
- // Prototype
32
- Local<ObjectTemplate> proto = tpl->PrototypeTemplate();
31
+ // Accessors and indexed handlers must be installed on the instance
32
+ // template, not the prototype: in V8 14 property callbacks expose only
33
+ // HolderV2() (the holder). An accessor on the prototype would hand the
34
+ // callback the prototype object, which has no internal field, and
35
+ // Nan::ObjectWrap::Unwrap would abort. The instance carries the field.
36
+ Local<ObjectTemplate> proto = tpl->InstanceTemplate();
33
37
  SetProtoAccessor(proto, UTF8("length"), GetLength, NULL, tpl);
34
38
  Nan::SetIndexedPropertyHandler(proto, IndexGetter);
35
39
 
@@ -28,8 +28,12 @@ void Path::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) {
28
28
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
29
29
  tpl->SetClassName(Nan::New("CairoPath").ToLocalChecked());
30
30
 
31
- // Prototype
32
- Local<ObjectTemplate> proto = tpl->PrototypeTemplate();
31
+ // Accessors and indexed handlers must be installed on the instance
32
+ // template, not the prototype: in V8 14 property callbacks expose only
33
+ // HolderV2() (the holder). An accessor on the prototype would hand the
34
+ // callback the prototype object, which has no internal field, and
35
+ // Nan::ObjectWrap::Unwrap would abort. The instance carries the field.
36
+ Local<ObjectTemplate> proto = tpl->InstanceTemplate();
33
37
  SetProtoAccessor(proto, UTF8("status"), GetStatus, NULL, tpl);
34
38
 
35
39
  auto ctor = Nan::GetFunction (tpl).ToLocalChecked();
@@ -28,8 +28,12 @@ void RectangleInt::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) {
28
28
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
29
29
  tpl->SetClassName(Nan::New("CairoRectangleInt").ToLocalChecked());
30
30
 
31
- // Prototype
32
- Local<ObjectTemplate> proto = tpl->PrototypeTemplate();
31
+ // Accessors and indexed handlers must be installed on the instance
32
+ // template, not the prototype: in V8 14 property callbacks expose only
33
+ // HolderV2() (the holder). An accessor on the prototype would hand the
34
+ // callback the prototype object, which has no internal field, and
35
+ // Nan::ObjectWrap::Unwrap would abort. The instance carries the field.
36
+ Local<ObjectTemplate> proto = tpl->InstanceTemplate();
33
37
  SetProtoAccessor(proto, UTF8("x"), GetX, SetX, tpl);
34
38
  SetProtoAccessor(proto, UTF8("y"), GetY, SetY, tpl);
35
39
  SetProtoAccessor(proto, UTF8("width"), GetWidth, SetWidth, tpl);
@@ -28,8 +28,12 @@ void Rectangle::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) {
28
28
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
29
29
  tpl->SetClassName(Nan::New("CairoRectangle").ToLocalChecked());
30
30
 
31
- // Prototype
32
- Local<ObjectTemplate> proto = tpl->PrototypeTemplate();
31
+ // Accessors and indexed handlers must be installed on the instance
32
+ // template, not the prototype: in V8 14 property callbacks expose only
33
+ // HolderV2() (the holder). An accessor on the prototype would hand the
34
+ // callback the prototype object, which has no internal field, and
35
+ // Nan::ObjectWrap::Unwrap would abort. The instance carries the field.
36
+ Local<ObjectTemplate> proto = tpl->InstanceTemplate();
33
37
  SetProtoAccessor(proto, UTF8("x"), GetX, SetX, tpl);
34
38
  SetProtoAccessor(proto, UTF8("y"), GetY, SetY, tpl);
35
39
  SetProtoAccessor(proto, UTF8("width"), GetWidth, SetWidth, tpl);
@@ -28,8 +28,12 @@ void TextCluster::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) {
28
28
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
29
29
  tpl->SetClassName(Nan::New("CairoTextCluster").ToLocalChecked());
30
30
 
31
- // Prototype
32
- Local<ObjectTemplate> proto = tpl->PrototypeTemplate();
31
+ // Accessors and indexed handlers must be installed on the instance
32
+ // template, not the prototype: in V8 14 property callbacks expose only
33
+ // HolderV2() (the holder). An accessor on the prototype would hand the
34
+ // callback the prototype object, which has no internal field, and
35
+ // Nan::ObjectWrap::Unwrap would abort. The instance carries the field.
36
+ Local<ObjectTemplate> proto = tpl->InstanceTemplate();
33
37
  SetProtoAccessor(proto, UTF8("length"), GetLength, NULL, tpl);
34
38
  SetProtoAccessor(proto, UTF8("flags"), GetFlags, NULL, tpl);
35
39
  Nan::SetIndexedPropertyHandler(proto, IndexGetter);
@@ -28,8 +28,12 @@ void TextExtents::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) {
28
28
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
29
29
  tpl->SetClassName(Nan::New("CairoTextExtents").ToLocalChecked());
30
30
 
31
- // Prototype
32
- Local<ObjectTemplate> proto = tpl->PrototypeTemplate();
31
+ // Accessors and indexed handlers must be installed on the instance
32
+ // template, not the prototype: in V8 14 property callbacks expose only
33
+ // HolderV2() (the holder). An accessor on the prototype would hand the
34
+ // callback the prototype object, which has no internal field, and
35
+ // Nan::ObjectWrap::Unwrap would abort. The instance carries the field.
36
+ Local<ObjectTemplate> proto = tpl->InstanceTemplate();
33
37
  SetProtoAccessor(proto, UTF8("xBearing"), GetXBearing, SetXBearing, tpl);
34
38
  SetProtoAccessor(proto, UTF8("yBearing"), GetYBearing, SetYBearing, tpl);
35
39
  SetProtoAccessor(proto, UTF8("width"), GetWidth, SetWidth, tpl);
@@ -24,7 +24,7 @@ namespace System {
24
24
  static gsize GetObjectSize (Local<Object> object) {
25
25
  // Boxed
26
26
  if (object->InternalFieldCount() == 2) {
27
- auto box = static_cast<Boxed*>(object->GetAlignedPointerFromInternalField(1));
27
+ auto box = static_cast<Boxed*>(Nan::GetInternalFieldPointer(object, 1));
28
28
  return GetComplexTypeSize(box->info);
29
29
  }
30
30
  // GObject
@@ -38,7 +38,7 @@ static gsize GetObjectSize (Local<Object> object) {
38
38
 
39
39
  NAN_METHOD(AddressOf) {
40
40
  Local<Object> object = info[0].As<Object>();
41
- void *pointer = object->GetAlignedPointerFromInternalField (0);
41
+ void *pointer = Nan::GetInternalFieldPointer(object, 0);
42
42
  RETURN(Nan::New<Number>((uint64_t)pointer));
43
43
  }
44
44
 
@@ -64,7 +64,7 @@ NAN_METHOD(ConvertGValue) {
64
64
  RETURN(Nan::Undefined());
65
65
  return;
66
66
  }
67
- void *ptr = obj->GetAlignedPointerFromInternalField (0);
67
+ void *ptr = Nan::GetInternalFieldPointer(obj, 0);
68
68
  ResourceOwnership ownership = kCopy;
69
69
  RETURN(GValueToV8(reinterpret_cast<GValue *>(ptr), ownership));
70
70
  }
@@ -79,7 +79,7 @@ NAN_METHOD(GetMemoryContent) {
79
79
  }
80
80
  else {
81
81
  auto object = info[0].As<Object>();
82
- address = (uint8_t *) object->GetAlignedPointerFromInternalField (0);
82
+ address = (uint8_t *) Nan::GetInternalFieldPointer(object, 0);
83
83
  size = GetObjectSize(object);
84
84
  }
85
85
 
package/src/util.h CHANGED
@@ -48,14 +48,14 @@ inline void SetProtoAccessor(
48
48
  Nan::SetterCallback setter,
49
49
  v8::Local<v8::FunctionTemplate> ctor
50
50
  ) {
51
+ // Trailing settings/attribute args are omitted so Nan supplies the right
52
+ // AccessControl default per V8 version (v8::DEFAULT was removed in V8 14).
51
53
  Nan::SetAccessor(
52
54
  tpl,
53
55
  name,
54
56
  getter,
55
57
  setter,
56
- v8::Local<v8::Value>(),
57
- v8::DEFAULT,
58
- v8::None);
58
+ v8::Local<v8::Value>());
59
59
  }
60
60
 
61
61
  namespace Util
package/src/value.cc CHANGED
@@ -6,6 +6,7 @@
6
6
 
7
7
  #include "error.h"
8
8
  #include "boxed.h"
9
+ #include "fundamental.h"
9
10
  #include "function.h"
10
11
  #include "gi.h"
11
12
  #include "gobject.h"
@@ -51,7 +52,7 @@ static guint64 V8ToUint64 (Local<Value> value) {
51
52
  }
52
53
 
53
54
 
54
- Local<Value> GIArgumentToV8(GITypeInfo *type_info, GIArgument *arg, long length, ResourceOwnership ownership) {
55
+ Local<Value> GIArgumentToV8(GITypeInfo *type_info, GIArgument *arg, long length, ResourceOwnership ownership, bool nullable) {
55
56
  GITypeTag type_tag = g_type_info_get_tag (type_info);
56
57
 
57
58
  switch (type_tag) {
@@ -120,6 +121,11 @@ Local<Value> GIArgumentToV8(GITypeInfo *type_info, GIArgument *arg, long length,
120
121
  case GI_TYPE_TAG_UTF8: {
121
122
  if (arg->v_string)
122
123
  return New<String>(arg->v_string).ToLocalChecked();
124
+ else if (nullable)
125
+ // A nullable string (e.g. g_data_input_stream_read_line_utf8_finish
126
+ // at EOF) returns NULL: surface it as `null` so it is
127
+ // distinguishable from a legitimately empty string. (#467)
128
+ return Nan::Null();
123
129
  else
124
130
  return Nan::EmptyString();
125
131
  }
@@ -136,7 +142,9 @@ Local<Value> GIArgumentToV8(GITypeInfo *type_info, GIArgument *arg, long length,
136
142
  * of a GObject, instead this represent the object type (eg class). A GObject
137
143
  * has methods, fields, properties, signals, interfaces, constants and virtual functions. */
138
144
  case GI_INFO_TYPE_OBJECT:
139
- if (G_IS_PARAM_SPEC(arg->v_pointer))
145
+ if (IsFundamentalObjectInfo(interface_info))
146
+ value = WrapperFromFundamental(interface_info, arg->v_pointer, ownership);
147
+ else if (G_IS_PARAM_SPEC(arg->v_pointer))
140
148
  value = ParamSpec::FromGParamSpec((GParamSpec *)arg->v_pointer);
141
149
  else
142
150
  value = WrapperFromGObject((GObject *)arg->v_pointer);
@@ -144,7 +152,12 @@ Local<Value> GIArgumentToV8(GITypeInfo *type_info, GIArgument *arg, long length,
144
152
  case GI_INFO_TYPE_BOXED:
145
153
  case GI_INFO_TYPE_STRUCT:
146
154
  case GI_INFO_TYPE_UNION:
147
- value = WrapperFromBoxed (interface_info, arg->v_pointer, ownership);
155
+ // GVariant is a struct-classed fundamental: refcount it via the
156
+ // fundamental wrapper rather than g_boxed_copy (#465).
157
+ if (IsVariantInfo (interface_info))
158
+ value = WrapperFromVariant (arg->v_pointer, ownership);
159
+ else
160
+ value = WrapperFromBoxed (interface_info, arg->v_pointer, ownership);
148
161
  break;
149
162
  case GI_INFO_TYPE_ENUM:
150
163
  value = New<Number>(arg->v_int);
@@ -166,7 +179,7 @@ Local<Value> GIArgumentToV8(GITypeInfo *type_info, GIArgument *arg, long length,
166
179
  }
167
180
 
168
181
  case GI_TYPE_TAG_ARRAY:
169
- return ArrayToV8(type_info, arg->v_pointer, length);
182
+ return ArrayToV8(type_info, arg->v_pointer, length, nullable);
170
183
 
171
184
  case GI_TYPE_TAG_GLIST:
172
185
  return GListToV8(type_info, (GList *)arg->v_pointer);
@@ -323,7 +336,13 @@ static bool IsZeroMemory (const void *ptr, gsize size) {
323
336
  return true;
324
337
  }
325
338
 
326
- Local<Value> ArrayToV8 (GITypeInfo *type_info, void* data, long length) {
339
+ Local<Value> ArrayToV8 (GITypeInfo *type_info, void* data, long length, bool nullable) {
340
+
341
+ // A nullable array return (e.g. g_data_input_stream_read_line_finish at
342
+ // EOF) yields a NULL pointer: surface it as `null` so it is
343
+ // distinguishable from a legitimately empty array. (#467)
344
+ if (data == nullptr && nullable)
345
+ return Nan::Null();
327
346
 
328
347
  auto array = New<Array>();
329
348
 
@@ -833,6 +852,15 @@ bool V8ToGIArgumentInterface(GIBaseInfo *gi_info, GIArgument *arg, Local<Value>
833
852
  arg->v_pointer = ParamSpec::FromWrapper(value);
834
853
  break;
835
854
  }
855
+
856
+ if (IsFundamentalObjectInfo(gi_info)) {
857
+ // A fundamental (non-GObject) instance such as GskRenderNode: take
858
+ // the raw wrapped pointer. GObjectFromWrapper would G_OBJECT()-cast
859
+ // it — silently on Linux (cast checks compiled out) but a fatal
860
+ // `invalid cast ... to GObject` under G_DEBUG on Windows (#468).
861
+ arg->v_pointer = PointerFromWrapper(value);
862
+ break;
863
+ }
836
864
  // fallthrough
837
865
  }
838
866
  case GI_INFO_TYPE_INTERFACE:
@@ -1726,7 +1754,7 @@ bool CanConvertV8ToGValue(GValue *gvalue, Local<Value> value) {
1726
1754
  } else if (G_VALUE_HOLDS_POINTER (gvalue)) {
1727
1755
  return false;
1728
1756
  } else if (G_VALUE_HOLDS_VARIANT (gvalue)) {
1729
- return false;
1757
+ return value->IsNullOrUndefined() || ValueIsInstanceOfGType(value, G_TYPE_VARIANT);
1730
1758
  }
1731
1759
 
1732
1760
  ERROR("Unhandled GValue type: %s (please report this)",
@@ -1819,7 +1847,13 @@ bool V8ToGValue(GValue *gvalue, Local<Value> value, ResourceOwnership ownership)
1819
1847
  } else if (G_VALUE_HOLDS_POINTER (gvalue)) {
1820
1848
  ERROR("Unsupported type: pointer");
1821
1849
  } else if (G_VALUE_HOLDS_VARIANT (gvalue)) {
1822
- ERROR("Unsupported type: variant");
1850
+ // GVariant is nullable. g_value_set_variant refs a non-NULL variant
1851
+ // (and sinks a floating one), so the GValue holds its own reference
1852
+ // independent of the JS wrapper (#465).
1853
+ g_value_set_variant (gvalue,
1854
+ value->IsNullOrUndefined()
1855
+ ? NULL
1856
+ : (GVariant *) PointerFromWrapper (value));
1823
1857
  } else {
1824
1858
  ERROR("Unhandled GValue type: %s (please report this)",
1825
1859
  g_type_name(G_VALUE_TYPE(gvalue)));
@@ -1896,7 +1930,9 @@ Local<Value> GValueToV8(const GValue *gvalue, ResourceOwnership ownership) {
1896
1930
  } else if (G_VALUE_HOLDS_POINTER (gvalue)) {
1897
1931
  ERROR("Unsuported type: pointer");
1898
1932
  } else if (G_VALUE_HOLDS_VARIANT (gvalue)) {
1899
- ERROR("Unsuported type: variant");
1933
+ // GVariant is a struct-classed fundamental; the fundamental wrapper
1934
+ // takes its own reference according to `ownership` (#465).
1935
+ return WrapperFromVariant (g_value_get_variant (gvalue), ownership);
1900
1936
  } else {
1901
1937
  // Don't abort the whole process on a GValue type we can't convert
1902
1938
  // (e.g. GStreamer's GstValueArray / GstValueList, #389). Warn and
package/src/value.h CHANGED
@@ -20,9 +20,9 @@ enum ResourceOwnership {
20
20
  Local<Value> GListToV8 (GITypeInfo *info, GList *glist);
21
21
  Local<Value> GSListToV8 (GITypeInfo *info, GSList *glist);
22
22
  Local<Value> GHashToV8 (GITypeInfo *info, GHashTable *hash);
23
- Local<Value> ArrayToV8 (GITypeInfo *info, gpointer data, long length = -1);
23
+ Local<Value> ArrayToV8 (GITypeInfo *info, gpointer data, long length = -1, bool nullable = false);
24
24
  Local<Value> GErrorToV8 (GITypeInfo *type_info, GError *err, ResourceOwnership ownership = kNone);
25
- Local<Value> GIArgumentToV8 (GITypeInfo *type_info, GIArgument *argument, long length = -1, ResourceOwnership ownership = kNone);
25
+ Local<Value> GIArgumentToV8 (GITypeInfo *type_info, GIArgument *argument, long length = -1, ResourceOwnership ownership = kNone, bool nullable = false);
26
26
  long GIArgumentToLength(GITypeInfo *type_info, GIArgument *arg, bool is_pointer);
27
27
 
28
28
  bool V8ToGIArgumentInterface (GIBaseInfo *gi_info, GIArgument *argument, Local<Value> value);