Commit d5925b76 authored by Simon Feltman's avatar Simon Feltman
Browse files

cache refactoring: Remove special case marshaling for instance arguments

Remove duplicate code for marshaling struct and objects for
instance arguments. Re-use individual cache marshalers for
structs and objects with the instance argument. This required
removal of passing GITypeInfo to the marshaler because it is
not available for instance arguments. Instead always assume
"is_pointer" for the instance argument by using the cache.

https://bugzilla.gnome.org/show_bug.cgi?id=640812
parent c19bed69
...@@ -1031,12 +1031,12 @@ array_success: ...@@ -1031,12 +1031,12 @@ array_success:
&arg, &arg,
NULL, /*arg_name*/ NULL, /*arg_name*/
info, /*interface_info*/ info, /*interface_info*/
type_info,
g_type, g_type,
py_type, py_type,
transfer, transfer,
FALSE, /*copy_reference*/ FALSE, /*copy_reference*/
g_struct_info_is_foreign (info)); g_struct_info_is_foreign (info),
g_type_info_is_pointer (type_info));
Py_DECREF (py_type); Py_DECREF (py_type);
break; break;
......
...@@ -42,6 +42,7 @@ PyGIArgCache * _arg_cache_new_for_interface (GIInterfaceInfo *iface_info, ...@@ -42,6 +42,7 @@ PyGIArgCache * _arg_cache_new_for_interface (GIInterfaceInfo *iface_info,
PyGIDirection direction, PyGIDirection direction,
gssize c_arg_index, gssize c_arg_index,
gssize py_arg_index); gssize py_arg_index);
/* cleanup */ /* cleanup */
static void static void
_pygi_arg_cache_free (PyGIArgCache *cache) _pygi_arg_cache_free (PyGIArgCache *cache)
...@@ -990,10 +991,6 @@ _args_cache_generate (GICallableInfo *callable_info, ...@@ -990,10 +991,6 @@ _args_cache_generate (GICallableInfo *callable_info,
callable_cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) { callable_cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) {
GIInterfaceInfo *interface_info; GIInterfaceInfo *interface_info;
PyGIArgCache *instance_cache; PyGIArgCache *instance_cache;
PyGIDirection instance_direction;
instance_direction = PYGI_DIRECTION_FROM_PYTHON;
interface_info = g_base_info_get_container ( (GIBaseInfo *)callable_info); interface_info = g_base_info_get_container ( (GIBaseInfo *)callable_info);
...@@ -1002,17 +999,19 @@ _args_cache_generate (GICallableInfo *callable_info, ...@@ -1002,17 +999,19 @@ _args_cache_generate (GICallableInfo *callable_info,
callable_cache, callable_cache,
NULL, NULL,
GI_TRANSFER_NOTHING, GI_TRANSFER_NOTHING,
instance_direction, PYGI_DIRECTION_FROM_PYTHON,
arg_index, arg_index,
0); 0);
/* FIXME: marshal interfaces from_py */
instance_cache->from_py_marshaller = _pygi_marshal_from_py_interface_instance;
g_base_info_unref ( (GIBaseInfo *)interface_info); g_base_info_unref ( (GIBaseInfo *)interface_info);
if (instance_cache == NULL) if (instance_cache == NULL)
return FALSE; return FALSE;
/* Because we are not supplied a GITypeInfo for instance arguments,
* assume some defaults. */
instance_cache->is_pointer = TRUE;
_pygi_callable_cache_set_arg (callable_cache, arg_index, instance_cache); _pygi_callable_cache_set_arg (callable_cache, arg_index, instance_cache);
arg_index++; arg_index++;
...@@ -1112,9 +1111,6 @@ _args_cache_generate (GICallableInfo *callable_info, ...@@ -1112,9 +1111,6 @@ _args_cache_generate (GICallableInfo *callable_info,
if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL) { if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL) {
callable_cache->n_to_py_args++; callable_cache->n_to_py_args++;
if (arg_cache == NULL)
goto arg_err;
callable_cache->to_py_args = callable_cache->to_py_args =
g_slist_append (callable_cache->to_py_args, arg_cache); g_slist_append (callable_cache->to_py_args, arg_cache);
} }
......
...@@ -1455,12 +1455,12 @@ _pygi_marshal_from_py_interface_struct_cache_adapter (PyGIInvokeState *state, ...@@ -1455,12 +1455,12 @@ _pygi_marshal_from_py_interface_struct_cache_adapter (PyGIInvokeState *state,
arg, arg,
arg_cache->arg_name, arg_cache->arg_name,
iface_cache->interface_info, iface_cache->interface_info,
arg_cache->type_info,
iface_cache->g_type, iface_cache->g_type,
iface_cache->py_type, iface_cache->py_type,
arg_cache->transfer, arg_cache->transfer,
TRUE, /*copy_reference*/ TRUE, /*copy_reference*/
iface_cache->is_foreign); iface_cache->is_foreign,
arg_cache->is_pointer);
} }
gboolean gboolean
...@@ -1516,83 +1516,6 @@ _pygi_marshal_from_py_interface_union (PyGIInvokeState *state, ...@@ -1516,83 +1516,6 @@ _pygi_marshal_from_py_interface_union (PyGIInvokeState *state,
return FALSE; return FALSE;
} }
gboolean _pygi_marshal_from_py_interface_instance (PyGIInvokeState *state,
PyGICallableCache *callable_cache,
PyGIArgCache *arg_cache,
PyObject *py_arg,
GIArgument *arg)
{
GIInfoType info_type;
PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
info_type = g_base_info_get_type (iface_cache->interface_info);
switch (info_type) {
case GI_INFO_TYPE_UNION:
case GI_INFO_TYPE_STRUCT:
{
GType type = iface_cache->g_type;
if (!PyObject_IsInstance (py_arg, iface_cache->py_type)) {
/* wait, we might be a member of a union so manually check */
if (!_is_union_member (iface_cache->interface_info, py_arg)) {
if (!PyErr_Occurred()) {
PyObject *module = PyObject_GetAttrString(py_arg, "__module__");
PyErr_Format (PyExc_TypeError,
"argument %s: Expected a %s, but got %s%s%s",
arg_cache->arg_name ? arg_cache->arg_name : "self",
iface_cache->type_name,
module ? PYGLIB_PyUnicode_AsString(module) : "",
module ? "." : "",
py_arg->ob_type->tp_name);
if (module)
Py_DECREF (module);
}
return FALSE;
}
}
if (g_type_is_a (type, G_TYPE_BOXED)) {
arg->v_pointer = pyg_boxed_get (py_arg, void);
} else if (g_type_is_a (type, G_TYPE_POINTER) ||
g_type_is_a (type, G_TYPE_VARIANT) ||
type == G_TYPE_NONE) {
arg->v_pointer = pyg_pointer_get (py_arg, void);
} else {
PyErr_Format (PyExc_TypeError, "unable to convert an instance of '%s'", g_type_name (type));
return FALSE;
}
break;
}
case GI_INFO_TYPE_OBJECT:
case GI_INFO_TYPE_INTERFACE:
arg->v_pointer = pygobject_get (py_arg);
if (arg->v_pointer != NULL) {
GType obj_type = G_OBJECT_TYPE (( GObject *)arg->v_pointer);
GType expected_type = iface_cache->g_type;
if (!g_type_is_a (obj_type, expected_type)) {
PyObject *module = PyObject_GetAttrString(py_arg, "__module__");
PyErr_Format (PyExc_TypeError, "argument %s: Expected %s, but got %s%s%s",
arg_cache->arg_name ? arg_cache->arg_name : "self",
iface_cache->type_name,
module ? PYGLIB_PyUnicode_AsString(module) : "",
module ? "." : "",
py_arg->ob_type->tp_name);
if (module)
Py_DECREF (module);
return FALSE;
}
}
break;
default:
/* Other types don't have methods. */
g_assert_not_reached ();
}
return TRUE;
}
/* _pygi_marshal_from_py_gobject: /* _pygi_marshal_from_py_gobject:
* py_arg: (in): * py_arg: (in):
* arg: (out): * arg: (out):
...@@ -1765,12 +1688,12 @@ _pygi_marshal_from_py_interface_struct (PyObject *py_arg, ...@@ -1765,12 +1688,12 @@ _pygi_marshal_from_py_interface_struct (PyObject *py_arg,
GIArgument *arg, GIArgument *arg,
const gchar *arg_name, const gchar *arg_name,
GIBaseInfo *interface_info, GIBaseInfo *interface_info,
GITypeInfo *type_info,
GType g_type, GType g_type,
PyObject *py_type, PyObject *py_type,
GITransfer transfer, GITransfer transfer,
gboolean copy_reference, gboolean copy_reference,
gboolean is_foreign) gboolean is_foreign,
gboolean is_pointer)
{ {
gboolean is_union = FALSE; gboolean is_union = FALSE;
...@@ -1826,7 +1749,7 @@ _pygi_marshal_from_py_interface_struct (PyObject *py_arg, ...@@ -1826,7 +1749,7 @@ _pygi_marshal_from_py_interface_struct (PyObject *py_arg,
} else if (g_type_is_a (g_type, G_TYPE_POINTER) || } else if (g_type_is_a (g_type, G_TYPE_POINTER) ||
g_type_is_a (g_type, G_TYPE_VARIANT) || g_type_is_a (g_type, G_TYPE_VARIANT) ||
g_type == G_TYPE_NONE) { g_type == G_TYPE_NONE) {
g_warn_if_fail (g_type_is_a (g_type, G_TYPE_VARIANT) || !g_type_info_is_pointer (type_info) || transfer == GI_TRANSFER_NOTHING); g_warn_if_fail (g_type_is_a (g_type, G_TYPE_VARIANT) || !is_pointer || transfer == GI_TRANSFER_NOTHING);
if (g_type_is_a (g_type, G_TYPE_VARIANT) && if (g_type_is_a (g_type, G_TYPE_VARIANT) &&
pyg_type_from_object (py_arg) != G_TYPE_VARIANT) { pyg_type_from_object (py_arg) != G_TYPE_VARIANT) {
......
...@@ -83,11 +83,6 @@ gboolean _pygi_marshal_from_py_interface_struct_cache_adapter (PyGIInvokeState ...@@ -83,11 +83,6 @@ gboolean _pygi_marshal_from_py_interface_struct_cache_adapter (PyGIInvokeState
PyGIArgCache *arg_cache, PyGIArgCache *arg_cache,
PyObject *py_arg, PyObject *py_arg,
GIArgument *arg); GIArgument *arg);
gboolean _pygi_marshal_from_py_interface_interface(PyGIInvokeState *state,
PyGICallableCache *callable_cache,
PyGIArgCache *arg_cache,
PyObject *py_arg,
GIArgument *arg);
gboolean _pygi_marshal_from_py_interface_boxed (PyGIInvokeState *state, gboolean _pygi_marshal_from_py_interface_boxed (PyGIInvokeState *state,
PyGICallableCache *callable_cache, PyGICallableCache *callable_cache,
PyGIArgCache *arg_cache, PyGIArgCache *arg_cache,
...@@ -103,11 +98,6 @@ gboolean _pygi_marshal_from_py_interface_union (PyGIInvokeState *state, ...@@ -103,11 +98,6 @@ gboolean _pygi_marshal_from_py_interface_union (PyGIInvokeState *state,
PyGIArgCache *arg_cache, PyGIArgCache *arg_cache,
PyObject *py_arg, PyObject *py_arg,
GIArgument *arg); GIArgument *arg);
gboolean _pygi_marshal_from_py_interface_instance (PyGIInvokeState *state,
PyGICallableCache *callable_cache,
PyGIArgCache *arg_cache,
PyObject *py_arg,
GIArgument *arg);
/* Simplified marshalers shared between vfunc/closure and direct function calls. */ /* Simplified marshalers shared between vfunc/closure and direct function calls. */
gboolean _pygi_marshal_from_py_basic_type (PyObject *object, /* in */ gboolean _pygi_marshal_from_py_basic_type (PyObject *object, /* in */
...@@ -139,12 +129,12 @@ gboolean _pygi_marshal_from_py_interface_struct (PyObject *py_arg, ...@@ -139,12 +129,12 @@ gboolean _pygi_marshal_from_py_interface_struct (PyObject *py_arg,
GIArgument *arg, GIArgument *arg,
const gchar *arg_name, const gchar *arg_name,
GIBaseInfo *interface_info, GIBaseInfo *interface_info,
GITypeInfo *type_info,
GType g_type, GType g_type,
PyObject *py_type, PyObject *py_type,
GITransfer transfer, GITransfer transfer,
gboolean is_allocated, gboolean is_allocated,
gboolean is_foreign); gboolean is_foreign,
gboolean is_pointer);
G_END_DECLS G_END_DECLS
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment