From bfab9862fcdd657a1bddafde49cdd182f89fcf8b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 20:41:34 +0100 Subject: python: Allow wrapping pointers within talloc'ed memory that are not talloc contexts. (This used to be commit 9c038a74113fb55ed5eb12a7d0ae4a46bad9050c) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 44 ++++++++++++++++++---------- source4/scripting/python/pytalloc.c | 10 ++++--- source4/scripting/python/pytalloc.h | 11 +++++-- 3 files changed, 42 insertions(+), 23 deletions(-) diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index a5f8053834..cea3889938 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -138,7 +138,7 @@ sub FromPythonToUnionFunction($$$$$) } $self->indent; if ($e->{NAME}) { - $self->ConvertObjectFromPython($mem_ctx, $e->{TYPE}, $name, "ret->$e->{NAME}"); + $self->ConvertObjectFromPython($mem_ctx, $e->{TYPE}, $name, "ret->$e->{NAME}", "talloc_free(ret); return NULL;"); } $self->pidl("break;"); $self->deindent; @@ -164,8 +164,6 @@ sub PythonStruct($$$$) { my ($self, $name, $cname, $d) = @_; - $self->pidl("staticforward PyTypeObject $name\_ObjectType;"); - $self->pidl(""); $self->pidl("static PyObject *py_$name\_getattr(PyObject *obj, char *name)"); @@ -190,12 +188,15 @@ sub PythonStruct($$$$) $self->pidl("{"); $self->indent; $self->pidl("$cname *object = py_talloc_get_type(py_obj, $cname);"); + $self->pidl("TALLOC_CTX *mem_ctx = py_talloc_get_mem_ctx(py_obj);"); foreach my $e (@{$d->{ELEMENTS}}) { $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); my $varname = "object->$e->{NAME}"; $self->indent; - $self->pidl("/* FIXME: talloc_free($varname) if necessary */"); - $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "value", $varname); + if ($e->{ORIGINAL}->{POINTERS} > 0) { + $self->pidl("talloc_free($varname);"); + } + $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "value", $varname, "talloc_free(mem_ctx); return -1;"); $self->pidl("return 0;"); $self->deindent; $self->pidl("}"); @@ -206,7 +207,11 @@ sub PythonStruct($$$$) $self->pidl("}"); $self->pidl(""); - $self->pidl("static PyTypeObject $name\_ObjectType = {"); + $self->pidl_hdr("PyAPI_DATA(PyTypeObject) $name\_Type;\n"); + $self->pidl_hdr("#define $name\_Check(op) PyObject_TypeCheck(op, &$name\_Type)\n"); + $self->pidl_hdr("#define $name\_CheckExact(op) ((op)->ob_type == &$name\_Type)\n"); + $self->pidl_hdr("\n"); + $self->pidl("PyTypeObject $name\_Type = {"); $self->indent; $self->pidl("PyObject_HEAD_INIT(NULL) 0,"); $self->pidl(".tp_name = \"$name\","); @@ -225,7 +230,7 @@ sub PythonStruct($$$$) $self->pidl("{"); $self->indent; $self->pidl("$cname *ret = talloc_zero(NULL, $cname);"); - $self->pidl("return py_talloc_import(&$name\_ObjectType, ret);"); + $self->pidl("return py_talloc_import(&$name\_Type, ret);"); $self->deindent; $self->pidl("}"); $self->pidl(""); @@ -265,7 +270,7 @@ sub PythonFunction($$$) foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/in/,@{$e->{DIRECTION}})) { - $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "py_$e->{NAME}", "r.in.$e->{NAME}"); + $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "py_$e->{NAME}", "r.in.$e->{NAME}", "talloc_free(mem_ctx); return NULL;"); } } $self->pidl("status = dcerpc_$fn->{NAME}(iface->pipe, mem_ctx, &r);"); @@ -377,7 +382,7 @@ sub Interface($$$) $self->PythonType($d, $interface, $basename); } - $self->pidl("staticforward PyTypeObject $interface->{NAME}_InterfaceType;"); + $self->pidl_hdr("PyAPI_DATA(PyTypeObject) $interface->{NAME}_InterfaceType;\n"); $self->pidl("typedef struct {"); $self->indent; $self->pidl("PyObject_HEAD"); @@ -430,13 +435,13 @@ sub Interface($$$) $self->pidl(""); - $self->pidl("static PyTypeObject $interface->{NAME}_InterfaceType = {"); + $self->pidl("PyTypeObject $interface->{NAME}_InterfaceType = {"); $self->indent; $self->pidl("PyObject_HEAD_INIT(NULL) 0,"); $self->pidl(".tp_name = \"$interface->{NAME}\","); $self->pidl(".tp_basicsize = sizeof($interface->{NAME}_InterfaceObject),"); - $self->pidl(".tp_dealloc = (destructor)interface_$interface->{NAME}_dealloc,"); - $self->pidl(".tp_getattr = (getattrfunc)interface_$interface->{NAME}_getattr,"); + $self->pidl(".tp_dealloc = interface_$interface->{NAME}_dealloc,"); + $self->pidl(".tp_getattr = interface_$interface->{NAME}_getattr,"); $self->deindent; $self->pidl("};"); @@ -479,9 +484,9 @@ sub register_module_method($$$$$) push (@{$self->{module_methods}}, [$fn_name, $pyfn_name, $flags, $doc]) } -sub ConvertObjectFromPython($$$$$) +sub ConvertObjectFromPython($$$$$$) { - my ($self, $mem_ctx, $ctype, $cvar, $target) = @_; + my ($self, $mem_ctx, $ctype, $cvar, $target, $fail) = @_; die("undef type for $cvar") unless(defined($ctype)); @@ -502,12 +507,14 @@ sub ConvertObjectFromPython($$$$$) if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or $actual_ctype->{TYPE} eq "SCALAR" and ( expandAlias($actual_ctype->{NAME}) =~ /^(u?int[0-9]+|hyper|NTTIME|time_t|NTTIME_hyper|NTTIME_1sec|dlong|udlong|udlongr)$/)) { + $self->pidl("PY_CHECK_TYPE(PyInt, $cvar, $fail);"); $self->pidl("$target = PyInt_AsLong($cvar);"); return; } if ($actual_ctype->{TYPE} eq "STRUCT") { - $self->pidl("$target = py_talloc_get_type($cvar, " . mapTypeName($ctype) . ");"); + $self->pidl("PY_CHECK_TYPE($ctype->{NAME}, $cvar, $fail);"); + $self->pidl("$target = py_talloc_get_ptr($cvar);"); return; } @@ -635,7 +642,7 @@ sub ConvertObjectToPython($$$) if ($actual_ctype->{TYPE} eq "STRUCT") { # FIXME: if $cvar is not a pointer, do a talloc_dup() - return "py_talloc_import(&$ctype->{NAME}_ObjectType, $cvar)"; + return "py_talloc_import(&$ctype->{NAME}_Type, $cvar)"; } die("unknown type ".mapTypeName($ctype) . ": $cvar"); @@ -660,6 +667,11 @@ sub Parse($$$$$) #include \"$ndr_hdr\" #include \"$py_hdr\" +#define PY_CHECK_TYPE(type, var, fail) \\ + if (!type ## _Check(var)) {\\ + PyErr_Format(PyExc_TypeError, \"Expected type %s\", type ## _Type.tp_name); \\ + fail; \\ + } "); foreach my $x (@$ndr) { diff --git a/source4/scripting/python/pytalloc.c b/source4/scripting/python/pytalloc.c index 4032ff75a4..d0b8cb83f2 100644 --- a/source4/scripting/python/pytalloc.c +++ b/source4/scripting/python/pytalloc.c @@ -22,14 +22,16 @@ void py_talloc_dealloc(PyObject* self) { py_talloc_Object *obj = (py_talloc_Object *)self; - talloc_free(obj->talloc_ptr); + talloc_free(obj->talloc_ctx); PyObject_Del(self); } -PyObject *py_talloc_import(PyTypeObject *py_type, void *ptr) +PyObject *py_talloc_import(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, + void *ptr) { PyObject *ret = PyObject_New(py_talloc_Object, &py_type); - ret->talloc_ptr = talloc_reference(NULL, ptr); + ret->talloc_ctx = talloc_reference(mem_ctx, ptr); + ret->ptr = ptr; return ret; } @@ -38,5 +40,5 @@ PyObject *py_talloc_default_repr(PyObject *py_obj) py_talloc_Object *obj = (py_talloc_Object *)py_obj; return PyString_FromFormat("", - talloc_get_name(obj->talloc_ptr)); + talloc_get_name(obj->talloc_ctx)); } diff --git a/source4/scripting/python/pytalloc.h b/source4/scripting/python/pytalloc.h index 735829bfcb..aad5840a67 100644 --- a/source4/scripting/python/pytalloc.h +++ b/source4/scripting/python/pytalloc.h @@ -24,7 +24,8 @@ typedef struct { PyObject_HEAD - void *talloc_ptr; + TALLOC_CTX *talloc_ctx; + void *ptr; } py_talloc_Object; /* Deallocate a py_talloc_Object */ @@ -36,9 +37,13 @@ void py_talloc_dealloc(PyObject* self); /* FIXME: Call PyErr_SetString(PyExc_TypeError, "expected " __STR(type) ") * when talloc_get_type() returns NULL. */ #define py_talloc_get_type(py_obj, type) \ - talloc_get_type(((py_talloc_Object *)py_obj)->talloc_ptr, type) + talloc_get_type(py_talloc_get_ptr(py_obj), type) -PyObject *py_talloc_import(PyTypeObject *py_type, void *ptr); +#define py_talloc_get_ptr(py_obj) ((py_talloc_Object *)py_obj)->ptr +#define py_talloc_get_mem_ctx(py_obj) ((py_talloc_Object *)py_obj)->talloc_ctx + +PyObject *py_talloc_import_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr); +#define py_talloc_import(py_type, talloc_ptr) py_talloc_import_ex(py_type, talloc_ptr, talloc_ptr) /* Sane default implementation of reprfunc. */ PyObject *py_talloc_default_repr(PyObject *py_obj); -- cgit