gnome-perl-introspection r24 - trunk/Glib-Object-Introspection/xs



Author: tsch
Date: Sun Nov  2 21:08:24 2008
New Revision: 24
URL: http://svn.gnome.org/viewvc/gnome-perl-introspection?rev=24&view=rev

Log:
Track the rename GI_TYPE_TAG_SYMBOL => GI_TYPE_TAG_INTERFACE.  Adapt to the
changed semantics of methods: the instance is not an explicit argument anymore.
Use g_typelib_symbol instead of manually mocking about with g_module_*.  Adapt
to the new GError semantics, which aren't an explicit argument anymore either.


Modified:
   trunk/Glib-Object-Introspection/xs/IdlBoxedInfo.xs
   trunk/Glib-Object-Introspection/xs/IdlFunctionInfo.xs

Modified: trunk/Glib-Object-Introspection/xs/IdlBoxedInfo.xs
==============================================================================
--- trunk/Glib-Object-Introspection/xs/IdlBoxedInfo.xs	(original)
+++ trunk/Glib-Object-Introspection/xs/IdlBoxedInfo.xs	Sun Nov  2 21:08:24 2008
@@ -138,7 +138,7 @@
 		ACCESS_VALUE (gchar*, gperl_sv_from_filename, gperl_filename_from_sv);
 		break;
 
