static void * _get_func(GIObjectInfo *info, SymbolGetter getter) { const char* symbol; GSList *parents = NULL, *l; GIObjectInfo *parent_info; gpointer func = NULL; parent_info = g_base_info_ref (info); while (parent_info != NULL) { parents = g_slist_prepend (parents, parent_info); parent_info = g_object_info_get_parent (parent_info); } for (l = parents; l; l = l->next) { parent_info = l->data; symbol = getter (parent_info); if (symbol == NULL) continue; g_typelib_symbol (((GIRealInfo *)parent_info)->typelib, symbol, (gpointer*) &func); if (func) break; } g_slist_free_full (parents, (GDestroyNotify) g_base_info_unref); return func; }
static GIBaseInfo * struct_get_info (PyTypeObject *type) { PyObject *py_info; GIBaseInfo *info = NULL; py_info = PyObject_GetAttrString ((PyObject *)type, "__info__"); if (py_info == NULL) { return NULL; } if (!PyObject_TypeCheck (py_info, &PyGIStructInfo_Type) && !PyObject_TypeCheck (py_info, &PyGIUnionInfo_Type)) { PyErr_Format (PyExc_TypeError, "attribute '__info__' must be %s or %s, not %s", PyGIStructInfo_Type.tp_name, PyGIUnionInfo_Type.tp_name, Py_TYPE(py_info)->tp_name); goto out; } info = ( (PyGIBaseInfo *) py_info)->info; g_base_info_ref (info); out: Py_DECREF (py_info); return info; }
GIBaseInfo * _pygi_object_get_gi_info (PyObject *object, PyTypeObject *type) { PyObject *py_info; GIBaseInfo *info = NULL; py_info = PyObject_GetAttrString (object, "__info__"); if (py_info == NULL) { return NULL; } if (!PyObject_TypeCheck (py_info, type)) { PyErr_Format (PyExc_TypeError, "attribute '__info__' must be %s, not %s", type->tp_name, Py_TYPE(&py_info)->tp_name); goto out; } info = ( (PyGIBaseInfo *) py_info)->info; g_base_info_ref (info); out: Py_DECREF (py_info); return info; }
PyGICClosure* _pygi_make_native_closure (GICallableInfo* info, GIArgInfo* arg_info, PyObject *py_function, gpointer py_user_data) { PyGICClosure *closure; ffi_closure *fficlosure; /* Begin by cleaning up old async functions */ g_slist_foreach(async_free_list, (GFunc)_pygi_invoke_closure_free, NULL); g_slist_free(async_free_list); async_free_list = NULL; /* Build the closure itself */ closure = g_slice_new0(PyGICClosure); closure->info = (GICallableInfo *) g_base_info_ref ((GIBaseInfo *) info); closure->function = py_function; closure->user_data = py_user_data; Py_INCREF(py_function); if (closure->user_data) Py_INCREF(closure->user_data); fficlosure = g_callable_info_prepare_closure (info, &closure->cif, _pygi_closure_handle, closure); closure->closure = fficlosure; /* Give the closure the information it needs to determine when to free itself later */ closure->scope = g_arg_info_get_scope(arg_info); return closure; }
static GPerlI11nPerlCallbackInfo * create_perl_callback_closure (GICallableInfo *cb_info, SV *code) { GPerlI11nPerlCallbackInfo *info; info = g_new0 (GPerlI11nPerlCallbackInfo, 1); if (!gperl_sv_is_defined (code)) return info; info->interface = g_base_info_ref (cb_info); info->cif = g_new0 (ffi_cif, 1); info->closure = g_callable_info_prepare_closure (info->interface, info->cif, invoke_perl_code, info); /* FIXME: This should most likely use SvREFCNT_inc instead of * newSVsv. */ info->code = newSVsv (code); info->sub_name = NULL; /* These are only relevant for signal marshalling; if needed, they get * set in invoke_perl_signal_handler. */ info->swap_data = FALSE; info->args_converter = NULL; #ifdef PERL_IMPLICIT_CONTEXT info->priv = aTHX; #endif return info; }
PyObject * _pygi_ccallback_new (GCallback callback, gpointer user_data, GIScopeType scope, GIFunctionInfo *info, GDestroyNotify destroy_notify) { PyGICCallback *self; if (!callback) { Py_RETURN_NONE; } self = (PyGICCallback *) PyGICCallback_Type.tp_alloc (&PyGICCallback_Type, 0); if (self == NULL) { return NULL; } self->callback = (GCallback) callback; self->user_data = user_data; self->scope = scope; self->destroy_notify_func = destroy_notify; self->info = g_base_info_ref( (GIBaseInfo *) info); return (PyObject *) self; }
JSObject* gjs_boxed_from_c_struct(JSContext *context, GIStructInfo *info, void *gboxed, GjsBoxedCreationFlags flags) { JSObject *obj; JSObject *proto; Boxed *priv; Boxed *proto_priv; if (gboxed == NULL) return NULL; gjs_debug_marshal(GJS_DEBUG_GBOXED, "Wrapping struct %s %p with JSObject", g_base_info_get_name((GIBaseInfo *)info), gboxed); proto = gjs_lookup_boxed_prototype(context, info); proto_priv = priv_from_js(context, proto); obj = JS_NewObjectWithGivenProto(context, JS_GET_CLASS(context, proto), proto, gjs_get_import_global (context)); GJS_INC_COUNTER(boxed); priv = g_slice_new0(Boxed); *priv = *proto_priv; g_base_info_ref( (GIBaseInfo*) priv->info); JS_SetPrivate(context, obj, priv); if ((flags & GJS_BOXED_CREATION_NO_COPY) != 0) { /* we need to create a JS Boxed which references the * original C struct, not a copy of it. Used for * G_SIGNAL_TYPE_STATIC_SCOPE */ priv->gboxed = gboxed; priv->not_owning_gboxed = TRUE; } else { if (priv->gtype != G_TYPE_NONE && g_type_is_a (priv->gtype, G_TYPE_BOXED)) { priv->gboxed = g_boxed_copy(priv->gtype, gboxed); } else if (priv->gtype == G_TYPE_VARIANT) { priv->gboxed = g_variant_ref_sink (gboxed); } else if (priv->can_allocate_directly) { boxed_new_direct(priv); memcpy(priv->gboxed, gboxed, g_struct_info_get_size (priv->info)); } else { gjs_throw(context, "Can't create a Javascript object for %s; no way to copy", g_base_info_get_name( (GIBaseInfo*) priv->info)); } } return obj; }
void gjs_define_error_class(JSContext *context, JSObject *in_object, GIEnumInfo *info) { const char *constructor_name; GIBoxedInfo *glib_error_info; JSObject *prototype, *parent_proto; JSObject *constructor; Error *priv; /* See the comment in gjs_define_boxed_class() for an * explanation of how this all works; Error is pretty much the * same as Boxed (except that we inherit from GLib.Error). */ constructor_name = g_base_info_get_name( (GIBaseInfo*) info); g_irepository_require(NULL, "GLib", "2.0", (GIRepositoryLoadFlags) 0, NULL); glib_error_info = (GIBoxedInfo*) g_irepository_find_by_name(NULL, "GLib", "Error"); parent_proto = gjs_lookup_generic_prototype(context, glib_error_info); g_base_info_unref((GIBaseInfo*)glib_error_info); if (!gjs_init_class_dynamic(context, in_object, parent_proto, g_base_info_get_namespace( (GIBaseInfo*) info), constructor_name, &gjs_error_class, gjs_error_constructor, 1, /* props of prototype */ &gjs_error_proto_props[0], /* funcs of prototype */ &gjs_error_proto_funcs[0], /* props of constructor, MyConstructor.myprop */ NULL, /* funcs of constructor, MyConstructor.myfunc() */ &gjs_error_constructor_funcs[0], &prototype, &constructor)) { gjs_log_exception(context); g_error("Can't init class %s", constructor_name); } GJS_INC_COUNTER(gerror); priv = g_slice_new0(Error); priv->info = info; g_base_info_ref( (GIBaseInfo*) priv->info); priv->domain = g_quark_from_string (g_enum_info_get_error_domain(priv->info)); JS_SetPrivate(prototype, priv); gjs_debug(GJS_DEBUG_GBOXED, "Defined class %s prototype is %p class %p in object %p", constructor_name, prototype, JS_GetClass(prototype), in_object); gjs_define_enum_values(context, constructor, priv->info); gjs_define_enum_static_methods(context, constructor, priv->info); }
static JSBool get_nested_interface_object (JSContext *context, JSObject *parent_obj, Boxed *parent_priv, GIFieldInfo *field_info, GITypeInfo *type_info, GIBaseInfo *interface_info, jsval *value) { JSObject *obj; JSObject *proto; int offset; Boxed *priv; Boxed *proto_priv; if (!struct_is_simple ((GIStructInfo *)interface_info)) { gjs_throw(context, "Reading field %s.%s is not supported", g_base_info_get_name ((GIBaseInfo *)parent_priv->info), g_base_info_get_name ((GIBaseInfo *)field_info)); return JS_FALSE; } proto = gjs_lookup_boxed_prototype(context, (GIBoxedInfo*) interface_info); proto_priv = priv_from_js(context, proto); offset = g_field_info_get_offset (field_info); obj = JS_NewObjectWithGivenProto(context, JS_GET_CLASS(context, proto), proto, gjs_get_import_global (context)); if (obj == NULL) return JS_FALSE; GJS_INC_COUNTER(boxed); priv = g_slice_new0(Boxed); JS_SetPrivate(context, obj, priv); priv->info = (GIBoxedInfo*) interface_info; g_base_info_ref( (GIBaseInfo*) priv->info); priv->gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo*) interface_info); priv->can_allocate_directly = proto_priv->can_allocate_directly; /* A structure nested inside a parent object; doesn't have an independent allocation */ priv->gboxed = ((char *)parent_priv->gboxed) + offset; priv->not_owning_gboxed = TRUE; /* We never actually read the reserved slot, but we put the parent object * into it to hold onto the parent object. */ JS_SetReservedSlot(context, obj, 0, OBJECT_TO_JSVAL (parent_obj)); *value = OBJECT_TO_JSVAL(obj); return JS_TRUE; }
/* * 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); }
JSObject* gjs_error_from_gerror(JSContext *context, GError *gerror, gboolean add_stack) { JSObject *obj; JSObject *proto; Error *priv; Error *proto_priv; GIEnumInfo *info; if (gerror == NULL) return NULL; info = find_error_domain_info(gerror->domain); if (!info) { /* We don't have error domain metadata */ /* Marshal the error as a plain GError */ GIBaseInfo *glib_boxed; JSObject *retval; glib_boxed = g_irepository_find_by_name(NULL, "GLib", "Error"); retval = gjs_boxed_from_c_struct(context, glib_boxed, gerror, 0); g_base_info_unref(glib_boxed); return retval; } gjs_debug_marshal(GJS_DEBUG_GBOXED, "Wrapping struct %s %p with JSObject", g_base_info_get_name((GIBaseInfo *)info), gboxed); proto = gjs_lookup_error_prototype(context, info); proto_priv = priv_from_js(context, proto); obj = JS_NewObjectWithGivenProto(context, JS_GET_CLASS(context, proto), proto, gjs_get_import_global (context)); GJS_INC_COUNTER(gerror); priv = g_slice_new0(Error); JS_SetPrivate(context, obj, priv); priv->info = info; priv->domain = proto_priv->domain; g_base_info_ref( (GIBaseInfo*) priv->info); priv->gerror = g_error_copy(gerror); if (add_stack) define_error_properties(context, obj); return obj; }
bool gjs_define_interface_class(JSContext *context, JS::HandleObject in_object, GIInterfaceInfo *info, GType gtype, JS::MutableHandleObject constructor) { Interface *priv; const char *constructor_name; const char *ns; JS::RootedObject prototype(context); ns = gjs_get_names_from_gtype_and_gi_info(gtype, (GIBaseInfo *) info, &constructor_name); if (!gjs_init_class_dynamic(context, in_object, JS::NullPtr(), ns, constructor_name, &gjs_interface_class, gjs_interface_constructor, 0, /* props of prototype */ &gjs_interface_proto_props[0], /* funcs of prototype */ &gjs_interface_proto_funcs[0], /* props of constructor, MyConstructor.myprop */ NULL, /* funcs of constructor, MyConstructor.myfunc() */ NULL, &prototype, constructor)) { g_error("Can't init class %s", constructor_name); } GJS_INC_COUNTER(interface); priv = g_slice_new0(Interface); priv->info = info == NULL ? NULL : g_base_info_ref((GIBaseInfo *) info); priv->gtype = gtype; priv->vtable = (GTypeInterface *) g_type_default_interface_ref(gtype); JS_SetPrivate(prototype, priv); /* If we have no GIRepository information, then this interface was defined * from within GJS and therefore has no C static methods to be defined. */ if (priv->info) gjs_define_static_methods(context, constructor, priv->gtype, priv->info); JS::RootedObject gtype_obj(context, gjs_gtype_create_gtype_wrapper(context, priv->gtype)); JS_DefineProperty(context, constructor, "$gtype", gtype_obj, JSPROP_PERMANENT); return true; }
static GPerlI11nCCallbackInfo * create_c_callback_closure (GIBaseInfo *interface, gpointer func) { GPerlI11nCCallbackInfo *info; info = g_new0 (GPerlI11nCCallbackInfo, 1); if (!func) return info; info->interface = interface; g_base_info_ref (interface); info->func = func; return info; }
static void seed_gi_importer_handle_function(JSContextRef ctx, JSObjectRef namespace_ref, GIFunctionInfo* info, JSValueRef* exception) { if (!seed_gi_importer_is_init(info)) seed_gobject_define_property_from_function_info(ctx, (GIFunctionInfo*) info, namespace_ref, FALSE); else { JSObjectRef init_method; init_method = JSObjectMake(ctx, gobject_init_method_class, g_base_info_ref((GIBaseInfo*) info)); seed_object_set_property(ctx, namespace_ref, "init", init_method); } }
/* assumes ownership of sub_name */ static GPerlI11nPerlCallbackInfo * create_perl_callback_closure_for_named_sub (GICallableInfo *cb_info, gchar *sub_name) { GPerlI11nPerlCallbackInfo *info; info = g_new0 (GPerlI11nPerlCallbackInfo, 1); info->interface = g_base_info_ref (cb_info); info->cif = g_new0 (ffi_cif, 1); info->closure = g_callable_info_prepare_closure (info->interface, info->cif, invoke_perl_code, info); info->sub_name = sub_name; info->code = NULL; info->data = NULL; #ifdef PERL_IMPLICIT_CONTEXT info->priv = aTHX; #endif return info; }
/** * g_object_info_find_vfunc_using_interfaces: * @info: a #GIObjectInfo * @name: name of method to obtain * @implementor: (out) (transfer full): The implementor of the interface * * Locate a virtual function slot with name @name, searching both the object * @info and any interfaces it implements. Note that the namespace for * virtuals is distinct from that of methods; there may or may not be a * concrete method associated for a virtual. If there is one, it may be * retrieved using g_vfunc_info_get_invoker(), otherwise %NULL will be * returned. * * Note that this function does *not* search parent classes; you will have * to chain up if that's desired. * * Returns: (transfer full): the #GIFunctionInfo. Free the struct by calling * g_base_info_unref() when done. */ GIVFuncInfo * g_object_info_find_vfunc_using_interfaces (GIObjectInfo *info, const gchar *name, GIObjectInfo **implementor) { GIVFuncInfo *result = NULL; GIObjectInfo *implementor_result = NULL; result = g_object_info_find_vfunc (info, name); if (result) implementor_result = g_base_info_ref ((GIBaseInfo*) info); if (result == NULL) { int n_interfaces; int i; n_interfaces = g_object_info_get_n_interfaces (info); for (i = 0; i < n_interfaces; ++i) { GIInterfaceInfo *iface_info; iface_info = g_object_info_get_interface (info, i); result = g_interface_info_find_vfunc (iface_info, name); if (result != NULL) { implementor_result = iface_info; break; } g_base_info_unref ((GIBaseInfo*) iface_info); } } if (implementor) *implementor = implementor_result; else if (implementor_result != NULL) g_base_info_unref ((GIBaseInfo*) implementor_result); return result; }
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); }
JSBool gjs_define_fundamental_class(JSContext *context, JSObject *in_object, GIObjectInfo *info, JSObject **constructor_p, JSObject **prototype_p) { const char *constructor_name; JSObject *prototype; jsval value; jsid js_constructor_name = JSID_VOID; JSObject *parent_proto; Fundamental *priv; JSObject *constructor; GType parent_gtype; GType gtype; GIFunctionInfo *constructor_info; /* See the comment in gjs_define_object_class() for an explanation * of how this all works; Fundamental is pretty much the same as * Object. */ constructor_name = g_base_info_get_name((GIBaseInfo *) info); constructor_info = find_fundamental_constructor(context, info, &js_constructor_name); gtype = g_registered_type_info_get_g_type (info); parent_gtype = g_type_parent(gtype); parent_proto = NULL; if (parent_gtype != G_TYPE_INVALID) parent_proto = gjs_lookup_fundamental_prototype_from_gtype(context, parent_gtype); if (!gjs_init_class_dynamic(context, in_object, /* parent prototype JSObject* for * prototype; NULL for * Object.prototype */ parent_proto, g_base_info_get_namespace((GIBaseInfo *) info), constructor_name, &gjs_fundamental_instance_class, gjs_fundamental_instance_constructor, /* number of constructor args (less can be passed) */ constructor_info != NULL ? g_callable_info_get_n_args((GICallableInfo *) constructor_info) : 0, /* props of prototype */ parent_proto ? NULL : &gjs_fundamental_instance_proto_props[0], /* funcs of prototype */ parent_proto ? NULL : &gjs_fundamental_instance_proto_funcs[0], /* props of constructor, MyConstructor.myprop */ NULL, /* funcs of constructor, MyConstructor.myfunc() */ NULL, &prototype, &constructor)) { gjs_log_exception(context); g_error("Can't init class %s", constructor_name); } /* Put the info in the prototype */ priv = g_slice_new0(Fundamental); g_assert(priv != NULL); g_assert(priv->info == NULL); priv->info = g_base_info_ref((GIBaseInfo *) info); priv->gtype = gtype; priv->constructor_name = js_constructor_name; priv->constructor_info = constructor_info; priv->ref_function = g_object_info_get_ref_function_pointer(info); g_assert(priv->ref_function != NULL); priv->unref_function = g_object_info_get_unref_function_pointer(info); g_assert(priv->unref_function != NULL); priv->set_value_function = g_object_info_get_set_value_function_pointer(info); g_assert(priv->set_value_function != NULL); priv->get_value_function = g_object_info_get_get_value_function_pointer(info); g_assert(priv->get_value_function != NULL); JS_SetPrivate(prototype, priv); gjs_debug(GJS_DEBUG_GFUNDAMENTAL, "Defined class %s prototype is %p class %p in object %p constructor %s.%s.%s", constructor_name, prototype, JS_GetClass(prototype), in_object, constructor_info != NULL ? g_base_info_get_namespace(constructor_info) : "unknown", constructor_info != NULL ? g_base_info_get_name(g_base_info_get_container(constructor_info)) : "unknown", constructor_info != NULL ? g_base_info_get_name(constructor_info) : "unknown"); if (g_object_info_get_n_fields(priv->info) > 0) { gjs_debug(GJS_DEBUG_GFUNDAMENTAL, "Fundamental type '%s.%s' apparently has accessible fields. " "Gjs has no support for this yet, ignoring these.", g_base_info_get_namespace((GIBaseInfo *)priv->info), g_base_info_get_name ((GIBaseInfo *)priv->info)); } gjs_object_define_static_methods(context, constructor, gtype, info); value = OBJECT_TO_JSVAL(gjs_gtype_create_gtype_wrapper(context, gtype)); JS_DefineProperty(context, constructor, "$gtype", value, NULL, NULL, JSPROP_PERMANENT); if (constructor_p) *constructor_p = constructor; if (prototype_p) *prototype_p = prototype; return JS_TRUE; }
JSBool gjs_define_error_class(JSContext *context, JSObject *in_object, GIEnumInfo *info, JSObject **constructor_p, JSObject **prototype_p) { const char *constructor_name; GIBoxedInfo *glib_error_info; JSObject *prototype, *parent_proto; JSObject *constructor; jsval value; Error *priv; /* See the comment in gjs_define_boxed_class() for an * explanation of how this all works; Error is pretty much the * same as Boxed (except that we inherit from GLib.Error). */ constructor_name = g_base_info_get_name( (GIBaseInfo*) info); if (gjs_object_get_property(context, in_object, constructor_name, &value)) { JSObject *constructor; if (!JSVAL_IS_OBJECT(value)) { gjs_throw(context, "Existing property '%s' does not look like a constructor", constructor_name); return JS_FALSE; } constructor = JSVAL_TO_OBJECT(value); gjs_object_get_property(context, constructor, "prototype", &value); if (!JSVAL_IS_OBJECT(value)) { gjs_throw(context, "error %s prototype property does not appear to exist or has wrong type", constructor_name); return JS_FALSE; } else { if (prototype_p) *prototype_p = JSVAL_TO_OBJECT(value); if (constructor_p) *constructor_p = constructor; return JS_TRUE; } } g_irepository_require(NULL, "GLib", "2.0", 0, NULL); glib_error_info = (GIBoxedInfo*) g_irepository_find_by_name(NULL, "GLib", "Error"); parent_proto = gjs_lookup_boxed_prototype(context, glib_error_info); g_base_info_unref((GIBaseInfo*)glib_error_info); prototype = gjs_init_class_dynamic(context, in_object, parent_proto, g_base_info_get_namespace( (GIBaseInfo*) info), constructor_name, &gjs_error_class, gjs_error_constructor, /* number of constructor args (less can be passed) */ 1, /* props of prototype */ &gjs_error_proto_props[0], /* funcs of prototype */ &gjs_error_proto_funcs[0], /* props of constructor, MyConstructor.myprop */ NULL, /* funcs of constructor, MyConstructor.myfunc() */ &gjs_error_constructor_funcs[0]); if (prototype == NULL) { gjs_log_exception(context, NULL); gjs_fatal("Can't init class %s", constructor_name); } g_assert(gjs_object_has_property(context, in_object, constructor_name)); GJS_INC_COUNTER(gerror); priv = g_slice_new0(Error); priv->info = info; g_base_info_ref( (GIBaseInfo*) priv->info); priv->domain = g_quark_from_string (g_enum_info_get_error_domain(priv->info)); JS_SetPrivate(context, prototype, priv); gjs_debug(GJS_DEBUG_GBOXED, "Defined class %s prototype is %p class %p in object %p", constructor_name, prototype, JS_GET_CLASS(context, prototype), in_object); constructor = NULL; gjs_object_get_property(context, in_object, constructor_name, &value); if (!JSVAL_IS_VOID(value)) { if (!JSVAL_IS_OBJECT(value)) { gjs_throw(context, "Property '%s' does not look like a constructor", constructor_name); return JS_FALSE; } } constructor = JSVAL_TO_OBJECT(value); gjs_define_enum_values(context, constructor, priv->info); if (constructor_p) *constructor_p = constructor; if (prototype_p) *prototype_p = prototype; return JS_TRUE; }
static gboolean pygi_arg_callback_setup_from_info (PyGICallbackCache *arg_cache, GITypeInfo *type_info, GIArgInfo *arg_info, /* may be null */ GITransfer transfer, PyGIDirection direction, GIInterfaceInfo *iface_info, PyGICallableCache *callable_cache) { PyGIArgCache *cache = (PyGIArgCache *)arg_cache; gssize child_offset = 0; if (!pygi_arg_base_setup ((PyGIArgCache *)arg_cache, type_info, arg_info, transfer, direction)) { return FALSE; } if (callable_cache != NULL) child_offset = callable_cache->args_offset; ( (PyGIArgCache *)arg_cache)->destroy_notify = (GDestroyNotify)_callback_cache_free_func; arg_cache->user_data_index = g_arg_info_get_closure (arg_info); if (arg_cache->user_data_index != -1) arg_cache->user_data_index += child_offset; arg_cache->destroy_notify_index = g_arg_info_get_destroy (arg_info); if (arg_cache->destroy_notify_index != -1) arg_cache->destroy_notify_index += child_offset; if (arg_cache->user_data_index >= 0) { PyGIArgCache *user_data_arg_cache = pygi_arg_cache_alloc (); user_data_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD_WITH_PYARG; user_data_arg_cache->direction = direction; user_data_arg_cache->has_default = TRUE; /* always allow user data with a NULL default. */ _pygi_callable_cache_set_arg (callable_cache, arg_cache->user_data_index, user_data_arg_cache); } if (arg_cache->destroy_notify_index >= 0) { PyGIArgCache *destroy_arg_cache = pygi_arg_cache_alloc (); destroy_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD; destroy_arg_cache->direction = direction; _pygi_callable_cache_set_arg (callable_cache, arg_cache->destroy_notify_index, destroy_arg_cache); } arg_cache->scope = g_arg_info_get_scope (arg_info); g_base_info_ref( (GIBaseInfo *)iface_info); arg_cache->interface_info = iface_info; if (direction & PYGI_DIRECTION_FROM_PYTHON) { cache->from_py_marshaller = _pygi_marshal_from_py_interface_callback; cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_callback; } if (direction & PYGI_DIRECTION_TO_PYTHON) { cache->to_py_marshaller = _pygi_marshal_to_py_interface_callback; } return TRUE; }
PyObject * _pygi_info_new (GIBaseInfo *info) { GIInfoType info_type; PyTypeObject *type = NULL; PyGIBaseInfo *self; info_type = g_base_info_get_type (info); switch (info_type) { case GI_INFO_TYPE_INVALID: PyErr_SetString (PyExc_RuntimeError, "Invalid info type"); return NULL; case GI_INFO_TYPE_FUNCTION: type = &PyGIFunctionInfo_Type; break; case GI_INFO_TYPE_CALLBACK: type = &PyGICallbackInfo_Type; break; case GI_INFO_TYPE_STRUCT: type = &PyGIStructInfo_Type; break; case GI_INFO_TYPE_BOXED: type = &PyGIBoxedInfo_Type; break; case GI_INFO_TYPE_ENUM: case GI_INFO_TYPE_FLAGS: type = &PyGIEnumInfo_Type; break; case GI_INFO_TYPE_OBJECT: type = &PyGIObjectInfo_Type; break; case GI_INFO_TYPE_INTERFACE: type = &PyGIInterfaceInfo_Type; break; case GI_INFO_TYPE_CONSTANT: type = &PyGIConstantInfo_Type; break; case GI_INFO_TYPE_UNION: type = &PyGIUnionInfo_Type; break; case GI_INFO_TYPE_VALUE: type = &PyGIValueInfo_Type; break; case GI_INFO_TYPE_SIGNAL: type = &PyGISignalInfo_Type; break; case GI_INFO_TYPE_VFUNC: type = &PyGIVFuncInfo_Type; break; case GI_INFO_TYPE_PROPERTY: type = &PyGIPropertyInfo_Type; break; case GI_INFO_TYPE_FIELD: type = &PyGIFieldInfo_Type; break; case GI_INFO_TYPE_ARG: type = &PyGIArgInfo_Type; break; case GI_INFO_TYPE_TYPE: type = &PyGITypeInfo_Type; break; case GI_INFO_TYPE_UNRESOLVED: type = &PyGIUnresolvedInfo_Type; break; default: g_assert_not_reached(); break; } self = (PyGIBaseInfo *) type->tp_alloc (type, 0); if (self == NULL) { return NULL; } self->info = g_base_info_ref (info); return (PyObject *) self; }
JSBool gjs_define_interface_class(JSContext *context, JSObject *in_object, GIInterfaceInfo *info, JSObject **prototype_p) { Interface *priv; const char *constructor_name; JSObject *constructor; JSObject *prototype; jsval value; constructor_name = g_base_info_get_name((GIBaseInfo*)info); gjs_object_get_property(context, in_object, constructor_name, &value); if (!JSVAL_IS_VOID(value)) { JSObject *constructor; if (!JSVAL_IS_OBJECT(value)) { gjs_throw(context, "Existing property '%s' does not look like a constructor", constructor_name); return JS_FALSE; } constructor = JSVAL_TO_OBJECT(value); gjs_object_get_property(context, constructor, "prototype", &value); if (!JSVAL_IS_OBJECT(value)) { gjs_throw(context, "prototype property does not appear to exist or has wrong type"); return JS_FALSE; } else { if (prototype_p) *prototype_p = JSVAL_TO_OBJECT(value); return JS_TRUE; } return JS_TRUE; } if (!gjs_init_class_dynamic(context, in_object, NULL, g_base_info_get_namespace((GIBaseInfo*)info), constructor_name, &gjs_interface_class, gjs_interface_constructor, 0, /* props of prototype */ &gjs_interface_proto_props[0], /* funcs of prototype */ &gjs_interface_proto_funcs[0], /* props of constructor, MyConstructor.myprop */ NULL, /* funcs of constructor, MyConstructor.myfunc() */ NULL, &prototype, &constructor)) { gjs_fatal("Can't init class %s", constructor_name); } GJS_INC_COUNTER(interface); priv = g_slice_new0(Interface); priv->info = info; priv->gtype = g_registered_type_info_get_g_type(priv->info); g_base_info_ref((GIBaseInfo*)priv->info); JS_SetPrivate(context, prototype, priv); gjs_define_static_methods(context, constructor, priv->gtype, priv->info); value = OBJECT_TO_JSVAL(gjs_gtype_create_gtype_wrapper(context, priv->gtype)); JS_DefineProperty(context, constructor, "$gtype", value, NULL, NULL, JSPROP_PERMANENT); if (prototype_p) *prototype_p = prototype; return JS_TRUE; }
JSBool gjs_define_boxed_class(JSContext *context, JSObject *in_object, GIBoxedInfo *info, JSObject **constructor_p, JSObject **prototype_p) { const char *constructor_name; JSObject *prototype; JSObject *constructor; jsval value; Boxed *priv; /* See the comment in gjs_define_object_class() for an * explanation of how this all works; Boxed is pretty much the * same as Object. */ constructor_name = g_base_info_get_name( (GIBaseInfo*) info); if (gjs_object_get_property(context, in_object, constructor_name, &value)) { JSObject *constructor; if (!JSVAL_IS_OBJECT(value)) { gjs_throw(context, "Existing property '%s' does not look like a constructor", constructor_name); return JS_FALSE; } constructor = JSVAL_TO_OBJECT(value); gjs_object_get_property(context, constructor, "prototype", &value); if (!JSVAL_IS_OBJECT(value)) { gjs_throw(context, "boxed %s prototype property does not appear to exist or has wrong type", constructor_name); return JS_FALSE; } else { if (prototype_p) *prototype_p = JSVAL_TO_OBJECT(value); if (constructor_p) *constructor_p = constructor; return JS_TRUE; } } if (!gjs_init_class_dynamic(context, in_object, NULL, /* parent prototype */ g_base_info_get_namespace( (GIBaseInfo*) info), constructor_name, &gjs_boxed_class, gjs_boxed_constructor, 1, /* props of prototype */ &gjs_boxed_proto_props[0], /* funcs of prototype */ &gjs_boxed_proto_funcs[0], /* props of constructor, MyConstructor.myprop */ NULL, /* funcs of constructor, MyConstructor.myfunc() */ NULL, &prototype, &constructor)) { gjs_log_exception(context, NULL); gjs_fatal("Can't init class %s", constructor_name); } GJS_INC_COUNTER(boxed); priv = g_slice_new0(Boxed); priv->info = info; boxed_fill_prototype_info(priv); g_base_info_ref( (GIBaseInfo*) priv->info); priv->gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo*) priv->info); JS_SetPrivate(context, prototype, priv); gjs_debug(GJS_DEBUG_GBOXED, "Defined class %s prototype is %p class %p in object %p", constructor_name, prototype, JS_GET_CLASS(context, prototype), in_object); priv->can_allocate_directly = struct_is_simple (priv->info); define_boxed_class_fields (context, priv, prototype); gjs_define_static_methods (context, constructor, priv->gtype, priv->info); value = OBJECT_TO_JSVAL(gjs_gtype_create_gtype_wrapper(context, priv->gtype)); JS_DefineProperty(context, constructor, "$gtype", value, NULL, NULL, JSPROP_PERMANENT); if (constructor_p) *constructor_p = constructor; if (prototype_p) *prototype_p = prototype; return JS_TRUE; }