[gjs/wip/ptomato/mozjs31prep] function: Store trampoline pointer in JS::Heap



commit d8bb804bda7d1150a7eccfee2755a594d3836f19
Author: Philip Chimento <philip endlessm com>
Date:   Thu Oct 27 19:18:38 2016 -0700

    function: Store trampoline pointer in JS::Heap
    
    In order to keep tracking the trampoline->js_function when the garbage
    collector moves it, it needs to be stored in a JS::Heap.
    
    The way to do this in future SpiderMonkeys is to use
    JS::PersistentRooted, but that is tricky here since sometimes we want to
    have the pointer (if is_vfunc) and sometimes we don't. After some
    conversation on #jsapi I believe the correct way is to manually add a
    root to the value. I'm not entirely sure though...
    
    (We cannot use a tracer here, as we did in previous commits, because this
    isn't tied to the lifetime of a JS object.)
    
    https://bugzilla.gnome.org/show_bug.cgi?id=742249

 gi/function.cpp |   10 ++++++----
 gi/function.h   |    4 ++--
 gi/object.cpp   |    4 ++--
 3 files changed, 10 insertions(+), 8 deletions(-)
---
diff --git a/gi/function.cpp b/gi/function.cpp
index 638026f..47ed46d 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -87,7 +87,7 @@ gjs_callback_trampoline_unref(GjsCallbackTrampoline *trampoline)
 
         if (!trampoline->is_vfunc) {
             JS_BeginRequest(context);
-            JS_RemoveValueRoot(context, &trampoline->js_function);
+            JS_RemoveValueRoot(context, trampoline->js_function.unsafeGet());
             JS_EndRequest(context);
         }
 
@@ -433,7 +433,7 @@ gjs_destroy_notify_callback(gpointer data)
 
 GjsCallbackTrampoline*
 gjs_callback_trampoline_new(JSContext      *context,
-                            JS::Value       function,
+                            JS::HandleValue function,
                             GICallableInfo *callable_info,
                             GIScopeType     scope,
                             bool            is_vfunc)
@@ -454,7 +454,7 @@ gjs_callback_trampoline_new(JSContext      *context,
     g_base_info_ref((GIBaseInfo*)trampoline->info);
     trampoline->js_function = function;
     if (!is_vfunc)
-        JS_AddValueRoot(context, &trampoline->js_function);
+        JS_AddValueRoot(context, trampoline->js_function.unsafeGet());
 
     /* Analyze param types and directions, similarly to init_cached_function_data */
     n_args = g_callable_info_get_n_args(trampoline->info);
@@ -846,7 +846,9 @@ gjs_invoke_c_function(JSContext       *context,
                 GIScopeType scope = g_arg_info_get_scope(&arg_info);
                 GjsCallbackTrampoline *trampoline;
                 ffi_closure *closure;
-                JS::Value value = js_argv[js_arg_pos];
+                /* COMPAT: Avoid this extra root by changing the function's
+                 * in parameter to JS::HandleValueArray in mozjs31 */
+                JS::RootedValue value(context, js_argv[js_arg_pos]);
 
                 if (value.isNull() && g_arg_info_may_be_null(&arg_info)) {
                     closure = NULL;
diff --git a/gi/function.h b/gi/function.h
index f11a262..5ed5dc9 100644
--- a/gi/function.h
+++ b/gi/function.h
@@ -45,7 +45,7 @@ typedef struct {
     gint ref_count;
     JSContext *context;
     GICallableInfo *info;
-    JS::Value js_function;
+    JS::Heap<JS::Value> js_function;
     ffi_cif cif;
     ffi_closure *closure;
     GIScopeType scope;
@@ -54,7 +54,7 @@ typedef struct {
 } GjsCallbackTrampoline;
 
 GjsCallbackTrampoline* gjs_callback_trampoline_new(JSContext      *context,
-                                                   JS::Value       function,
+                                                   JS::HandleValue function,
                                                    GICallableInfo *callable_info,
                                                    GIScopeType     scope,
                                                    bool            is_vfunc);
diff --git a/gi/object.cpp b/gi/object.cpp
index 188afce..b4a0d0d 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -2289,8 +2289,8 @@ gjs_hook_up_vfunc(JSContext *cx,
         offset = g_field_info_get_offset(field_info);
         method_ptr = G_STRUCT_MEMBER_P(implementor_vtable, offset);
 
-        trampoline = gjs_callback_trampoline_new(cx, JS::ObjectValue(*function),
-                                                 callback_info,
+        JS::RootedValue v_function(cx, JS::ObjectValue(*function));
+        trampoline = gjs_callback_trampoline_new(cx, v_function, callback_info,
                                                  GI_SCOPE_TYPE_NOTIFIED, true);
 
         *((ffi_closure **)method_ptr) = trampoline->closure;


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