-	    case GI_TYPE_TAG_SYMBOL:
+	    case GI_TYPE_TAG_INTERFACE:
 	    {
 		if (g_field_info_get_flags (field_info) & GI_FIELD_IS_READABLE) {
 			RETVAL = gperl_i11n_pointer_to_sv (field_type_info, G_STRUCT_MEMBER_P (pointer, offset), FALSE);

Modified: trunk/Glib-Object-Introspection/xs/IdlFunctionInfo.xs
==============================================================================
--- trunk/Glib-Object-Introspection/xs/IdlFunctionInfo.xs	(original)
+++ trunk/Glib-Object-Introspection/xs/IdlFunctionInfo.xs	Sun Nov  2 21:08:24 2008
@@ -226,6 +226,48 @@
 
 /* ------------------------------------------------------------------------- */
 
+static void *
+instance_sv_to_pointer (GIFunctionInfo *function_info, SV *sv)
+{
+	// We do *not* own container.
+	GIBaseInfo *container = g_base_info_get_container (
+				  (GIBaseInfo *) function_info);
+	GIInfoType info_type = g_base_info_get_type (container);
+
+#ifdef NOISY
+	warn ("instance_sv_to_pointer: container name: %s, info type: %d",
+	      g_base_info_get_name (container),
+	      info_type);
+#endif
+
+	void *pointer = NULL;
+
+	switch (info_type) {
+	    case GI_INFO_TYPE_OBJECT:
+		pointer = gperl_get_object (sv);
+		break;
+
+	    case GI_INFO_TYPE_BOXED:
+	    {
+		GType type = gperl_i11n_get_gtype (
+			       (GIRegisteredTypeInfo *) container);
+		pointer = gperl_get_boxed_check (sv, type);
+		break;
+	    }
+
+	    case GI_INFO_TYPE_ENUM:
+	    case GI_INFO_TYPE_FLAGS:
+	    case GI_INFO_TYPE_CALLBACK:
+	    case GI_INFO_TYPE_UNRESOLVED:
+	    default:
+		croak ("instance_sv_to_pointer: Don't know how to handle info type %d", info_type);
+	}
+
+	return pointer;
+}
+
+/* ------------------------------------------------------------------------- */
+
 static void
 sv_to_arg (SV * sv,
 	   GArgument * arg,
@@ -236,7 +278,7 @@
 
 	if (!sv || !SvOK (sv))
 		/* Interfaces need to be able to handle undef separately. */
-		if (!may_be_null && tag != GI_TYPE_TAG_SYMBOL)
+		if (!may_be_null && tag != GI_TYPE_TAG_INTERFACE)
 			croak ("undefined value for a mandatory argument encountered");
 
 	switch (tag) {
@@ -308,7 +350,7 @@
 		croak ("FIXME - GI_TYPE_TAG_ARRAY");
 		break;
 
-	    case GI_TYPE_TAG_SYMBOL:
+	    case GI_TYPE_TAG_INTERFACE:
 		arg->v_pointer = gperl_i11n_sv_to_pointer (info, sv);
 		break;
 
@@ -409,7 +451,7 @@
 	    case GI_TYPE_TAG_ARRAY:
 		croak ("FIXME - GI_TYPE_TAG_ARRAY");
 
-	    case GI_TYPE_TAG_SYMBOL:
+	    case GI_TYPE_TAG_INTERFACE:
 		return gperl_i11n_pointer_to_sv (info, arg->v_pointer, own);
 
 	    case GI_TYPE_TAG_GLIST:
@@ -443,8 +485,7 @@
 		croak ("FIXME - GI_TYPE_TAG_GHASH");
 
 	    case GI_TYPE_TAG_ERROR:
-		if (arg->v_pointer)
-			gperl_croak_gerror (NULL, arg->v_pointer);
+		croak ("FIXME - GI_TYPE_TAG_ERROR");
 		break;
 
 	    case GI_TYPE_TAG_SSIZE:
@@ -551,7 +592,7 @@
 		break;
 
 	    case GI_TYPE_TAG_ARRAY:
-	    case GI_TYPE_TAG_SYMBOL:
+	    case GI_TYPE_TAG_INTERFACE:
 	    case GI_TYPE_TAG_GLIST:
 	    case GI_TYPE_TAG_GSLIST:
 	    case GI_TYPE_TAG_GHASH:
@@ -648,7 +689,7 @@
 		break;
 
 	    case GI_TYPE_TAG_ARRAY:
-	    case GI_TYPE_TAG_SYMBOL:
+	    case GI_TYPE_TAG_INTERFACE:
 	    case GI_TYPE_TAG_GLIST:
 	    case GI_TYPE_TAG_GSLIST:
 	    case GI_TYPE_TAG_GHASH:
@@ -740,7 +781,7 @@
       case GI_TYPE_TAG_UTF8:
       case GI_TYPE_TAG_FILENAME:
       case GI_TYPE_TAG_ARRAY:
-      case GI_TYPE_TAG_SYMBOL:
+      case GI_TYPE_TAG_INTERFACE:
       case GI_TYPE_TAG_GLIST:
       case GI_TYPE_TAG_GSLIST:
       case GI_TYPE_TAG_GHASH:
@@ -1101,51 +1142,75 @@
 	ffi_type *return_type_ffi = NULL;
 	gpointer *args = NULL;
 	gpointer func_pointer = NULL;
-	GModule *module = NULL;
 	const gchar *symbol = NULL;
 
 	int have_args;
-	int n_args;
+	int n_args, n_invoke_args;
 	int n_in_args;
 	int n_out_args;
 	int i, out_i;
 	GITypeInfo ** out_arg_type = NULL;
 	GITypeInfo * return_type_info = NULL;
-	gboolean has_return_value;
+	gboolean throws, is_method, has_return_value;
 	GArgument return_value;
 	GArgument * in_args = NULL;
 	GArgument * out_args = NULL;
+	GError * local_error = NULL;
 
 	symbol = g_function_info_get_symbol (info);
 
-#ifdef NOISY
-	warn ("invoke: %s\n", symbol);
-#endif
-
-	module = g_module_open (NULL, 0);
-	if (!g_module_symbol (module, symbol, &func_pointer)) {
+	if (!g_typelib_symbol (g_base_info_get_typelib((GIBaseInfo *) info),
+			       symbol, &func_pointer))
+	{
 		croak ("Could not locate symbol %s", symbol);
 	}
 
 #define OFFSET 1
 	have_args = items - OFFSET;
-	n_args = g_callable_info_get_n_args ((GICallableInfo *) info);
+
+	n_invoke_args = n_args = g_callable_info_get_n_args ((GICallableInfo *) info);
+
+	throws = g_function_info_get_flags (info) & GI_FUNCTION_THROWS;
+	if (throws) {
+		n_invoke_args++;
+	}
+
+	is_method =
+		(g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD)
+	    && !(g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR);
+	if (is_method) {
+		n_invoke_args++;
+	}
+
+#ifdef NOISY
+	warn ("invoke: %s -> n_args %d, n_invoke_args %d, have_args %d\n",
+	      symbol, n_args, n_invoke_args, have_args);
+#endif
 
 	/* to allow us to make only one pass through the arg list, allocate
 	 * enough space for all args in both the out and in lists.  we'll
 	 * only use as much as we need.  since function argument lists are
 	 * typically small, this shouldn't be a big problem. */
-	if (n_args) {
-		in_args = gperl_alloc_temp (sizeof (GArgument) * n_args);
-		out_args = gperl_alloc_temp (sizeof (GArgument) * n_args);
-		out_arg_type = gperl_alloc_temp (sizeof (GITypeInfo*) * n_args);
+	if (n_invoke_args) {
+		in_args = gperl_alloc_temp (sizeof (GArgument) * n_invoke_args);
+		out_args = gperl_alloc_temp (sizeof (GArgument) * n_invoke_args);
+		out_arg_type = gperl_alloc_temp (sizeof (GITypeInfo*) * n_invoke_args);
 
-		arg_types = gperl_alloc_temp (sizeof (ffi_type *) * n_args);
-		args = gperl_alloc_temp (sizeof (gpointer) * n_args);
+		arg_types = gperl_alloc_temp (sizeof (ffi_type *) * n_invoke_args);
+		args = gperl_alloc_temp (sizeof (gpointer) * n_invoke_args);
 	}
 
 	n_in_args = n_out_args = 0;
+
+	if (is_method) {
+		gpointer instance = instance_sv_to_pointer (info, ST (0+OFFSET));
+		arg_types[0] = &ffi_type_pointer;
+		args[0] = &instance;
+		n_in_args++;
+	}
+
 	for (i = 0 ; i < n_args ; i++) {
+		int method_offset = is_method ? 1 : 0;
 		GIArgInfo * arg_info =
 			g_callable_info_get_arg ((GICallableInfo *) info, i);
 		/* In case of out and in-out args, arg_type is unref'ed after
@@ -1159,9 +1224,9 @@
 
 		switch (g_arg_info_get_direction (arg_info)) {
 		    case GI_DIRECTION_IN:
-			sv_to_arg (ST (i+OFFSET), &in_args[n_in_args], arg_type, may_be_null);
-			arg_types[i] = get_ffi_type (arg_type);
-			args[i] = &in_args[n_in_args];
+			sv_to_arg (ST (i + method_offset + OFFSET), &in_args[n_in_args], arg_type, may_be_null);
+			arg_types[i + method_offset] = get_ffi_type (arg_type);
+			args[i + method_offset] = &in_args[n_in_args];
 			g_base_info_unref ((GIBaseInfo *) arg_type);
 			n_in_args++;
 			break;
@@ -1169,21 +1234,21 @@
 			out_args[n_out_args].v_pointer =
 				gperl_alloc_temp (sizeof (GArgument));
 			out_arg_type[n_out_args] = arg_type;
-			arg_types[i] = &ffi_type_pointer;
-			args[i] = &out_args[n_out_args];
+			arg_types[i + method_offset] = &ffi_type_pointer;
+			args[i + method_offset] = &out_args[n_out_args];
 			n_out_args++;
 			break;
 		    case GI_DIRECTION_INOUT:
 		    {
 			GArgument * temp =
 				gperl_alloc_temp (sizeof (GArgument));
-			sv_to_arg (ST (i+OFFSET), temp, arg_type, may_be_null);
+			sv_to_arg (ST (i + method_offset + OFFSET), temp, arg_type, may_be_null);
 			in_args[n_in_args].v_pointer =
 				out_args[n_out_args].v_pointer =
 					temp;
 			out_arg_type[n_out_args] = arg_type;
-			arg_types[i] = &ffi_type_pointer;
-			args[i] = &in_args[n_in_args];
+			arg_types[i + method_offset] = &ffi_type_pointer;
+			args[i + method_offset] = &in_args[n_in_args];
 			n_in_args++;
 			n_out_args++;
 		    }
@@ -1203,12 +1268,18 @@
 		croak ("%s needs %d args, got %d", symbol, n_in_args, have_args);
 #endif
 
+	if (throws) {
+		gpointer address = &local_error;
+		args[n_invoke_args - 1] = &address;
+		arg_types[n_invoke_args - 1] = &ffi_type_pointer;
+	}
+
 	/* find the return value type */
 	return_type_info = g_callable_info_get_return_type ((GICallableInfo *) info);
 	return_type_ffi = get_ffi_type (return_type_info);
 
 	/* prepare and call the function */
-	if (FFI_OK != ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args,
+	if (FFI_OK != ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_invoke_args,
 	   	      		    return_type_ffi, arg_types))
 	{
 		g_base_info_unref ((GIBaseInfo *) return_type_info);
@@ -1217,6 +1288,10 @@
 
 	ffi_call (&cif, func_pointer, &return_value, args);
 
+	if (local_error) {
+		gperl_croak_gerror (NULL, local_error);
+	}
+
 	/*
 	 * place return value and output args on the stack
 	 */



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