/* Find the first constructor */ static GIFunctionInfo * find_fundamental_constructor(JSContext *context, GIObjectInfo *info, jsid *constructor_name) { int i, n_methods; n_methods = g_object_info_get_n_methods(info); for (i = 0; i < n_methods; ++i) { GIFunctionInfo *func_info; GIFunctionInfoFlags flags; func_info = g_object_info_get_method(info, i); flags = g_function_info_get_flags(func_info); if ((flags & GI_FUNCTION_IS_CONSTRUCTOR) != 0) { const char *name; name = g_base_info_get_name((GIBaseInfo *) func_info); *constructor_name = gjs_intern_string_to_id(context, name); return func_info; } g_base_info_unref((GIBaseInfo *) func_info); } return NULL; }
PyObject * _wrap_g_callable_info_invoke (PyGIBaseInfo *self, PyObject *py_args, PyObject *kwargs) { if (self->cache == NULL) { PyGIFunctionCache *function_cache; GIInfoType type = g_base_info_get_type (self->info); if (type == GI_INFO_TYPE_FUNCTION) { GIFunctionInfoFlags flags; flags = g_function_info_get_flags ( (GIFunctionInfo *)self->info); if (flags & GI_FUNCTION_IS_CONSTRUCTOR) { function_cache = pygi_constructor_cache_new (self->info); } else if (flags & GI_FUNCTION_IS_METHOD) { function_cache = pygi_method_cache_new (self->info); } else { function_cache = pygi_function_cache_new (self->info); } } else if (type == GI_INFO_TYPE_VFUNC) { function_cache = pygi_vfunc_cache_new (self->info); } else if (type == GI_INFO_TYPE_CALLBACK) { g_error ("Cannot invoke callback types"); } else { function_cache = pygi_method_cache_new (self->info); } self->cache = (PyGICallableCache *)function_cache; if (self->cache == NULL) return NULL; } return pygi_callable_info_invoke (self->info, py_args, kwargs, self->cache, NULL); }
static JSBool gjs_define_static_methods(JSContext *context, JSObject *constructor, GType gtype, GIStructInfo *boxed_info) { int i; int n_methods; n_methods = g_struct_info_get_n_methods(boxed_info); for (i = 0; i < n_methods; i++) { GIFunctionInfo *meth_info; GIFunctionInfoFlags flags; meth_info = g_struct_info_get_method (boxed_info, i); flags = g_function_info_get_flags (meth_info); /* Anything that isn't a method we put on the prototype of the * constructor. This includes <constructor> introspection * methods, as well as the forthcoming "static methods" * support. We may want to change this to use * GI_FUNCTION_IS_CONSTRUCTOR and GI_FUNCTION_IS_STATIC or the * like in the near future. */ if (!(flags & GI_FUNCTION_IS_METHOD)) { gjs_define_function(context, constructor, gtype, (GICallableInfo *)meth_info); } g_base_info_unref((GIBaseInfo*) meth_info); } return JS_TRUE; }
static VALUE rg_flags(VALUE self) { GIFunctionInfo *info; info = SELF(self); return GI_FUNCTION_INFO_FLAGS2RVAL(g_function_info_get_flags(info)); }
/* * The *resolved out parameter, on success, should be false to indicate that id * was not resolved; and true if id was resolved. */ static bool param_resolve(JSContext *context, JS::HandleObject obj, JS::HandleId id, bool *resolved) { GIObjectInfo *info = NULL; GIFunctionInfo *method_info; Param *priv; bool ret = false; priv = priv_from_js(context, obj); if (priv != NULL) { /* instance, not prototype */ *resolved = false; return true; } GjsAutoJSChar name; if (!gjs_get_string_id(context, id, &name)) { *resolved = false; return true; /* not resolved, but no error */ } info = (GIObjectInfo*)g_irepository_find_by_gtype(g_irepository_get_default(), G_TYPE_PARAM); method_info = g_object_info_find_method(info, name); if (method_info == NULL) { *resolved = false; ret = true; goto out; } #if GJS_VERBOSE_ENABLE_GI_USAGE _gjs_log_info_usage((GIBaseInfo*) method_info); #endif if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) { gjs_debug(GJS_DEBUG_GOBJECT, "Defining method %s in prototype for GObject.ParamSpec", g_base_info_get_name( (GIBaseInfo*) method_info)); if (gjs_define_function(context, obj, G_TYPE_PARAM, method_info) == NULL) { g_base_info_unref( (GIBaseInfo*) method_info); goto out; } *resolved = true; /* we defined the prop in obj */ } g_base_info_unref( (GIBaseInfo*) method_info); ret = true; out: if (info != NULL) g_base_info_unref( (GIBaseInfo*)info); return ret; }
/* * Set up prototype and constructor for structs. Same semantics as objects * except * for the type. */ static void seed_gi_importer_handle_struct(JSContextRef ctx, JSObjectRef namespace_ref, GIStructInfo* info, JSValueRef* exception) { JSObjectRef struct_ref; JSObjectRef proto; gint i, n_methods; GIFunctionInfo* finfo; struct_ref = JSObjectMake(ctx, seed_struct_constructor_class, info); g_base_info_ref(info); n_methods = g_struct_info_get_n_methods(info); for (i = 0; i < n_methods; i++) { GIFunctionInfoFlags flags; finfo = g_struct_info_get_method(info, i); flags = g_function_info_get_flags(finfo); if (flags & GI_FUNCTION_IS_CONSTRUCTOR) { JSObjectRef constructor = JSObjectMake(ctx, gobject_named_constructor_class, finfo); const gchar* fname = g_base_info_get_name((GIBaseInfo*) finfo); if (g_strrstr(fname, "new_") == fname) { // To be compatible with gjs, we need to have a method with // new_, too. seed_object_set_property(ctx, struct_ref, fname, constructor); fname += 4; } else if (!g_strcmp0(fname, "new")) { // To be compatible with gjs, we need to have new as function, // too. seed_object_set_property(ctx, struct_ref, fname, constructor); fname = "c_new"; } seed_object_set_property(ctx, struct_ref, fname, constructor); } else if (flags & GI_FUNCTION_IS_METHOD) g_base_info_unref((GIBaseInfo*) finfo); else seed_gobject_define_property_from_function_info(ctx, finfo, struct_ref, FALSE); } proto = seed_struct_prototype(ctx, (GIBaseInfo*) info); seed_object_set_property(ctx, struct_ref, "prototype", proto); seed_object_set_property(ctx, namespace_ref, g_base_info_get_name((GIBaseInfo*) info), struct_ref); }
/** * g_function_info_invoke: (skip) * @info: a #GIFunctionInfo describing the function to invoke * @in_args: an array of #GIArgument<!-- -->s, one for each in * parameter of @info. If there are no in parameter, @in_args * can be %NULL * @n_in_args: the length of the @in_args array * @out_args: an array of #GIArgument<!-- -->s, one for each out * parameter of @info. If there are no out parameters, @out_args * may be %NULL * @n_out_args: the length of the @out_args array * @return_value: return location for the return value of the * function. If the function returns void, @return_value may be * %NULL * @error: return location for detailed error information, or %NULL * * Invokes the function described in @info with the given * arguments. Note that inout parameters must appear in both * argument lists. This function uses dlsym() to obtain a pointer * to the function, so the library or shared object containing the * described function must either be linked to the caller, or must * have been g_module_symbol()<!-- -->ed before calling this function. * * Returns: %TRUE if the function has been invoked, %FALSE if an * error occurred. */ gboolean g_function_info_invoke (GIFunctionInfo *info, const GIArgument *in_args, int n_in_args, const GIArgument *out_args, int n_out_args, GIArgument *return_value, GError **error) { const gchar *symbol; gpointer func; gboolean is_method; gboolean throws; symbol = g_function_info_get_symbol (info); if (!g_typelib_symbol (g_base_info_get_typelib((GIBaseInfo *) info), symbol, &func)) { g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_SYMBOL_NOT_FOUND, "Could not locate %s: %s", symbol, g_module_error ()); return FALSE; } is_method = (g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0 && (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR) == 0; throws = g_function_info_get_flags (info) & GI_FUNCTION_THROWS; return g_callable_info_invoke ((GICallableInfo*) info, func, in_args, n_in_args, out_args, n_out_args, return_value, is_method, throws, error); }
static PyObject * _wrap_g_function_info_is_method (PyGIBaseInfo *self) { GIFunctionInfoFlags flags; gboolean is_method; flags = g_function_info_get_flags ( (GIFunctionInfo*) self->info); is_method = flags & GI_FUNCTION_IS_METHOD; return PyBool_FromLong (is_method); }
static PyObject * _wrap_g_function_info_is_constructor (PyGIBaseInfo *self) { GIFunctionInfoFlags flags; gboolean is_constructor; flags = g_function_info_get_flags ( (GIFunctionInfo*) self->info); is_constructor = flags & GI_FUNCTION_IS_CONSTRUCTOR; return PyBool_FromLong (is_constructor); }
static JSBool fundamental_instance_new_resolve_interface(JSContext *context, JS::HandleObject obj, JS::MutableHandleObject objp, Fundamental *proto_priv, char *name) { GIFunctionInfo *method_info; JSBool ret; GType *interfaces; guint n_interfaces; guint i; ret = JS_TRUE; interfaces = g_type_interfaces(proto_priv->gtype, &n_interfaces); for (i = 0; i < n_interfaces; i++) { GIBaseInfo *base_info; GIInterfaceInfo *iface_info; base_info = g_irepository_find_by_gtype(g_irepository_get_default(), interfaces[i]); if (base_info == NULL) continue; /* An interface GType ought to have interface introspection info */ g_assert(g_base_info_get_type(base_info) == GI_INFO_TYPE_INTERFACE); iface_info = (GIInterfaceInfo *) base_info; method_info = g_interface_info_find_method(iface_info, name); g_base_info_unref(base_info); if (method_info != NULL) { if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) { if (gjs_define_function(context, obj, proto_priv->gtype, (GICallableInfo *) method_info)) { objp.set(obj); } else { ret = JS_FALSE; } } g_base_info_unref((GIBaseInfo *) method_info); } } g_free(interfaces); return ret; }
static bool interface_new_resolve(JSContext *context, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleObject objp) { Interface *priv; char *name; bool ret = false; GIFunctionInfo *method_info; if (!gjs_get_string_id(context, id, &name)) return true; priv = priv_from_js(context, obj); if (priv == NULL) goto out; /* If we have no GIRepository information then this interface was defined * from within GJS. In that case, it has no properties that need to be * resolved from within C code, as interfaces cannot inherit. */ if (priv->info == NULL) { ret = true; goto out; } method_info = g_interface_info_find_method((GIInterfaceInfo*) priv->info, name); if (method_info != NULL) { if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) { if (gjs_define_function(context, obj, priv->gtype, (GICallableInfo*)method_info) == NULL) { g_base_info_unref((GIBaseInfo*)method_info); goto out; } objp.set(obj); } g_base_info_unref((GIBaseInfo*)method_info); } ret = true; out: g_free (name); return ret; }
static void* union_new(JSContext *context, JSObject *obj, /* "this" for constructor */ GIUnionInfo *info) { int n_methods; int i; /* Find a zero-args constructor and call it */ n_methods = g_union_info_get_n_methods(info); for (i = 0; i < n_methods; ++i) { GIFunctionInfo *func_info; GIFunctionInfoFlags flags; func_info = g_union_info_get_method(info, i); flags = g_function_info_get_flags(func_info); if ((flags & GI_FUNCTION_IS_CONSTRUCTOR) != 0 && g_callable_info_get_n_args((GICallableInfo*) func_info) == 0) { jsval rval; rval = JSVAL_NULL; gjs_invoke_c_function_uncached(context, func_info, obj, 0, NULL, &rval); g_base_info_unref((GIBaseInfo*) func_info); /* We are somewhat wasteful here; invoke_c_function() above * creates a JSObject wrapper for the union that we immediately * discard. */ if (JSVAL_IS_NULL(rval)) return NULL; else return gjs_c_union_from_union(context, JSVAL_TO_OBJECT(rval)); } g_base_info_unref((GIBaseInfo*) func_info); } gjs_throw(context, "Unable to construct union type %s since it has no zero-args <constructor>, can only wrap an existing one", g_base_info_get_name((GIBaseInfo*) info)); return NULL; }
static void boxed_fill_prototype_info(Boxed *priv) { int i, n_methods; int first_constructor = -1; priv->gtype = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) priv->info); priv->zero_args_constructor = -1; priv->default_constructor = -1; if (priv->gtype != G_TYPE_NONE) { /* If the structure is registered as a boxed, we can create a new instance by * looking for a zero-args constructor and calling it; constructors don't * really make sense for non-boxed types, since there is no memory management * for the return value. */ n_methods = g_struct_info_get_n_methods(priv->info); for (i = 0; i < n_methods; ++i) { GIFunctionInfo *func_info; GIFunctionInfoFlags flags; func_info = g_struct_info_get_method(priv->info, i); flags = g_function_info_get_flags(func_info); if ((flags & GI_FUNCTION_IS_CONSTRUCTOR) != 0) { if (first_constructor < 0) first_constructor = i; if (priv->zero_args_constructor < 0 && g_callable_info_get_n_args((GICallableInfo*) func_info) == 0) priv->zero_args_constructor = i; if (priv->default_constructor < 0 && strcmp(g_base_info_get_name ((GIBaseInfo*) func_info), "new") == 0) priv->default_constructor = i; } g_base_info_unref((GIBaseInfo*) func_info); } if (priv->default_constructor < 0) priv->default_constructor = priv->zero_args_constructor; if (priv->default_constructor < 0) priv->default_constructor = first_constructor; } }
int main(int argc, char **argv) { GIRepository *repo; GITypelib *ret; GIBaseInfo *info; GIArgument in_arg[1]; GIArgument ret_arg; GError *error; gboolean invoke_return; repo = g_irepository_get_default (); error = NULL; ret = g_irepository_require (repo, "GLib", NULL, 0, &error); g_assert (ret != NULL); g_assert (error == NULL); info = g_irepository_find_by_name (repo, "GLib", "file_read_link"); g_assert (info != NULL); g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION); g_assert (g_function_info_get_flags ((GIFunctionInfo *)info) & GI_FUNCTION_THROWS); in_arg[0].v_string = g_strdup ("non-existent-file/hope"); error = NULL; invoke_return = g_function_info_invoke ((GIFunctionInfo *)info, in_arg, 1, NULL, 0, &ret_arg, &error); g_free(in_arg[0].v_string); g_assert (invoke_return == FALSE); g_assert (error != NULL); g_assert (error->domain == G_FILE_ERROR); g_assert (error->code == G_FILE_ERROR_NOENT); exit(0); }
static void seed_gi_importer_handle_iface(JSContextRef ctx, JSObjectRef namespace_ref, GIObjectInfo* info, JSValueRef* exception) { GType type; type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo*) info); if (type != 0) { GIFunctionInfo* finfo; GIFunctionInfoFlags flags; JSObjectRef constructor_ref; guint i, n_methods; constructor_ref = JSObjectMake(ctx, gobject_constructor_class, (gpointer) type); seed_object_set_property(ctx, constructor_ref, "type", seed_value_from_long(ctx, type, exception)); n_methods = g_interface_info_get_n_methods(info); for (i = 0; i < n_methods; i++) { finfo = g_interface_info_get_method(info, i); flags = g_function_info_get_flags(finfo); if (!(flags & GI_FUNCTION_IS_METHOD)) { seed_gobject_define_property_from_function_info(ctx, finfo, constructor_ref, FALSE); } else { g_base_info_unref((GIBaseInfo*) finfo); } } seed_object_set_property(ctx, namespace_ref, g_base_info_get_name((GIBaseInfo*) info), constructor_ref); seed_object_set_property(ctx, constructor_ref, "prototype", seed_gobject_get_prototype_for_gtype(type)); } }
static void seed_gi_importer_handle_union(JSContextRef ctx, JSObjectRef namespace_ref, GIUnionInfo* info, JSValueRef* exception) { JSObjectRef union_ref; JSObjectRef proto; guint i, n_methods; GIFunctionInfo* finfo; union_ref = JSObjectMake(ctx, seed_struct_constructor_class, info); g_base_info_ref(info); n_methods = g_union_info_get_n_methods(info); for (i = 0; i < n_methods; i++) { GIFunctionInfoFlags flags; finfo = g_union_info_get_method(info, i); flags = g_function_info_get_flags(finfo); if (flags & GI_FUNCTION_IS_METHOD) g_base_info_unref((GIBaseInfo*) finfo); else seed_gobject_define_property_from_function_info(ctx, finfo, union_ref, FALSE); } proto = seed_union_prototype(ctx, (GIBaseInfo*) info); seed_object_set_property(ctx, union_ref, "prototype", proto); seed_object_set_property(ctx, namespace_ref, g_base_info_get_name((GIBaseInfo*) info), union_ref); }
/* * Like JSResolveOp, but flags provide contextual information as follows: * * JSRESOLVE_QUALIFIED a qualified property id: obj.id or obj[id], not id * JSRESOLVE_ASSIGNING obj[id] is on the left-hand side of an assignment * JSRESOLVE_DETECTING 'if (o.p)...' or similar detection opcode sequence * JSRESOLVE_DECLARING var, const, or boxed prolog declaration opcode * JSRESOLVE_CLASSNAME class name used when constructing * * The *objp out parameter, on success, should be null to indicate that id * was not resolved; and non-null, referring to obj or one of its prototypes, * if id was resolved. */ static JSBool union_new_resolve(JSContext *context, JS::HandleObject obj, JS::HandleId id, unsigned flags, JS::MutableHandleObject objp) { Union *priv; char *name; JSBool ret = JS_TRUE; if (!gjs_get_string_id(context, id, &name)) return JS_TRUE; /* not resolved, but no error */ priv = priv_from_js(context, obj); gjs_debug_jsprop(GJS_DEBUG_GBOXED, "Resolve prop '%s' hook obj %p priv %p", name, *obj, priv); if (priv == NULL) { ret = JS_FALSE; /* wrong class */ goto out; } if (priv->gboxed == NULL) { /* We are the prototype, so look for methods and other class properties */ GIFunctionInfo *method_info; method_info = g_union_info_find_method((GIUnionInfo*) priv->info, name); if (method_info != NULL) { JSObject *union_proto; const char *method_name; #if GJS_VERBOSE_ENABLE_GI_USAGE _gjs_log_info_usage((GIBaseInfo*) method_info); #endif if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) { method_name = g_base_info_get_name( (GIBaseInfo*) method_info); gjs_debug(GJS_DEBUG_GBOXED, "Defining method %s in prototype for %s.%s", method_name, g_base_info_get_namespace( (GIBaseInfo*) priv->info), g_base_info_get_name( (GIBaseInfo*) priv->info)); union_proto = obj; if (gjs_define_function(context, union_proto, g_registered_type_info_get_g_type(priv->info), method_info) == NULL) { g_base_info_unref( (GIBaseInfo*) method_info); ret = JS_FALSE; goto out; } objp.set(union_proto); /* we defined the prop in object_proto */ } g_base_info_unref( (GIBaseInfo*) method_info); } } else { /* We are an instance, not a prototype, so look for * per-instance props that we want to define on the * JSObject. Generally we do not want to cache these in JS, we * want to always pull them from the C object, or JS would not * see any changes made from C. So we use the get/set prop * hooks, not this resolve hook. */ } out: g_free(name); return ret; }
/** * g_function_info_prep_invoker: * @info: A #GIFunctionInfo * @invoker: Output invoker structure * @error: A #GError * * Initialize the caller-allocated @invoker structure with a cache * of information needed to invoke the C function corresponding to * @info with the platform's default ABI. * * A primary intent of this function is that a dynamic structure allocated * by a language binding could contain a #GIFunctionInvoker structure * inside the binding's function mapping. * * Returns: %TRUE on success, %FALSE otherwise with @error set. */ gboolean g_function_info_prep_invoker (GIFunctionInfo *info, GIFunctionInvoker *invoker, GError **error) { const char *symbol; ffi_type *rtype; ffi_type **atypes; GITypeInfo *tinfo; GIArgInfo *ainfo; gboolean is_method; gboolean throws; gint n_args, n_invoke_args, i; g_return_val_if_fail (info != NULL, FALSE); g_return_val_if_fail (invoker != NULL, FALSE); symbol = g_function_info_get_symbol ((GIFunctionInfo*) info); if (!g_typelib_symbol (g_base_info_get_typelib((GIBaseInfo *) info), symbol, &(invoker->native_address))) { g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_SYMBOL_NOT_FOUND, "Could not locate %s: %s", symbol, g_module_error ()); return FALSE; } is_method = (g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0 && (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR) == 0; throws = g_function_info_get_flags (info) & GI_FUNCTION_THROWS; tinfo = g_callable_info_get_return_type ((GICallableInfo *)info); rtype = g_type_info_get_ffi_type (tinfo); g_base_info_unref ((GIBaseInfo *)tinfo); n_args = g_callable_info_get_n_args ((GICallableInfo *)info); if (is_method) n_invoke_args = n_args+1; else n_invoke_args = n_args; if (throws) /* Add an argument for the GError */ n_invoke_args ++; /* TODO: avoid malloc here? */ atypes = g_malloc0 (sizeof (ffi_type*) * n_invoke_args); if (is_method) { atypes[0] = &ffi_type_pointer; } for (i = 0; i < n_args; i++) { int offset = (is_method ? 1 : 0); ainfo = g_callable_info_get_arg ((GICallableInfo *)info, i); switch (g_arg_info_get_direction (ainfo)) { case GI_DIRECTION_IN: tinfo = g_arg_info_get_type (ainfo); atypes[i+offset] = g_type_info_get_ffi_type (tinfo); g_base_info_unref ((GIBaseInfo *)tinfo); break; case GI_DIRECTION_OUT: case GI_DIRECTION_INOUT: atypes[i+offset] = &ffi_type_pointer; break; default: g_assert_not_reached (); } g_base_info_unref ((GIBaseInfo *)ainfo); } if (throws) { atypes[n_invoke_args - 1] = &ffi_type_pointer; } return ffi_prep_cif (&(invoker->cif), FFI_DEFAULT_ABI, n_invoke_args, rtype, atypes) == FFI_OK; }
/* * Like JSResolveOp, but flags provide contextual information as follows: * * JSRESOLVE_QUALIFIED a qualified property id: obj.id or obj[id], not id * JSRESOLVE_ASSIGNING obj[id] is on the left-hand side of an assignment * JSRESOLVE_DETECTING 'if (o.p)...' or similar detection opcode sequence * JSRESOLVE_DECLARING var, const, or fundamental prolog declaration opcode * JSRESOLVE_CLASSNAME class name used when constructing * * The *objp out parameter, on success, should be null to indicate that id * was not resolved; and non-null, referring to obj or one of its prototypes, * if id was resolved. */ static JSBool fundamental_instance_new_resolve(JSContext *context, JS::HandleObject obj, JS::HandleId id, unsigned flags, JS::MutableHandleObject objp) { FundamentalInstance *priv; char *name; JSBool ret = JS_FALSE; if (!gjs_get_string_id(context, id, &name)) return JS_TRUE; /* not resolved, but no error */ priv = priv_from_js(context, obj); gjs_debug_jsprop(GJS_DEBUG_GFUNDAMENTAL, "Resolve prop '%s' hook obj %p priv %p", name, *obj, priv); if (priv == NULL) goto out; /* wrong class */ if (priv->prototype == NULL) { /* We are the prototype, so look for methods and other class properties */ Fundamental *proto_priv = (Fundamental *) priv; GIFunctionInfo *method_info; method_info = g_object_info_find_method((GIStructInfo*) proto_priv->info, name); if (method_info != NULL) { const char *method_name; #if GJS_VERBOSE_ENABLE_GI_USAGE _gjs_log_info_usage((GIBaseInfo *) method_info); #endif if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) { method_name = g_base_info_get_name((GIBaseInfo *) method_info); /* we do not define deprecated methods in the prototype */ if (g_base_info_is_deprecated((GIBaseInfo *) method_info)) { gjs_debug(GJS_DEBUG_GFUNDAMENTAL, "Ignoring definition of deprecated method %s in prototype %s.%s", method_name, g_base_info_get_namespace((GIBaseInfo *) proto_priv->info), g_base_info_get_name((GIBaseInfo *) proto_priv->info)); g_base_info_unref((GIBaseInfo *) method_info); ret = JS_TRUE; goto out; } gjs_debug(GJS_DEBUG_GFUNDAMENTAL, "Defining method %s in prototype for %s.%s", method_name, g_base_info_get_namespace((GIBaseInfo *) proto_priv->info), g_base_info_get_name((GIBaseInfo *) proto_priv->info)); if (gjs_define_function(context, obj, proto_priv->gtype, method_info) == NULL) { g_base_info_unref((GIBaseInfo *) method_info); goto out; } objp.set(obj); } g_base_info_unref((GIBaseInfo *) method_info); } ret = fundamental_instance_new_resolve_interface(context, obj, objp, proto_priv, name); } else { /* We are an instance, not a prototype, so look for * per-instance props that we want to define on the * JSObject. Generally we do not want to cache these in JS, we * want to always pull them from the C object, or JS would not * see any changes made from C. So we use the get/set prop * hooks, not this resolve hook. */ } ret = JS_TRUE; out: g_free(name); return ret; }
/* * Handle setting up the prototype and constructor for a GObject type * Namespace.Type will be the constructor and Namespace.Type.prototype is * the prototype object. Namespace.Type.type will be the GType. */ static void seed_gi_importer_handle_object(JSContextRef ctx, JSObjectRef namespace_ref, GIObjectInfo* info, JSValueRef* exception) { GType type; JSClassRef class_ref; type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo*) info); if (type != 0) { GIFunctionInfo* finfo; GIFunctionInfoFlags flags; JSObjectRef constructor_ref; guint i, n_methods; class_ref = seed_gobject_get_class_for_gtype(ctx, type); constructor_ref = JSObjectMake(ctx, gobject_constructor_class, (gpointer) type); seed_object_set_property(ctx, constructor_ref, "type", seed_value_from_long(ctx, type, exception)); n_methods = g_object_info_get_n_methods(info); for (i = 0; i < n_methods; i++) { finfo = g_object_info_get_method(info, i); flags = g_function_info_get_flags(finfo); if (flags & GI_FUNCTION_IS_CONSTRUCTOR) { JSObjectRef constructor = JSObjectMake(ctx, gobject_named_constructor_class, finfo); const gchar* fname = g_base_info_get_name((GIBaseInfo*) finfo); if (g_strrstr(fname, "new_") == fname) { // To be compatible with gjs, we need to have a method with // new_, too. seed_object_set_property(ctx, constructor_ref, fname, constructor); fname += 4; } else if (!g_strcmp0(fname, "new")) { // To be compatible with gjs, we need to have new as // function, too. seed_object_set_property(ctx, constructor_ref, fname, constructor); fname = "c_new"; } seed_object_set_property(ctx, constructor_ref, fname, constructor); } else if (!(flags & GI_FUNCTION_IS_METHOD)) { seed_gobject_define_property_from_function_info(ctx, finfo, constructor_ref, FALSE); } else { g_base_info_unref((GIBaseInfo*) finfo); } } seed_object_set_property(ctx, namespace_ref, g_base_info_get_name((GIBaseInfo*) info), constructor_ref); seed_object_set_property(ctx, constructor_ref, "prototype", seed_gobject_get_prototype_for_gtype(type)); } }