[perl-Glib/gio-support: 2/12] [gio] Install copies of AUTOLOAD for method resolution
- From: Torsten Schönfeld <tsch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [perl-Glib/gio-support: 2/12] [gio] Install copies of AUTOLOAD for method resolution
- Date: Mon, 12 Apr 2010 21:12:05 +0000 (UTC)
commit 04239891677c3e6fbd40ae1076c4dd2b2be14f2c
Author: Torsten Schönfeld <kaffeetisch gmx de>
Date: Thu Dec 31 15:07:00 2009 +0100
[gio] Install copies of AUTOLOAD for method resolution
This is better than the old approach (relying on AUTOLOAD inheritance)
because it also works for functions.
GObjectIntrospection.xs | 56 +++++++++++++++++++++++++++++++++++++++-------
1 files changed, 47 insertions(+), 9 deletions(-)
---
diff --git a/GObjectIntrospection.xs b/GObjectIntrospection.xs
index 32fbce1..85d23ac 100644
--- a/GObjectIntrospection.xs
+++ b/GObjectIntrospection.xs
@@ -23,6 +23,7 @@
#include <girepository.h>
#include <ffi.h>
+/* #define NOISY */
#ifdef NOISY
# define dwarn(...) warn(__VA_ARGS__)
#else
@@ -46,7 +47,7 @@ get_function_info (GIRepository *repository,
const gchar *namespace,
const gchar *method)
{
- dwarn ("%s: %s, %s, %s", G_STRFUNC, basename, namespace, method);
+ dwarn ("%s: %s, %s, %s\n", G_STRFUNC, basename, namespace, method);
if (namespace) {
GIBaseInfo *namespace_info = g_irepository_find_by_name (
@@ -82,6 +83,10 @@ get_function_info (GIRepository *repository,
} else {
GIBaseInfo *method_info = g_irepository_find_by_name (
repository, basename, method);
+
+ if (!method_info)
+ croak ("Can't find information for method %s", method);
+
switch (g_base_info_get_type (method_info)) {
case GI_INFO_TYPE_FUNCTION:
return (GIFunctionInfo *) method_info;
@@ -152,10 +157,11 @@ sv_to_pointer (GITypeInfo* info, SV *sv)
/* FIXME: this is a hack */
if (0 == strncmp (type_name, "DestroyNotify", 14)) {
warn ("FIXME: callback of name DestroyNotify "
- "interpreted as destroy notify thingy");
+ "interpreted as destroy notify thingy\n");
pointer = release_callback;
} else {
pointer = create_callback_closure (info, sv);
+ dwarn (" returning closure %p\n", pointer);
}
break;
}
@@ -287,7 +293,7 @@ sv_to_arg (SV * sv,
switch (tag) {
case GI_TYPE_TAG_VOID:
dwarn (" type %p -> void pointer\n", info);
- warn ("FIXME: void pointer interpreted as callback user data");
+ warn ("FIXME: void pointer interpreted as callback user data\n");
/* FIXME: this is a hack */
arg->v_pointer = create_callback_data (sv);
break;
@@ -917,7 +923,7 @@ invoke_callback (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata)
GITransfer transfer = g_arg_info_get_ownership_transfer (arg_info);
GIDirection direction = g_arg_info_get_direction (arg_info);
- dwarn ("arg info: 0x%x\n"
+ dwarn ("arg info: %p\n"
" direction: %d\n"
" is dipper: %d\n"
" is return value: %d\n"
@@ -932,7 +938,7 @@ invoke_callback (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata)
g_arg_info_may_be_null (arg_info),
g_arg_info_get_ownership_transfer (arg_info));
- dwarn ("arg type: 0x%x\n"
+ dwarn ("arg type: %p\n"
" is pointer: %d\n"
" tag: %d\n",
arg_type,
@@ -1044,7 +1050,7 @@ invoke_callback (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata)
info = g_callable_info_get_return_type (cb_interface);
may_be_null = g_callable_info_may_return_null (cb_interface);
- dwarn ("ret type: 0x%x\n"
+ dwarn ("ret type: %p\n"
" is pointer: %d\n"
" tag: %d\n",
info,
@@ -1093,6 +1099,36 @@ release_callback (gpointer data)
/* ------------------------------------------------------------------------- */
+static void
+clone_autoload (const gchar *base_package, const gchar *package)
+{
+ gchar *autoload_name;
+ GV *autoload_glob;
+ CV *autoload_code;
+ gchar *package_autoload;
+ GV *gv;
+
+ /* FIXME: This would only need to be done once per register_types()
+ call */
+ autoload_name = g_strconcat (base_package, "::AUTOLOAD", NULL);
+ autoload_glob = gv_fetchpv (autoload_name, GV_NOADD_NOINIT, SVt_PVCV);
+ autoload_code = GvCV (autoload_glob);
+ g_free (autoload_name);
+
+ package_autoload = g_strconcat (package, "::AUTOLOAD", NULL);
+ gv = gv_fetchpv (package_autoload, GV_ADDMULTI, SVt_PVCV);
+ g_free (package_autoload);
+
+ /* FIXME: Shouldn't we have to increase the CV's ref count? Valgrind
+ doesn't complain, though.
+ SvREFCNT_inc (autoload_code); */
+ GvCV (gv) = autoload_code;
+ GvCVGEN (gv) = 0;
+ mro_method_changed_in (GvSTASH (gv)); /* FIXME: version checks */
+}
+
+/* ------------------------------------------------------------------------- */
+
MODULE = Glib::Object::_Introspection PACKAGE = Glib::Object::_Introspection
void
@@ -1145,13 +1181,13 @@ register_types (class, namespace, version, package)
g_type_name (type), type,
full_package);
- /* FIXME: This is a hack to get our AUTOLOAD involved. */
if (info_type == GI_INFO_TYPE_OBJECT ||
info_type == GI_INFO_TYPE_INTERFACE ||
info_type == GI_INFO_TYPE_BOXED ||
info_type == GI_INFO_TYPE_STRUCT ||
- info_type == GI_INFO_TYPE_UNION) {
- gperl_set_isa (full_package, package);
+ info_type == GI_INFO_TYPE_UNION)
+ {
+ clone_autoload (package, full_package);
}
switch (info_type) {
@@ -1384,6 +1420,8 @@ PPCODE:
if (has_return_value)
out_i++;
+ dwarn (" number of return values: %d\n", out_i);
+
if (out_i == 0) {
XSRETURN_EMPTY;
} else if (out_i == 1) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]