|
|
f96290 |
From a44c356190f44f1532208f1a0612a878bbafce27 Mon Sep 17 00:00:00 2001
|
|
|
f96290 |
From: Ray Strode <rstrode@redhat.com>
|
|
|
f96290 |
Date: Fri, 16 Feb 2018 10:51:37 -0500
|
|
|
f96290 |
Subject: [PATCH] object: only print stacktraces when debugging enabled
|
|
|
f96290 |
|
|
|
f96290 |
We have a bunch of corruption right now spamming the
|
|
|
f96290 |
log.
|
|
|
f96290 |
|
|
|
f96290 |
This commit gets rid of the spam unless G_MESSAGES_DEBUG
|
|
|
f96290 |
is set.
|
|
|
f96290 |
---
|
|
|
f96290 |
gi/object.cpp | 86 +++++++++++++++++++++++++++++++--------------------
|
|
|
f96290 |
1 file changed, 52 insertions(+), 34 deletions(-)
|
|
|
f96290 |
|
|
|
f96290 |
diff --git a/gi/object.cpp b/gi/object.cpp
|
|
|
f96290 |
index fe381ec3..bd09a75c 100644
|
|
|
f96290 |
--- a/gi/object.cpp
|
|
|
f96290 |
+++ b/gi/object.cpp
|
|
|
f96290 |
@@ -127,60 +127,83 @@ struct ObjectInstance {
|
|
|
f96290 |
prototypes) */
|
|
|
f96290 |
GTypeClass *klass;
|
|
|
f96290 |
|
|
|
f96290 |
GjsListLink instance_link;
|
|
|
f96290 |
|
|
|
f96290 |
unsigned js_object_finalized : 1;
|
|
|
f96290 |
unsigned g_object_finalized : 1;
|
|
|
f96290 |
|
|
|
f96290 |
/* True if this object has visible JS state, and thus its lifecycle is
|
|
|
f96290 |
* managed using toggle references. False if this object just keeps a
|
|
|
f96290 |
* hard ref on the underlying GObject, and may be finalized at will. */
|
|
|
f96290 |
bool uses_toggle_ref : 1;
|
|
|
f96290 |
};
|
|
|
f96290 |
|
|
|
f96290 |
static std::stack<JS::PersistentRootedObject> object_init_list;
|
|
|
f96290 |
|
|
|
f96290 |
using ParamRef = std::unique_ptr<GParamSpec, decltype(&g_param_spec_unref)>;
|
|
|
f96290 |
using ParamRefArray = std::vector<ParamRef>;
|
|
|
f96290 |
static std::unordered_map<GType, ParamRefArray> class_init_properties;
|
|
|
f96290 |
|
|
|
f96290 |
static bool context_weak_pointer_callback = false;
|
|
|
f96290 |
static bool weak_pointer_callback = false;
|
|
|
f96290 |
ObjectInstance *wrapped_gobject_list;
|
|
|
f96290 |
|
|
|
f96290 |
extern struct JSClass gjs_object_instance_class;
|
|
|
f96290 |
GJS_DEFINE_PRIV_FROM_JS(ObjectInstance, gjs_object_instance_class)
|
|
|
f96290 |
|
|
|
f96290 |
static void disassociate_js_gobject (GObject *gobj);
|
|
|
f96290 |
static void ensure_uses_toggle_ref(JSContext *cx, ObjectInstance *priv);
|
|
|
f96290 |
|
|
|
f96290 |
+static void
|
|
|
f96290 |
+gjs_log_stacktrace(const char *format,
|
|
|
f96290 |
+ ...)
|
|
|
f96290 |
+{
|
|
|
f96290 |
+ const char *domain;
|
|
|
f96290 |
+ va_list args;
|
|
|
f96290 |
+
|
|
|
f96290 |
+ domain = g_getenv("G_MESSAGES_DEBUG");
|
|
|
f96290 |
+
|
|
|
f96290 |
+ if (!domain)
|
|
|
f96290 |
+ return;
|
|
|
f96290 |
+
|
|
|
f96290 |
+ if (!g_str_equal(domain, "all") &&
|
|
|
f96290 |
+ !strstr(domain, G_LOG_DOMAIN))
|
|
|
f96290 |
+ return;
|
|
|
f96290 |
+
|
|
|
f96290 |
+ va_start(args, format);
|
|
|
f96290 |
+ g_logv(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format, args);
|
|
|
f96290 |
+ va_end(args);
|
|
|
f96290 |
+
|
|
|
f96290 |
+ gjs_dumpstack();
|
|
|
f96290 |
+}
|
|
|
f96290 |
+
|
|
|
f96290 |
typedef enum {
|
|
|
f96290 |
SOME_ERROR_OCCURRED = false,
|
|
|
f96290 |
NO_SUCH_G_PROPERTY,
|
|
|
f96290 |
VALUE_WAS_SET
|
|
|
f96290 |
} ValueFromPropertyResult;
|
|
|
f96290 |
|
|
|
f96290 |
static GQuark
|
|
|
f96290 |
gjs_is_custom_type_quark (void)
|
|
|
f96290 |
{
|
|
|
f96290 |
static GQuark val = 0;
|
|
|
f96290 |
if (!val)
|
|
|
f96290 |
val = g_quark_from_static_string ("gjs::custom-type");
|
|
|
f96290 |
|
|
|
f96290 |
return val;
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
static GQuark
|
|
|
f96290 |
gjs_is_custom_property_quark (void)
|
|
|
f96290 |
{
|
|
|
f96290 |
static GQuark val = 0;
|
|
|
f96290 |
if (!val)
|
|
|
f96290 |
val = g_quark_from_static_string ("gjs::custom-property");
|
|
|
f96290 |
|
|
|
f96290 |
return val;
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
static GQuark
|
|
|
f96290 |
gjs_object_priv_quark (void)
|
|
|
f96290 |
{
|
|
|
f96290 |
static GQuark val = 0;
|
|
|
f96290 |
@@ -433,66 +456,65 @@ out:
|
|
|
f96290 |
/* a hook on getting a property; set value_p to override property's value.
|
|
|
f96290 |
* Return value is false on OOM/exception.
|
|
|
f96290 |
*/
|
|
|
f96290 |
static bool
|
|
|
f96290 |
object_instance_get_prop(JSContext *context,
|
|
|
f96290 |
JS::HandleObject obj,
|
|
|
f96290 |
JS::HandleId id,
|
|
|
f96290 |
JS::MutableHandleValue value_p)
|
|
|
f96290 |
{
|
|
|
f96290 |
ObjectInstance *priv;
|
|
|
f96290 |
GjsAutoJSChar name;
|
|
|
f96290 |
|
|
|
f96290 |
if (!gjs_get_string_id(context, id, &name))
|
|
|
f96290 |
return true; /* not resolved, but no error */
|
|
|
f96290 |
|
|
|
f96290 |
priv = priv_from_js(context, obj);
|
|
|
f96290 |
gjs_debug_jsprop(GJS_DEBUG_GOBJECT,
|
|
|
f96290 |
"Get prop '%s' hook obj %p priv %p",
|
|
|
f96290 |
name.get(), obj.get(), priv);
|
|
|
f96290 |
|
|
|
f96290 |
if (priv == nullptr)
|
|
|
f96290 |
/* If we reach this point, either object_instance_new_resolve
|
|
|
f96290 |
* did not throw (so name == "_init"), or the property actually
|
|
|
f96290 |
* exists and it's not something we should be concerned with */
|
|
|
f96290 |
return true;
|
|
|
f96290 |
|
|
|
f96290 |
if (priv->gobj == NULL) /* prototype, not an instance. */
|
|
|
f96290 |
return true;
|
|
|
f96290 |
|
|
|
f96290 |
if (priv->g_object_finalized) {
|
|
|
f96290 |
- g_critical("Object %s.%s (%p), has been already finalized. "
|
|
|
f96290 |
- "Impossible to get any property from it.",
|
|
|
f96290 |
- priv->info ? g_base_info_get_namespace( (GIBaseInfo*) priv->info) : "",
|
|
|
f96290 |
- priv->info ? g_base_info_get_name( (GIBaseInfo*) priv->info) : g_type_name(priv->gtype),
|
|
|
f96290 |
- priv->gobj);
|
|
|
f96290 |
- gjs_dumpstack();
|
|
|
f96290 |
+ gjs_log_stacktrace("Object %s.%s (%p), has been already finalized. "
|
|
|
f96290 |
+ "Impossible to get any property from it.",
|
|
|
f96290 |
+ priv->info ? g_base_info_get_namespace( (GIBaseInfo*) priv->info) : "",
|
|
|
f96290 |
+ priv->info ? g_base_info_get_name( (GIBaseInfo*) priv->info) : g_type_name(priv->gtype),
|
|
|
f96290 |
+ priv->gobj);
|
|
|
f96290 |
return true;
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
if (!get_prop_from_g_param(context, obj, priv, name, value_p))
|
|
|
f96290 |
return false;
|
|
|
f96290 |
|
|
|
f96290 |
if (!value_p.isUndefined())
|
|
|
f96290 |
return true;
|
|
|
f96290 |
|
|
|
f96290 |
/* Fall back to fields */
|
|
|
f96290 |
return get_prop_from_field(context, obj, priv, name, value_p);
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
static bool
|
|
|
f96290 |
set_g_param_from_prop(JSContext *context,
|
|
|
f96290 |
ObjectInstance *priv,
|
|
|
f96290 |
const char *name,
|
|
|
f96290 |
bool& was_set,
|
|
|
f96290 |
JS::HandleValue value_p,
|
|
|
f96290 |
JS::ObjectOpResult& result)
|
|
|
f96290 |
{
|
|
|
f96290 |
GParameter param = { NULL, { 0, }};
|
|
|
f96290 |
was_set = false;
|
|
|
f96290 |
|
|
|
f96290 |
switch (init_g_param_from_property(context, name,
|
|
|
f96290 |
value_p,
|
|
|
f96290 |
G_TYPE_FROM_INSTANCE(priv->gobj),
|
|
|
f96290 |
¶m,
|
|
|
f96290 |
false /* constructing */)) {
|
|
|
f96290 |
case SOME_ERROR_OCCURRED:
|
|
|
f96290 |
@@ -549,66 +571,65 @@ check_set_field_from_prop(JSContext *cx,
|
|
|
f96290 |
value_p.setUndefined();
|
|
|
f96290 |
out:
|
|
|
f96290 |
g_base_info_unref((GIBaseInfo *) field);
|
|
|
f96290 |
return retval;
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
/* a hook on setting a property; set value_p to override property value to
|
|
|
f96290 |
* be set. Return value is false on OOM/exception.
|
|
|
f96290 |
*/
|
|
|
f96290 |
static bool
|
|
|
f96290 |
object_instance_set_prop(JSContext *context,
|
|
|
f96290 |
JS::HandleObject obj,
|
|
|
f96290 |
JS::HandleId id,
|
|
|
f96290 |
JS::MutableHandleValue value_p,
|
|
|
f96290 |
JS::ObjectOpResult& result)
|
|
|
f96290 |
{
|
|
|
f96290 |
ObjectInstance *priv;
|
|
|
f96290 |
GjsAutoJSChar name;
|
|
|
f96290 |
bool ret = true;
|
|
|
f96290 |
bool g_param_was_set = false;
|
|
|
f96290 |
|
|
|
f96290 |
priv = priv_from_js(context, obj);
|
|
|
f96290 |
if (priv == nullptr)
|
|
|
f96290 |
/* see the comment in object_instance_get_prop() on this */
|
|
|
f96290 |
return result.succeed();
|
|
|
f96290 |
|
|
|
f96290 |
if (priv->gobj == NULL) /* prototype, not an instance. */
|
|
|
f96290 |
return result.succeed();
|
|
|
f96290 |
|
|
|
f96290 |
if (priv->g_object_finalized) {
|
|
|
f96290 |
- g_critical("Object %s.%s (%p), has been already finalized. "
|
|
|
f96290 |
- "Impossible to set any property to it.",
|
|
|
f96290 |
- priv->info ? g_base_info_get_namespace( (GIBaseInfo*) priv->info) : "",
|
|
|
f96290 |
- priv->info ? g_base_info_get_name( (GIBaseInfo*) priv->info) : g_type_name(priv->gtype),
|
|
|
f96290 |
- priv->gobj);
|
|
|
f96290 |
- gjs_dumpstack();
|
|
|
f96290 |
+ gjs_log_stacktrace("Object %s.%s (%p), has been already finalized. "
|
|
|
f96290 |
+ "Impossible to set any property to it.",
|
|
|
f96290 |
+ priv->info ? g_base_info_get_namespace( (GIBaseInfo*) priv->info) : "",
|
|
|
f96290 |
+ priv->info ? g_base_info_get_name( (GIBaseInfo*) priv->info) : g_type_name(priv->gtype),
|
|
|
f96290 |
+ priv->gobj);
|
|
|
f96290 |
return result.succeed();
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
if (!gjs_get_string_id(context, id, &name)) {
|
|
|
f96290 |
/* We need to keep the wrapper alive in order not to lose custom
|
|
|
f96290 |
* "expando" properties. In this case if gjs_get_string_id() is false
|
|
|
f96290 |
* then a number or symbol property was probably set. */
|
|
|
f96290 |
ensure_uses_toggle_ref(context, priv);
|
|
|
f96290 |
return result.succeed(); /* not resolved, but no error */
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
gjs_debug_jsprop(GJS_DEBUG_GOBJECT,
|
|
|
f96290 |
"Set prop '%s' hook obj %p priv %p",
|
|
|
f96290 |
name.get(), obj.get(), priv);
|
|
|
f96290 |
|
|
|
f96290 |
ret = set_g_param_from_prop(context, priv, name, g_param_was_set, value_p, result);
|
|
|
f96290 |
if (g_param_was_set || !ret)
|
|
|
f96290 |
return ret;
|
|
|
f96290 |
|
|
|
f96290 |
/* note that the prop will also have been set in JS, which I think
|
|
|
f96290 |
* is OK, since we hook get and set so will always override that
|
|
|
f96290 |
* value. We could also use JS_DefineProperty though and specify a
|
|
|
f96290 |
* getter/setter maybe, don't know if that is better.
|
|
|
f96290 |
*/
|
|
|
f96290 |
return check_set_field_from_prop(context, priv, name, value_p, result);
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
static bool
|
|
|
f96290 |
is_vfunc_unchanged(GIVFuncInfo *info,
|
|
|
f96290 |
GType gtype)
|
|
|
f96290 |
@@ -1780,67 +1801,66 @@ do_associate_closure(ObjectInstance *priv,
|
|
|
f96290 |
* invalidated */
|
|
|
f96290 |
priv->closures.insert(closure);
|
|
|
f96290 |
g_closure_add_invalidate_notifier(closure, priv, closure_invalidated);
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
static bool
|
|
|
f96290 |
real_connect_func(JSContext *context,
|
|
|
f96290 |
unsigned argc,
|
|
|
f96290 |
JS::Value *vp,
|
|
|
f96290 |
bool after)
|
|
|
f96290 |
{
|
|
|
f96290 |
GJS_GET_PRIV(context, argc, vp, argv, obj, ObjectInstance, priv);
|
|
|
f96290 |
GClosure *closure;
|
|
|
f96290 |
gulong id;
|
|
|
f96290 |
guint signal_id;
|
|
|
f96290 |
GQuark signal_detail;
|
|
|
f96290 |
|
|
|
f96290 |
gjs_debug_gsignal("connect obj %p priv %p argc %d", obj.get(), priv, argc);
|
|
|
f96290 |
if (priv == NULL) {
|
|
|
f96290 |
throw_priv_is_null_error(context);
|
|
|
f96290 |
return false; /* wrong class passed in */
|
|
|
f96290 |
}
|
|
|
f96290 |
if (priv->gobj == NULL) {
|
|
|
f96290 |
/* prototype, not an instance. */
|
|
|
f96290 |
gjs_throw(context, "Can't connect to signals on %s.%s.prototype; only on instances",
|
|
|
f96290 |
priv->info ? g_base_info_get_namespace( (GIBaseInfo*) priv->info) : "",
|
|
|
f96290 |
priv->info ? g_base_info_get_name( (GIBaseInfo*) priv->info) : g_type_name(priv->gtype));
|
|
|
f96290 |
return false;
|
|
|
f96290 |
}
|
|
|
f96290 |
if (priv->g_object_finalized) {
|
|
|
f96290 |
- g_critical("Object %s.%s (%p), has been already deallocated - impossible to connect to signal. "
|
|
|
f96290 |
- "This might be caused by the fact that the object has been destroyed from C "
|
|
|
f96290 |
- "code using something such as destroy(), dispose(), or remove() vfuncs",
|
|
|
f96290 |
- priv->info ? g_base_info_get_namespace( (GIBaseInfo*) priv->info) : "",
|
|
|
f96290 |
- priv->info ? g_base_info_get_name( (GIBaseInfo*) priv->info) : g_type_name(priv->gtype),
|
|
|
f96290 |
- priv->gobj);
|
|
|
f96290 |
- gjs_dumpstack();
|
|
|
f96290 |
+ gjs_log_stacktrace("Object %s.%s (%p), has been already deallocated - impossible to connect to signal. "
|
|
|
f96290 |
+ "This might be caused by the fact that the object has been destroyed from C "
|
|
|
f96290 |
+ "code using something such as destroy(), dispose(), or remove() vfuncs",
|
|
|
f96290 |
+ priv->info ? g_base_info_get_namespace( (GIBaseInfo*) priv->info) : "",
|
|
|
f96290 |
+ priv->info ? g_base_info_get_name( (GIBaseInfo*) priv->info) : g_type_name(priv->gtype),
|
|
|
f96290 |
+ priv->gobj);
|
|
|
f96290 |
return true;
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
ensure_uses_toggle_ref(context, priv);
|
|
|
f96290 |
|
|
|
f96290 |
if (argc != 2 || !argv[0].isString() || !JS::IsCallable(&argv[1].toObject())) {
|
|
|
f96290 |
gjs_throw(context, "connect() takes two args, the signal name and the callback");
|
|
|
f96290 |
return false;
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
JS::RootedString signal_str(context, argv[0].toString());
|
|
|
f96290 |
GjsAutoJSChar signal_name = JS_EncodeStringToUTF8(context, signal_str);
|
|
|
f96290 |
if (!signal_name)
|
|
|
f96290 |
return false;
|
|
|
f96290 |
|
|
|
f96290 |
if (!g_signal_parse_name(signal_name,
|
|
|
f96290 |
G_OBJECT_TYPE(priv->gobj),
|
|
|
f96290 |
&signal_id,
|
|
|
f96290 |
&signal_detail,
|
|
|
f96290 |
true)) {
|
|
|
f96290 |
gjs_throw(context, "No signal '%s' on object '%s'",
|
|
|
f96290 |
signal_name.get(),
|
|
|
f96290 |
g_type_name(G_OBJECT_TYPE(priv->gobj)));
|
|
|
f96290 |
return false;
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
closure = gjs_closure_new_for_signal(context, &argv[1].toObject(), "signal callback", signal_id);
|
|
|
f96290 |
if (closure == NULL)
|
|
|
f96290 |
return false;
|
|
|
f96290 |
do_associate_closure(priv, closure);
|
|
|
f96290 |
@@ -1875,67 +1895,66 @@ connect_func(JSContext *context,
|
|
|
f96290 |
static bool
|
|
|
f96290 |
emit_func(JSContext *context,
|
|
|
f96290 |
unsigned argc,
|
|
|
f96290 |
JS::Value *vp)
|
|
|
f96290 |
{
|
|
|
f96290 |
GJS_GET_PRIV(context, argc, vp, argv, obj, ObjectInstance, priv);
|
|
|
f96290 |
guint signal_id;
|
|
|
f96290 |
GQuark signal_detail;
|
|
|
f96290 |
GSignalQuery signal_query;
|
|
|
f96290 |
GValue *instance_and_args;
|
|
|
f96290 |
GValue rvalue = G_VALUE_INIT;
|
|
|
f96290 |
unsigned int i;
|
|
|
f96290 |
bool failed;
|
|
|
f96290 |
|
|
|
f96290 |
gjs_debug_gsignal("emit obj %p priv %p argc %d", obj.get(), priv, argc);
|
|
|
f96290 |
|
|
|
f96290 |
if (priv == NULL) {
|
|
|
f96290 |
throw_priv_is_null_error(context);
|
|
|
f96290 |
return false; /* wrong class passed in */
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
if (priv->gobj == NULL) {
|
|
|
f96290 |
/* prototype, not an instance. */
|
|
|
f96290 |
gjs_throw(context, "Can't emit signal on %s.%s.prototype; only on instances",
|
|
|
f96290 |
priv->info ? g_base_info_get_namespace( (GIBaseInfo*) priv->info) : "",
|
|
|
f96290 |
priv->info ? g_base_info_get_name( (GIBaseInfo*) priv->info) : g_type_name(priv->gtype));
|
|
|
f96290 |
return false;
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
if (priv->g_object_finalized) {
|
|
|
f96290 |
- g_critical("Object %s.%s (%p), has been already deallocated - impossible to emit signal. "
|
|
|
f96290 |
- "This might be caused by the fact that the object has been destroyed from C "
|
|
|
f96290 |
- "code using something such as destroy(), dispose(), or remove() vfuncs",
|
|
|
f96290 |
- priv->info ? g_base_info_get_namespace( (GIBaseInfo*) priv->info) : "",
|
|
|
f96290 |
- priv->info ? g_base_info_get_name( (GIBaseInfo*) priv->info) : g_type_name(priv->gtype),
|
|
|
f96290 |
- priv->gobj);
|
|
|
f96290 |
- gjs_dumpstack();
|
|
|
f96290 |
+ gjs_log_stacktrace("Object %s.%s (%p), has been already deallocated - impossible to emit signal. "
|
|
|
f96290 |
+ "This might be caused by the fact that the object has been destroyed from C "
|
|
|
f96290 |
+ "code using something such as destroy(), dispose(), or remove() vfuncs",
|
|
|
f96290 |
+ priv->info ? g_base_info_get_namespace( (GIBaseInfo*) priv->info) : "",
|
|
|
f96290 |
+ priv->info ? g_base_info_get_name( (GIBaseInfo*) priv->info) : g_type_name(priv->gtype),
|
|
|
f96290 |
+ priv->gobj);
|
|
|
f96290 |
return true;
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
if (argc < 1 || !argv[0].isString()) {
|
|
|
f96290 |
gjs_throw(context, "emit() first arg is the signal name");
|
|
|
f96290 |
return false;
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
JS::RootedString signal_str(context, argv[0].toString());
|
|
|
f96290 |
GjsAutoJSChar signal_name = JS_EncodeStringToUTF8(context, signal_str);
|
|
|
f96290 |
if (!signal_name)
|
|
|
f96290 |
return false;
|
|
|
f96290 |
|
|
|
f96290 |
if (!g_signal_parse_name(signal_name,
|
|
|
f96290 |
G_OBJECT_TYPE(priv->gobj),
|
|
|
f96290 |
&signal_id,
|
|
|
f96290 |
&signal_detail,
|
|
|
f96290 |
false)) {
|
|
|
f96290 |
gjs_throw(context, "No signal '%s' on object '%s'",
|
|
|
f96290 |
signal_name.get(),
|
|
|
f96290 |
g_type_name(G_OBJECT_TYPE(priv->gobj)));
|
|
|
f96290 |
return false;
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
g_signal_query(signal_id, &signal_query);
|
|
|
f96290 |
|
|
|
f96290 |
if ((argc - 1) != signal_query.n_params) {
|
|
|
f96290 |
gjs_throw(context, "Signal '%s' on %s requires %d args got %d",
|
|
|
f96290 |
signal_name.get(),
|
|
|
f96290 |
g_type_name(G_OBJECT_TYPE(priv->gobj)),
|
|
|
f96290 |
@@ -2250,68 +2269,67 @@ gjs_object_from_g_object(JSContext *context,
|
|
|
f96290 |
return nullptr;
|
|
|
f96290 |
|
|
|
f96290 |
JS::RootedObject obj(context,
|
|
|
f96290 |
JS_NewObjectWithGivenProto(context, JS_GetClass(proto), proto));
|
|
|
f96290 |
if (!obj)
|
|
|
f96290 |
return nullptr;
|
|
|
f96290 |
|
|
|
f96290 |
priv = init_object_private(context, obj);
|
|
|
f96290 |
|
|
|
f96290 |
g_object_ref_sink(gobj);
|
|
|
f96290 |
associate_js_gobject(context, obj, gobj);
|
|
|
f96290 |
|
|
|
f96290 |
g_assert(priv->keep_alive == obj.get());
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
return priv->keep_alive;
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
GObject*
|
|
|
f96290 |
gjs_g_object_from_object(JSContext *context,
|
|
|
f96290 |
JS::HandleObject obj)
|
|
|
f96290 |
{
|
|
|
f96290 |
ObjectInstance *priv;
|
|
|
f96290 |
|
|
|
f96290 |
if (!obj)
|
|
|
f96290 |
return NULL;
|
|
|
f96290 |
|
|
|
f96290 |
priv = priv_from_js(context, obj);
|
|
|
f96290 |
|
|
|
f96290 |
if (priv->g_object_finalized) {
|
|
|
f96290 |
- g_critical("Object %s.%s (%p), has been already deallocated - "
|
|
|
f96290 |
- "impossible to access it. This might be caused by the "
|
|
|
f96290 |
- "object having been destroyed from C code using something "
|
|
|
f96290 |
- "such as destroy(), dispose(), or remove() vfuncs",
|
|
|
f96290 |
- priv->info ? g_base_info_get_namespace(priv->info) : "",
|
|
|
f96290 |
- priv->info ? g_base_info_get_name(priv->info) : g_type_name(priv->gtype),
|
|
|
f96290 |
- priv->gobj);
|
|
|
f96290 |
- gjs_dumpstack();
|
|
|
f96290 |
+ gjs_log_stacktrace ("Object %s.%s (%p), has been already deallocated - "
|
|
|
f96290 |
+ "impossible to access it. This might be caused by the "
|
|
|
f96290 |
+ "object having been destroyed from C code using something "
|
|
|
f96290 |
+ "such as destroy(), dispose(), or remove() vfuncs",
|
|
|
f96290 |
+ priv->info ? g_base_info_get_namespace(priv->info) : "",
|
|
|
f96290 |
+ priv->info ? g_base_info_get_name(priv->info) : g_type_name(priv->gtype),
|
|
|
f96290 |
+ priv->gobj);
|
|
|
f96290 |
return nullptr;
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
return priv->gobj;
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
bool
|
|
|
f96290 |
gjs_typecheck_is_object(JSContext *context,
|
|
|
f96290 |
JS::HandleObject object,
|
|
|
f96290 |
bool throw_error)
|
|
|
f96290 |
{
|
|
|
f96290 |
return do_base_typecheck(context, object, throw_error);
|
|
|
f96290 |
}
|
|
|
f96290 |
|
|
|
f96290 |
bool
|
|
|
f96290 |
gjs_typecheck_object(JSContext *context,
|
|
|
f96290 |
JS::HandleObject object,
|
|
|
f96290 |
GType expected_type,
|
|
|
f96290 |
bool throw_error)
|
|
|
f96290 |
{
|
|
|
f96290 |
ObjectInstance *priv;
|
|
|
f96290 |
bool result;
|
|
|
f96290 |
|
|
|
f96290 |
if (!do_base_typecheck(context, object, throw_error))
|
|
|
f96290 |
return false;
|
|
|
f96290 |
|
|
|
f96290 |
priv = priv_from_js(context, object);
|
|
|
f96290 |
|
|
|
f96290 |
if (priv == NULL) {
|
|
|
f96290 |
if (throw_error) {
|
|
|
f96290 |
--
|
|
|
f96290 |
2.17.1
|
|
|
f96290 |
|