[gjs: 1/2] system: add addressOfGObject method



commit 75fd942af27ae2769719346ad706f06e377c7426
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Mon May 27 23:29:55 2019 -0500

    system: add addressOfGObject method
    
    This debug method returns the address of an underlying GObject if the current
    object is of such type. It throws otherwise.
    
    Useful for debugging GObject.Object's, especially once disposed.

 installed-tests/js/testSystem.js | 16 +++++++++++++++-
 modules/system.cpp               | 21 +++++++++++++++++++++
 2 files changed, 36 insertions(+), 1 deletion(-)
---
diff --git a/installed-tests/js/testSystem.js b/installed-tests/js/testSystem.js
index 89a65b5f..922a70fe 100644
--- a/installed-tests/js/testSystem.js
+++ b/installed-tests/js/testSystem.js
@@ -23,6 +23,20 @@ describe('System.refcount()', function () {
     });
 });
 
+describe('System.addressOfGObject()', function () {
+    it('gives different results for different objects', function () {
+        let a = new GObject.Object({});
+        let b = new GObject.Object({});
+        expect(System.addressOfGObject(a)).toEqual(System.addressOfGObject(a));
+        expect(System.addressOfGObject(a)).not.toEqual(System.addressOfGObject(b));
+    });
+
+    it('throws for non GObject objects', function () {
+        expect(() => System.addressOfGObject({})).
+            toThrowError(/Object 0x[a-f0-9]+ is not a GObject/);
+    });
+});
+
 describe('System.gc()', function () {
     it('does not crash the application', function () {
         expect(System.gc).not.toThrow();
@@ -33,4 +47,4 @@ describe('System.dumpHeap()', function () {
     it('throws but does not crash when given a nonexistent path', function () {
         expect(() => System.dumpHeap('/does/not/exist')).toThrow();
     });
-});
\ No newline at end of file
+});
diff --git a/modules/system.cpp b/modules/system.cpp
index 8d523991..6ca99195 100644
--- a/modules/system.cpp
+++ b/modules/system.cpp
@@ -58,6 +58,26 @@ gjs_address_of(JSContext *context,
     return gjs_string_from_utf8(context, pointer_string, argv.rval());
 }
 
+GJS_JSAPI_RETURN_CONVENTION
+static bool gjs_address_of_gobject(JSContext* cx, unsigned argc,
+                                   JS::Value* vp) {
+    JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
+    JS::RootedObject target_obj(cx);
+    GObject *obj;
+
+    if (!gjs_parse_call_args(cx, "addressOfGObject", argv, "o", "object",
+                             &target_obj))
+        return false;
+
+    if (!ObjectBase::to_c_ptr(cx, target_obj, &obj)) {
+        gjs_throw(cx, "Object %p is not a GObject", &target_obj);
+        return false;
+    }
+
+    GjsAutoChar pointer_string = g_strdup_printf("%p", obj);
+    return gjs_string_from_utf8(cx, pointer_string, argv.rval());
+}
+
 static bool
 gjs_refcount(JSContext *context,
              unsigned   argc,
@@ -174,6 +194,7 @@ gjs_clear_date_caches(JSContext *context,
 
 static JSFunctionSpec module_funcs[] = {
     JS_FN("addressOf", gjs_address_of, 1, GJS_MODULE_PROP_FLAGS),
+    JS_FN("addressOfGObject", gjs_address_of_gobject, 1, GJS_MODULE_PROP_FLAGS),
     JS_FN("refcount", gjs_refcount, 1, GJS_MODULE_PROP_FLAGS),
     JS_FN("breakpoint", gjs_breakpoint, 0, GJS_MODULE_PROP_FLAGS),
     JS_FN("dumpHeap", gjs_dump_heap, 1, GJS_MODULE_PROP_FLAGS),


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]