diff --git a/lib/bootstrap.js b/lib/bootstrap.js index b5cb5189..27145fe1 100644 --- a/lib/bootstrap.js +++ b/lib/bootstrap.js @@ -220,7 +220,7 @@ function makeEnum(info) { for (let i = 0; i < nValues; i++) { const valueInfo = GI.enum_info_get_value(info, i); const valueName = getName(valueInfo).toUpperCase() - const value = GI.value_info_get_value(valueInfo) + const value = Number(GI.value_info_get_value(valueInfo)) Object.defineProperty(object, valueName, { configurable: true, enumerable: true, diff --git a/lib/inspect.js b/lib/inspect.js index 2fd0b7c6..818eb03e 100644 --- a/lib/inspect.js +++ b/lib/inspect.js @@ -203,7 +203,7 @@ function ConstantInfo(info, parent) { function ValueInfo (info, parent) { BaseInfo.call(this, info) - this.value = GI.value_info_get_value(info) + this.value = Number(GI.value_info_get_value(info)) } function PropInfo(info, parent) { diff --git a/src/value.cc b/src/value.cc index 826bb052..5afc5d3f 100644 --- a/src/value.cc +++ b/src/value.cc @@ -20,6 +20,7 @@ using v8::Array; using v8::TypedArray; using v8::Integer; +using v8::BigInt; using v8::Local; using v8::Number; using v8::Object; @@ -35,6 +36,22 @@ static void HashPointerToGIArgument (GIArgument *arg, GITypeInfo *type_info); static bool IsUint8Array (GITypeInfo *type_info); +static int64_t V8ToInt64 (Local value) { + if (value->IsBigInt()) + return value.As()->Int64Value(); + return Nan::To(value).ToChecked(); +} + +static int64_t V8ToUint64Strict (Local value) { + return Local::Cast(value)->Uint64Value(); +} + +static int64_t V8ToInt32 (Local value) { + if (value->IsBigInt()) + return value.As()->Int64Value(); + return Nan::To(value).ToChecked(); +} + Local GIArgumentToV8(GITypeInfo *type_info, GIArgument *arg, long length, bool mustCopy) { GITypeTag type_tag = g_type_info_get_tag (type_info); @@ -64,9 +81,9 @@ Local GIArgumentToV8(GITypeInfo *type_info, GIArgument *arg, long length, /* For 64-bit integer types, use a float. When JS and V8 adopt * bigger sized integer types, start using those instead. */ case GI_TYPE_TAG_INT64: - return New (arg->v_int64); + return v8::BigInt::New(Isolate::GetCurrent(), arg->v_int64); case GI_TYPE_TAG_UINT64: - return New (arg->v_uint64); + return v8::BigInt::NewFromUnsigned(Isolate::GetCurrent(), arg->v_uint64); case GI_TYPE_TAG_GTYPE: /* c++: gulong */ return v8::BigInt::NewFromUnsigned(Isolate::GetCurrent(), arg->v_ulong); @@ -688,28 +705,28 @@ bool V8ToGIArgument(GITypeInfo *type_info, GIArgument *arg, Local value, arg->v_boolean = Nan::To (value).ToChecked(); break; case GI_TYPE_TAG_INT8: - arg->v_int8 = Nan::To (value).ToChecked(); + arg->v_int8 = V8ToInt32(value); break; case GI_TYPE_TAG_INT16: - arg->v_int16 = Nan::To (value).ToChecked(); + arg->v_int16 = V8ToInt32(value); break; case GI_TYPE_TAG_INT32: - arg->v_int = Nan::To (value).ToChecked(); + arg->v_int = V8ToInt32(value); break; case GI_TYPE_TAG_INT64: - arg->v_int64 = Nan::To (value).ToChecked(); + arg->v_int64 = V8ToInt64(value); break; case GI_TYPE_TAG_UINT8: - arg->v_uint8 = Nan::To (value).ToChecked(); + arg->v_uint8 = V8ToInt32(value); break; case GI_TYPE_TAG_UINT16: - arg->v_uint16 = Nan::To (value).ToChecked(); + arg->v_uint16 = V8ToInt32(value); break; case GI_TYPE_TAG_UINT32: - arg->v_uint = Nan::To (value).ToChecked(); + arg->v_uint = V8ToInt32(value); break; case GI_TYPE_TAG_UINT64: - arg->v_uint64 = Nan::To (value).ToChecked(); + arg->v_uint64 = V8ToInt64(value); break; case GI_TYPE_TAG_FLOAT: arg->v_float = Nan::To (value).ToChecked(); @@ -718,10 +735,7 @@ bool V8ToGIArgument(GITypeInfo *type_info, GIArgument *arg, Local value, arg->v_double = Nan::To (value).ToChecked(); break; case GI_TYPE_TAG_GTYPE: - if (value->IsBigInt()) - arg->v_ulong = value.As()->Uint64Value(); - else - arg->v_ulong = Nan::To (value).ToChecked(); + arg->v_ulong = V8ToUint64Strict(value); break; case GI_TYPE_TAG_UTF8: @@ -826,28 +840,28 @@ bool V8ToOutGIArgument(GITypeInfo *type_info, GIArgument *arg, Local valu *(gboolean*)arg->v_pointer = Nan::To (value).ToChecked(); break; case GI_TYPE_TAG_INT8: - *(gint8*)arg->v_pointer = Nan::To (value).ToChecked(); + *(gint8*)arg->v_pointer = V8ToInt32(value); break; case GI_TYPE_TAG_INT16: - *(gint16*)arg->v_pointer = Nan::To (value).ToChecked(); + *(gint16*)arg->v_pointer = V8ToInt32(value); break; case GI_TYPE_TAG_INT32: - *(gint*)arg->v_pointer = Nan::To (value).ToChecked(); + *(gint*)arg->v_pointer = V8ToInt32(value); break; case GI_TYPE_TAG_INT64: - *(gint64*)arg->v_pointer = Nan::To (value).ToChecked(); + *(gint64*)arg->v_pointer = V8ToInt64(value); break; case GI_TYPE_TAG_UINT8: - *(guint8*)arg->v_pointer = Nan::To (value).ToChecked(); + *(guint8*)arg->v_pointer = V8ToInt32(value); break; case GI_TYPE_TAG_UINT16: - *(guint16*)arg->v_pointer = Nan::To (value).ToChecked(); + *(guint16*)arg->v_pointer = V8ToInt32(value); break; case GI_TYPE_TAG_UINT32: - *(guint*)arg->v_pointer = Nan::To (value).ToChecked(); + *(guint*)arg->v_pointer = V8ToInt32(value); break; case GI_TYPE_TAG_UINT64: - *(guint64*)arg->v_pointer = Nan::To (value).ToChecked(); + *(guint64*)arg->v_pointer = V8ToInt64(value); break; case GI_TYPE_TAG_FLOAT: *(gfloat*)arg->v_pointer = Nan::To (value).ToChecked(); @@ -856,10 +870,7 @@ bool V8ToOutGIArgument(GITypeInfo *type_info, GIArgument *arg, Local valu *(gdouble*)arg->v_pointer = Nan::To (value).ToChecked(); break; case GI_TYPE_TAG_GTYPE: - if (value->IsBigInt()) - *(gulong*)arg->v_pointer = value.As()->Uint64Value(); - else - *(gulong*)arg->v_pointer = Nan::To (value).ToChecked(); + *(gulong*)arg->v_pointer = V8ToUint64Strict(value); break; case GI_TYPE_TAG_UTF8: @@ -918,12 +929,14 @@ bool CanConvertV8ToGIArgument(GITypeInfo *type_info, Local value, bool ma case GI_TYPE_TAG_UINT16: case GI_TYPE_TAG_UINT32: case GI_TYPE_TAG_UINT64: + return value->IsNumber () || value->IsBigInt (); + case GI_TYPE_TAG_FLOAT: case GI_TYPE_TAG_DOUBLE: return value->IsNumber (); case GI_TYPE_TAG_GTYPE: - return value->IsNumber () || value->IsBigInt (); + return value->IsBigInt (); case GI_TYPE_TAG_UTF8: return true; @@ -1300,27 +1313,27 @@ bool CanConvertV8ToGValue(GValue *gvalue, Local value) { if (G_VALUE_HOLDS_BOOLEAN (gvalue)) { return value->IsBoolean() || value->IsNumber(); } else if (G_VALUE_HOLDS_CHAR (gvalue)) { - return value->IsNumber(); + return value->IsNumber() || value->IsBigInt(); } else if (G_VALUE_HOLDS_UCHAR (gvalue)) { - return value->IsNumber(); + return value->IsNumber() || value->IsBigInt(); } else if (G_VALUE_HOLDS_INT (gvalue)) { - return value->IsNumber(); + return value->IsNumber() || value->IsBigInt(); } else if (G_VALUE_HOLDS_UINT (gvalue)) { - return value->IsNumber(); - } else if (G_VALUE_HOLDS_LONG (gvalue)) { - return value->IsNumber(); - } else if (G_VALUE_HOLDS_ULONG (gvalue)) { - return value->IsNumber(); + return value->IsNumber() || value->IsBigInt(); } else if (G_VALUE_HOLDS_INT64 (gvalue)) { - return value->IsNumber(); + return value->IsNumber() || value->IsBigInt(); } else if (G_VALUE_HOLDS_UINT64 (gvalue)) { - return value->IsNumber(); + return value->IsNumber() || value->IsBigInt(); + } else if (G_VALUE_HOLDS_LONG (gvalue)) { + return value->IsNumber() || value->IsBigInt(); + } else if (G_VALUE_HOLDS_ULONG (gvalue)) { + return value->IsNumber() || value->IsBigInt(); } else if (G_VALUE_HOLDS_FLOAT (gvalue)) { return value->IsNumber(); } else if (G_VALUE_HOLDS_DOUBLE (gvalue)) { return value->IsNumber(); } else if (G_VALUE_HOLDS_GTYPE (gvalue)) { - return value->IsNumber(); + return value->IsBigInt(); } else if (G_VALUE_HOLDS_ENUM (gvalue)) { return value->IsNumber(); } else if (G_VALUE_HOLDS_FLAGS (gvalue)) { @@ -1364,27 +1377,27 @@ bool V8ToGValue(GValue *gvalue, Local value, bool mustCopy) { if (G_VALUE_HOLDS_BOOLEAN (gvalue)) { g_value_set_boolean (gvalue, Nan::To (value).ToChecked()); } else if (G_VALUE_HOLDS_CHAR (gvalue)) { - g_value_set_schar (gvalue, Nan::To (value).ToChecked()); + g_value_set_schar (gvalue, V8ToInt32(value)); } else if (G_VALUE_HOLDS_UCHAR (gvalue)) { - g_value_set_uchar (gvalue, Nan::To (value).ToChecked()); + g_value_set_uchar (gvalue, V8ToInt32(value)); } else if (G_VALUE_HOLDS_INT (gvalue)) { - g_value_set_int (gvalue, Nan::To (value).ToChecked()); + g_value_set_int (gvalue, V8ToInt32(value)); } else if (G_VALUE_HOLDS_UINT (gvalue)) { - g_value_set_uint (gvalue, Nan::To (value).ToChecked()); + g_value_set_uint (gvalue, V8ToInt32(value)); } else if (G_VALUE_HOLDS_LONG (gvalue)) { - g_value_set_long (gvalue, Nan::To (value).ToChecked()); + g_value_set_long (gvalue, V8ToInt64(value)); } else if (G_VALUE_HOLDS_ULONG (gvalue)) { - g_value_set_ulong (gvalue, Nan::To (value).ToChecked()); + g_value_set_ulong (gvalue, V8ToInt64(value)); } else if (G_VALUE_HOLDS_INT64 (gvalue)) { - g_value_set_int64 (gvalue, Nan::To (value).ToChecked()); + g_value_set_int64 (gvalue, V8ToInt64(value)); } else if (G_VALUE_HOLDS_UINT64 (gvalue)) { - g_value_set_uint64 (gvalue, Nan::To (value).ToChecked()); + g_value_set_uint64 (gvalue, V8ToInt64(value)); } else if (G_VALUE_HOLDS_FLOAT (gvalue)) { g_value_set_float (gvalue, Nan::To (value).ToChecked()); } else if (G_VALUE_HOLDS_DOUBLE (gvalue)) { g_value_set_double (gvalue, Nan::To (value).ToChecked()); } else if (G_VALUE_HOLDS_GTYPE (gvalue)) { - g_value_set_gtype (gvalue, Nan::To (value).ToChecked()); + g_value_set_gtype (gvalue, (GType) V8ToUint64Strict(value)); } else if (G_VALUE_HOLDS_ENUM (gvalue)) { g_value_set_enum (gvalue, Nan::To (value).ToChecked()); } else if (G_VALUE_HOLDS_FLAGS (gvalue)) { @@ -1440,19 +1453,19 @@ Local GValueToV8(const GValue *gvalue, bool mustCopy) { } else if (G_VALUE_HOLDS_UINT (gvalue)) { return New(g_value_get_uint (gvalue)); } else if (G_VALUE_HOLDS_LONG (gvalue)) { - return New(g_value_get_long (gvalue)); + return v8::BigInt::New(Isolate::GetCurrent(), g_value_get_long (gvalue)); } else if (G_VALUE_HOLDS_ULONG (gvalue)) { - return New(g_value_get_ulong (gvalue)); + return v8::BigInt::NewFromUnsigned(Isolate::GetCurrent(), g_value_get_ulong (gvalue)); } else if (G_VALUE_HOLDS_INT64 (gvalue)) { - return New(g_value_get_int64 (gvalue)); + return v8::BigInt::New(Isolate::GetCurrent(), g_value_get_int64 (gvalue)); } else if (G_VALUE_HOLDS_UINT64 (gvalue)) { - return New(g_value_get_uint64 (gvalue)); + return v8::BigInt::NewFromUnsigned(Isolate::GetCurrent(), g_value_get_uint64 (gvalue)); } else if (G_VALUE_HOLDS_FLOAT (gvalue)) { return New(g_value_get_float (gvalue)); } else if (G_VALUE_HOLDS_DOUBLE (gvalue)) { return New(g_value_get_double (gvalue)); } else if (G_VALUE_HOLDS_GTYPE (gvalue)) { - return New(g_value_get_gtype (gvalue)); + return v8::BigInt::NewFromUnsigned(Isolate::GetCurrent(), g_value_get_gtype(gvalue)); } else if (G_VALUE_HOLDS_ENUM (gvalue)) { return New(g_value_get_enum (gvalue)); } else if (G_VALUE_HOLDS_FLAGS (gvalue)) { diff --git a/tests/object__non-introspected.js b/tests/object__non-introspected.js index 8e50f6c2..8cb6f6c6 100644 --- a/tests/object__non-introspected.js +++ b/tests/object__non-introspected.js @@ -38,7 +38,7 @@ describe('create non-introspected objected', () => { it('has non-introspected properties', () => { expect(src.pattern, 0) - expect(src.timestampOffset, 0) + expect(src.timestampOffset, BigInt(0)) expect(src.isLive, false) }) diff --git a/tests/union__fields.js b/tests/union__fields.js index 886270b4..e74487aa 100644 --- a/tests/union__fields.js +++ b/tests/union__fields.js @@ -18,7 +18,7 @@ const tk = new GLib.TokenValue() tk.vInt = Number.MAX_SAFE_INTEGER const result = tk.vInt console.log('Result:', result) - common.assert(result === Number.MAX_SAFE_INTEGER) + common.assert(result === BigInt(Number.MAX_SAFE_INTEGER)) } /*