Bug 848464 - gobject javascript bindings cannot use 64 bit integers
Summary: gobject javascript bindings cannot use 64 bit integers
Keywords:
Status: NEW
Alias: None
Product: Virtualization Tools
Classification: Community
Component: libguestfs
Version: unspecified
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Richard W.M. Jones
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2012-08-15 16:38 UTC by Richard W.M. Jones
Modified: 2021-04-19 10:34 UTC (History)
1 user (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description Richard W.M. Jones 2012-08-15 16:38:36 UTC
Description of problem:

64 bit integers cannot be used reliably via the Javascript
GObject bindings.  This applies to gjs, I didn't test anything
else.  It applies to integer literals, but my belief is this
bug would affect any 64 bit number, not just source code literals
but ones eg. read in from external sources or passed through
to the API from return values from other functions.

Version-Release number of selected component (if applicable):

libguestfs 1.19.30

How reproducible:

100%

Steps to Reproduce:
1. ./run gjs gobject/bindtests.js

Actual results:

Fails on the following line:
o = new Guestfs.InternalTest({obool: true, oint: 1, oint64: 9223372036854775807});
with the error:

    JS ERROR: !!!   Exception was: Error: can't convert 9223372036854776000 to an integer
    JS ERROR: !!!     message = '"can't convert 9223372036854776000 to an integer"'
    JS ERROR: !!!     fileName = '"gobject/bindtests.js"'
    JS ERROR: !!!     lineNumber = '27'
    JS ERROR: !!!     stack = '"@gobject/bindtests.js:27
"'
Error: can't convert 9223372036854776000 to an integer

Additional info:

There seem to be two interacting problems.

(1) Javascript cannot represent 64 bit integers accurately.  We should
be using another type, eg. string.

(2) GObject Introspection converts the number to a 32 bit integer and
fails on overflow, so any time we try to use a number which is larger
than can be held in a 32 bit integer, this is going to fail.

Comment 1 Richard W.M. Jones 2012-11-30 14:36:44 UTC
I had a look into this, and here are my findings:

(1) GObject is a world of pain.  It's a wonder it works at all.

(2) gjs is a thin wrapper around SpiderMonkey, which is the same
Javascript engine used by Firefox (ie. written by Mozilla).
https://developer.mozilla.org/en/docs/SpiderMonkey
http://pkgs.fedoraproject.org/cgit/js.git/

(3) SpiderMonkey has a well-defined embedding API, mainly
designed so you can use it from other applications.  See:
https://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_User_Guide

(4) gjs supports "native modules".  These are .so objects which
are dlopened and load into gjs, they are present on the search
path etc.  All the examples use GObject, but I'm not sure if that's
required -- apart from GObject stupid, most of them just make
direct JSAPI calls.
http://git.gnome.org/browse/gjs/tree/modules/

$ ls -l /usr/lib64/gjs-1.0/
total 240
-rwxr-xr-x. 1 root root 90280 Sep 25 16:52 cairoNative.so
-rwxr-xr-x. 1 root root 11288 Sep 25 16:52 console.so
-rwxr-xr-x. 1 root root 71096 Sep 25 16:52 dbusNative.so
-rwxr-xr-x. 1 root root  6960 Sep 25 16:52 debugger.so
-rwxr-xr-x. 1 root root  7000 Sep 25 16:52 formatNative.so
-rwxr-xr-x. 1 root root 11200 Sep 25 16:52 gettextNative.so
-rwxr-xr-x. 1 root root  6984 Sep 25 16:52 langNative.so
-rwxr-xr-x. 1 root root 15600 Sep 25 16:52 mainloop.so
-rwxr-xr-x. 1 root root 11184 Sep 25 16:52 system.so

So could we not write the Javascript bindings either directly
using the JSAPI, or that plus a thin gjs "native module"
wrapper?  That would eliminate use of GObject Introspection,
and possibly even GObject entirely.


Note You need to log in before you can comment on or make changes to this bug.