[gjs/wip/ptomato/mozjs31prep] WIP - Replace JS_ValueToInt32 - buggy
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/wip/ptomato/mozjs31prep] WIP - Replace JS_ValueToInt32 - buggy
- Date: Sat, 1 Oct 2016 01:25:24 +0000 (UTC)
commit 17df51ebb9696d1c10c9839dd4ceb96332c92907
Author: Philip Chimento <philip endlessm com>
Date: Fri Sep 30 18:19:37 2016 -0700
WIP - Replace JS_ValueToInt32 - buggy
This changes rounding behaviour when converting JS number values to ints
during JS->GI marshalling!
A test is failing that expected failure while marshalling an array to an
int, whereas now the operation succeeds with 0. The offending change
seems to be arg.cpp:1213. However, this behaviour would seem to be normal
in JS:
gjs> let a = Int32Array(1);
gjs> a[0] = ['this', 'is', 'fine'];
this,is,fine
gjs> a[0]
0
NEWS | 8 +++++++
gi/arg.cpp | 10 ++++----
gi/value.cpp | 10 ++++----
gjs/context.cpp | 10 +++-----
gjs/jsapi-util.cpp | 40 +++++---------------------------------
gjs/jsapi-util.h | 3 +-
installed-tests/js/testGDBus.js | 2 +-
modules/cairo-region.cpp | 8 +++---
8 files changed, 35 insertions(+), 56 deletions(-)
---
diff --git a/NEWS b/NEWS
index 330db9d..6f5d2c1 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,11 @@
+NEXT
+----
+- The rounding of signed integers when marshalling JavaScript number values into
+ GObject introspection integer values has changed to match the ECMA standard: instead of floor(x + 0.5), we
now round as signum(x) * floor(abs(x)).
+ Basically this means 10.5 will round to 10, not 11 as it would have in
+ previous GJS versions.
+ http://www.ecma-international.org/ecma-262/7.0/index.html#sec-toint32
+
Version 1.46.0
--------------
diff --git a/gi/arg.cpp b/gi/arg.cpp
index b7ea873..455b6a4 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -1173,7 +1173,7 @@ gjs_value_to_g_argument(JSContext *context,
case GI_TYPE_TAG_INT8: {
gint32 i;
- if (!JS_ValueToInt32(context, value, &i))
+ if (!JS::ToInt32(context, value, &i))
wrong = true;
if (i > G_MAXINT8 || i < G_MININT8)
out_of_range = true;
@@ -1191,7 +1191,7 @@ gjs_value_to_g_argument(JSContext *context,
}
case GI_TYPE_TAG_INT16: {
gint32 i;
- if (!JS_ValueToInt32(context, value, &i))
+ if (!JS::ToInt32(context, value, &i))
wrong = true;
if (i > G_MAXINT16 || i < G_MININT16)
out_of_range = true;
@@ -1210,7 +1210,7 @@ gjs_value_to_g_argument(JSContext *context,
}
case GI_TYPE_TAG_INT32:
- if (!JS_ValueToInt32(context, value, &arg->v_int))
+ if (!JS::ToInt32(context, value, &arg->v_int))
wrong = true;
break;
@@ -1589,7 +1589,7 @@ gjs_value_to_g_argument(JSContext *context,
if (interface_type == GI_INFO_TYPE_ENUM) {
gint64 value_int64;
- if (!gjs_value_to_int64 (context, value, &value_int64))
+ if (!JS::ToInt64(context, value, &value_int64))
wrong = true;
else if (!_gjs_enum_value_is_valid(context, (GIEnumInfo *)interface_info, value_int64))
wrong = true;
@@ -1599,7 +1599,7 @@ gjs_value_to_g_argument(JSContext *context,
} else if (interface_type == GI_INFO_TYPE_FLAGS) {
gint64 value_int64;
- if (!gjs_value_to_int64 (context, value, &value_int64))
+ if (!JS::ToInt64(context, value, &value_int64))
wrong = true;
else if (!_gjs_flags_value_is_valid(context, gtype, value_int64))
wrong = true;
diff --git a/gi/value.cpp b/gi/value.cpp
index d5c2282..3af97c0 100644
--- a/gi/value.cpp
+++ b/gi/value.cpp
@@ -414,7 +414,7 @@ gjs_value_to_g_value_internal(JSContext *context,
}
} else if (gtype == G_TYPE_CHAR) {
gint32 i;
- if (JS_ValueToInt32(context, value, &i) && i >= SCHAR_MIN && i <= SCHAR_MAX) {
+ if (JS::ToInt32(context, value, &i) && i >= SCHAR_MIN && i <= SCHAR_MAX) {
g_value_set_schar(gvalue, (signed char)i);
} else {
gjs_throw(context,
@@ -434,7 +434,7 @@ gjs_value_to_g_value_internal(JSContext *context,
}
} else if (gtype == G_TYPE_INT) {
gint32 i;
- if (JS_ValueToInt32(context, value, &i)) {
+ if (JS::ToInt32(context, value, &i)) {
g_value_set_int(gvalue, i);
} else {
gjs_throw(context,
@@ -629,7 +629,7 @@ gjs_value_to_g_value_internal(JSContext *context,
} else if (g_type_is_a(gtype, G_TYPE_ENUM)) {
gint64 value_int64;
- if (gjs_value_to_int64 (context, value, &value_int64)) {
+ if (JS::ToInt64(context, value, &value_int64)) {
GEnumValue *v;
gpointer gtype_class = g_type_class_ref(gtype);
@@ -655,7 +655,7 @@ gjs_value_to_g_value_internal(JSContext *context,
} else if (g_type_is_a(gtype, G_TYPE_FLAGS)) {
gint64 value_int64;
- if (gjs_value_to_int64 (context, value, &value_int64)) {
+ if (JS::ToInt64(context, value, &value_int64)) {
if (!_gjs_flags_value_is_valid(context, gtype, value_int64))
return false;
@@ -717,7 +717,7 @@ gjs_value_to_g_value_internal(JSContext *context,
* e.g. ClutterUnit.
*/
gint32 i;
- if (JS_ValueToInt32(context, value, &i)) {
+ if (JS::ToInt32(context, value, &i)) {
GValue int_value = { 0, };
g_value_init(&int_value, G_TYPE_INT);
g_value_set_int(&int_value, i);
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 1954d86..68837aa 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -652,12 +652,10 @@ gjs_context_eval(GjsContext *js_context,
if (exit_status_p) {
if (retval.isInt32()) {
- int code;
- if (JS_ValueToInt32(js_context->context, retval, &code)) {
- gjs_debug(GJS_DEBUG_CONTEXT,
- "Script returned integer code %d", code);
- *exit_status_p = code;
- }
+ int code = retval.toInt32();
+ gjs_debug(GJS_DEBUG_CONTEXT,
+ "Script returned integer code %d", code);
+ *exit_status_p = code;
} else {
/* Assume success if no integer was returned */
*exit_status_p = 0;
diff --git a/gjs/jsapi-util.cpp b/gjs/jsapi-util.cpp
index 68b1e7c..06e48a9 100644
--- a/gjs/jsapi-util.cpp
+++ b/gjs/jsapi-util.cpp
@@ -823,46 +823,18 @@ gjs_get_type_name(JS::Value value)
* gjs_value_to_int64:
* @context: the Javascript context object
* @val: Javascript value to convert
- * @gint64: location to store the return value
+ * @result: location to store the return value
*
* Converts a Javascript value into the nearest 64 bit signed value.
*
- * This function behaves indentically for rounding to JS_ValueToInt32(), which
- * means that it rounds (0.5 toward positive infinity) rather than doing
- * a C-style truncation to 0. If we change to using JS::ToInt32() then this
- * should be changed to match.
- *
- * Return value: If the javascript value converted to a number (see
- * JS::ToNumber()) is NaN, or outside the range of 64-bit signed numbers,
- * fails and sets an exception. Otherwise returns the value rounded to the
- * nearest 64-bit integer. Like JS::ToInt32(), undefined throws, but
- * null => 0, false => 0, true => 1.
+ * Deprecated: Use JS::ToInt64() instead.
*/
bool
gjs_value_to_int64(JSContext *context,
const JS::Value val,
gint64 *result)
{
- if (val.isInt32()) {
- *result = val.toInt32();
- return true;
- } else {
- double value_double;
- if (!JS::ToNumber(context, val, &value_double))
- return false;
-
- if (isnan(value_double) ||
- value_double < G_MININT64 ||
- value_double > G_MAXINT64) {
-
- gjs_throw(context,
- "Value is not a valid 64-bit integer");
- return false;
- }
-
- *result = (gint64)(value_double + 0.5);
- return true;
- }
+ return JS::ToInt64(context, val, result);
}
static bool
@@ -1002,7 +974,7 @@ gjs_parse_args_valist (JSContext *context,
}
break;
case 'i': {
- if (!JS_ValueToInt32(context, js_value, (gint32*) arg_location)) {
+ if (!JS::ToInt32(context, js_value, (int32_t *) arg_location)) {
/* Our error message is going to be more useful */
JS_ClearPendingException(context);
arg_error_message = "Couldn't convert to integer";
@@ -1023,7 +995,7 @@ gjs_parse_args_valist (JSContext *context,
}
break;
case 't': {
- if (!gjs_value_to_int64(context, js_value, (gint64*) arg_location)) {
+ if (!JS::ToInt64(context, js_value, (gint64*) arg_location)) {
/* Our error message is going to be more useful */
JS_ClearPendingException(context);
arg_error_message = "Couldn't convert to 64-bit integer";
@@ -1088,7 +1060,7 @@ gjs_parse_args_valist (JSContext *context,
* F: A string, converted into "filename encoding" (i.e. active locale)
* i: A number, will be converted to a C "gint32"
* u: A number, converted into a C "guint32"
- * t: A 64-bit number, converted into a C "gint64" by way of gjs_value_to_int64()
+ * t: A 64-bit number, converted into a C "gint64"
* o: A JavaScript object, as a "JSObject *"
*
* If the first character in the format string is a '!', then JS is allowed
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 4b8ab01..5b6b3ef 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -406,7 +406,8 @@ const char* gjs_get_type_name (JS::Value value);
bool gjs_value_to_int64 (JSContext *context,
const JS::Value val,
- gint64 *result);
+ gint64 *result)
+G_GNUC_DEPRECATED_FOR(JS::ToInt64);
bool gjs_parse_args (JSContext *context,
const char *function_name,
diff --git a/installed-tests/js/testGDBus.js b/installed-tests/js/testGDBus.js
index 4e5c8ec..eff6765 100644
--- a/installed-tests/js/testGDBus.js
+++ b/installed-tests/js/testGDBus.js
@@ -591,7 +591,7 @@ function testDictSignatures() {
JSUnit.assertNotNull(theResult);
// verify the fractional part was dropped off int
- JSUnit.assertEquals(11, theResult['anInteger'].deep_unpack());
+ JSUnit.assertEquals(10, theResult['anInteger'].deep_unpack());
// and not dropped off a double
JSUnit.assertEquals(10.5, theResult['aDoubleBeforeAndAfter'].deep_unpack());
diff --git a/modules/cairo-region.cpp b/modules/cairo-region.cpp
index 74688da..e635ecf 100644
--- a/modules/cairo-region.cpp
+++ b/modules/cairo-region.cpp
@@ -122,22 +122,22 @@ fill_rectangle(JSContext *context, JSObject *obj,
if (!gjs_object_get_property_const(context, obj, GJS_STRING_X, &val))
return false;
- if (!JS_ValueToInt32(context, val, &rect->x))
+ if (!JS::ToInt32(context, val, &rect->x))
return false;
if (!gjs_object_get_property_const(context, obj, GJS_STRING_Y, &val))
return false;
- if (!JS_ValueToInt32(context, val, &rect->y))
+ if (!JS::ToInt32(context, val, &rect->y))
return false;
if (!gjs_object_get_property_const(context, obj, GJS_STRING_WIDTH, &val))
return false;
- if (!JS_ValueToInt32(context, val, &rect->width))
+ if (!JS::ToInt32(context, val, &rect->width))
return false;
if (!gjs_object_get_property_const(context, obj, GJS_STRING_HEIGHT, &val))
return false;
- if (!JS_ValueToInt32(context, val, &rect->height))
+ if (!JS::ToInt32(context, val, &rect->height))
return false;
return true;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]