[pypy-commit] creflect default: another reorganization, split more the ffi and the lib
arigo
noreply at buildbot.pypy.org
Mon Dec 1 22:14:28 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r137:111c65f6cc20
Date: 2014-12-01 21:40 +0100
http://bitbucket.org/cffi/creflect/changeset/111c65f6cc20/
Log: another reorganization, split more the ffi and the lib
diff --git a/zeffir/zef_builder.c b/zeffir/builder.c
rename from zeffir/zef_builder.c
rename to zeffir/builder.c
--- a/zeffir/zef_builder.c
+++ b/zeffir/builder.c
@@ -5,11 +5,36 @@
typedef struct {
_crx_builder_t cb;
ZefLibObject *lib;
+ PyObject *l_dict;
ZefFFIObject *ffi;
- PyObject *l_dict;
+ PyObject *types_dict;
} zeffir_builder_t;
-static PyObject *zef_cache_primitive_signed;
+static CTypeDescrObject *get_cached_type(_crx_builder_t *cb, const char *name,
+ int accept_flags)
+{
+ PyObject *types_dict = ((zeffir_builder_t *)cb)->types_dict;
+ PyObject *x = PyDict_GetItemString(types_dict, name);
+ CTypeDescrObject *ct;
+
+ if (x == NULL || !CTypeDescr_Check(x))
+ return NULL;
+ ct = (CTypeDescrObject *)x;
+ if ((ct->ct_flags & accept_flags) == 0)
+ return NULL;
+ return ct;
+}
+
+static _crx_type_t *put_cached_type(_crx_builder_t *cb, const char *name,
+ CTypeDescrObject *ct)
+{
+ PyObject *types_dict = ((zeffir_builder_t *)cb)->types_dict;
+ int err = PyDict_SetItemString(types_dict, name, (PyObject *)ct);
+ Py_DECREF(ct);
+ if (err < 0)
+ return NULL;
+ return ct; /* still a reference in the dict */
+}
static _crx_type_t *zef_get_void_type(_crx_builder_t *cb)
{
@@ -29,33 +54,26 @@
static _crx_type_t *zef_get_signed_type(_crx_builder_t *cb, size_t sz,
const char *name)
{
- PyObject *x = PyDict_GetItemString(zef_cache_primitive_signed, name);
- CTypeDescrObject *td = (CTypeDescrObject *)x;
+ CTypeDescrObject *td = get_cached_type(cb, name, CT_PRIMITIVE_SIGNED);
+ if (td != NULL && td->ct_size == sz)
+ return td;
- if (td == NULL) {
- int err;
- size_t name_length = strlen(name);
+ size_t name_length = strlen(name);
- td = ctypedescr_new(name_length + 1);
- if (td == NULL)
- return NULL;
+ td = ctypedescr_new(name_length + 1);
+ if (td == NULL)
+ return NULL;
- memcpy(td->ct_name, name, name_length + 1);
- td->ct_name_position = name_length;
- td->ct_size = sz;
- //td->ct_length = ptypes->align;
- //td->ct_extra = ffitype;
- td->ct_flags = CT_PRIMITIVE_SIGNED;
- if (td->ct_size <= sizeof(long))
- td->ct_flags |= CT_PRIMITIVE_FITS_LONG;
+ memcpy(td->ct_name, name, name_length + 1);
+ td->ct_name_position = name_length;
+ td->ct_size = sz;
+ //td->ct_length = ptypes->align;
+ //td->ct_extra = ffitype;
+ td->ct_flags = CT_PRIMITIVE_SIGNED;
+ if (td->ct_size <= sizeof(long))
+ td->ct_flags |= CT_PRIMITIVE_FITS_LONG;
- x = (PyObject *)td;
- err = PyDict_SetItemString(zef_cache_primitive_signed, name, x);
- Py_DECREF(x);
- if (err < 0)
- return NULL;
- }
- return td;
+ return put_cached_type(cb, name, td);
}
static _crx_type_t *zef_get_unsigned_type(_crx_builder_t *cb, size_t sz,
@@ -158,10 +176,11 @@
_crx_trampoline0_fn trampl, void *directcall)
{
PyObject *l_dict = ((zeffir_builder_t *)cb)->l_dict;
- ZefFFIObject *ffi = ((zeffir_builder_t *)cb)->ffi;
+ PyObject *l_libname_obj = ((zeffir_builder_t *)cb)->lib->l_libname_obj;
assert(trampl != NULL);
- PyObject *x = make_builtin_func(ffi, name, ret, args, nargs, trampl);
+ PyObject *x = make_builtin_func(l_libname_obj, name, ret,
+ args, nargs, trampl);
if (x == NULL)
return;
@@ -189,27 +208,27 @@
abort();
}
-static int load_creflect_main(ZefLibObject *lib)
+static int load_creflect_main(ZefFFIObject *ffi, ZefLibObject *lib)
{
const char *creflect_main = "_creflect_main"; /* XXX fixed for now */
int (*crxmain)(_crx_builder_t *);
- crxmain = (int(*)(_crx_builder_t *))dlsym(lib->ffi->f_dl_lib,
- creflect_main);
+
+ crxmain = (int(*)(_crx_builder_t *))dlsym(lib->l_dl_lib, creflect_main);
if (crxmain == NULL) {
PyErr_Format(PyExc_OSError, "%s: symbol '%s' not found",
- lib->ffi->f_libname, creflect_main);
+ lib->l_libname, creflect_main);
return -1;
}
int result = crxmain(NULL);
if ((result & ~0xFF) != MAGIC_CREFLECT_TAG) {
PyErr_Format(PyExc_OSError, "%s: %s() is not a creflect entry point",
- lib->ffi->f_libname, creflect_main);
+ lib->l_libname, creflect_main);
return -1;
}
if ((result & 0xFF) != CREFLECT_VERSION) {
PyErr_Format(PyExc_OSError, "%s was made with creflect version %d, "
- "expected %d", lib->ffi->f_libname, result & 0xFF,
+ "expected %d", lib->l_libname, result & 0xFF,
CREFLECT_VERSION);
return -1;
}
@@ -240,17 +259,12 @@
zef_define_num_const,
zef_error,
},
- lib, /* lib */
- lib->ffi, /* ffi */
- lib->l_dict, /* l_dict */
+ lib, /* lib */
+ lib->l_dict, /* l_dict */
+ ffi, /* ffi */
+ ffi->types_dict, /* types_dict */
};
crxmain(&builder.cb);
return PyErr_Occurred() ? -1 : 0;
}
-
-static void init_caches(void)
-{
- if ((zef_cache_primitive_signed = PyDict_New()) == NULL)
- return;
-}
diff --git a/zeffir/zef_cdata.c b/zeffir/cdata.c
rename from zeffir/zef_cdata.c
rename to zeffir/cdata.c
diff --git a/zeffir/zef_cfunc.c b/zeffir/cfunc.c
rename from zeffir/zef_cfunc.c
rename to zeffir/cfunc.c
--- a/zeffir/zef_cfunc.c
+++ b/zeffir/cfunc.c
@@ -2,7 +2,6 @@
typedef struct {
PyObject_HEAD
- ZefFFIObject *zfs_ffi;
int zfs_nargs;
_crx_trampoline0_fn zfs_trampl;
PyMethodDef zfs_md;
@@ -12,13 +11,12 @@
static void zef_builtin_support_dealloc(ZefFuncSupportObject *zfs)
{
- Py_DECREF(zfs->zfs_ffi);
PyObject_Del(zfs);
}
static PyTypeObject ZefFuncSupport_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "zeffir.BuiltinSupport",
+ "zeffir.FuncSupport",
sizeof(ZefFuncSupportObject),
0,
(destructor)zef_builtin_support_dealloc, /* tp_dealloc */
@@ -67,8 +65,8 @@
return PyInt_FromLong(lloutput);
}
-static PyObject *make_builtin_func(ZefFFIObject *ffi, const char *funcname,
- _crx_type_t *ret,
+static PyObject *make_builtin_func(PyObject *libname_obj,
+ const char *funcname, _crx_type_t *ret,
_crx_qual_type args[], int nargs,
_crx_trampoline0_fn trampl)
{
@@ -78,8 +76,6 @@
return PyErr_NoMemory();
PyObject_Init((PyObject *)zfs, &ZefFuncSupport_Type);
- Py_INCREF(ffi);
- zfs->zfs_ffi = ffi;
zfs->zfs_nargs = nargs;
zfs->zfs_trampl = trampl;
@@ -90,7 +86,7 @@
/*zfs->zfs_md.ml_doc = ... */
PyObject *res = PyCFunction_NewEx(&zfs->zfs_md, (PyObject *)zfs,
- ffi->f_libname_obj);
+ libname_obj);
Py_DECREF(zfs);
return res;
}
diff --git a/zeffir/zef_ctype.c b/zeffir/ctype.c
rename from zeffir/zef_ctype.c
rename to zeffir/ctype.c
diff --git a/zeffir/zef_ffi_obj.c b/zeffir/ffi_obj.c
rename from zeffir/zef_ffi_obj.c
rename to zeffir/ffi_obj.c
--- a/zeffir/zef_ffi_obj.c
+++ b/zeffir/ffi_obj.c
@@ -1,24 +1,125 @@
+
+/* An FFI object has methods like ffi.new(). It is also a container for the
+ type declarations (typedefs and structs) that you can use, say in ffi.new().
+ They are in a dictionary available in the 'types' attribute, which you
+ can edit manually (e.g. 'ffi.types.update(ffi2.types)').
+
+ The method ffi.load_library() finds a creflect dynamic library, load
+ its type declarations into ffi.types, and returns a Lib object with
+ the functions, global variables and constants as attributes. Once the
+ Lib object goes out of scope (or ffi.close_library() is called), the
+ library is unloaded; accessing functions or global variables afterwards
+ will segfault.
+
+ There is no direct internal reference between the FFI and the Lib object.
+*/
struct ZefFFIObject_s {
PyObject_HEAD
- void *f_dl_lib; /* keep the library returned by 'dlopen()' */
- char *f_libname; /* the original argument to 'dlopen()' */
- PyObject *f_libname_obj; /* same, as a PyObject */
+ PyObject *types_dict;
};
static void ffi_dealloc(ZefFFIObject *ffi)
{
- if (ffi->f_dl_lib != NULL)
- dlclose(ffi->f_dl_lib);
- Py_DECREF(ffi->f_libname_obj);
- PyObject_Del(ffi);
+ PyObject_GC_UnTrack(ffi);
+ Py_DECREF(ffi->types_dict);
+ PyObject_GC_Del(ffi);
}
-static PyObject *ffi_repr(ZefFFIObject *ffi)
+static int ffi_traverse(ZefFFIObject *ffi, visitproc visit, void *arg)
{
- return PyString_FromFormat("<zeffir.FFI object for '%s'>", ffi->f_libname);
+ Py_VISIT(ffi->types_dict);
+ return 0;
}
+static PyObject *ffiobj_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ char *keywords[] = {NULL};
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "", keywords))
+ return NULL;
+
+ PyObject *dict = PyDict_New();
+ if (dict == NULL)
+ return NULL;
+
+ ZefFFIObject *ffi = PyObject_GC_New(ZefFFIObject, &ZefFFI_Type);
+ if (ffi == NULL) {
+ Py_DECREF(dict);
+ return NULL;
+ }
+ ffi->types_dict = dict;
+ PyObject_GC_Track(ffi);
+
+ return (PyObject *)ffi;
+}
+
+static PyObject *ffi_load_library(ZefFFIObject *self, PyObject *args,
+ PyObject *kwds)
+{
+ char *keywords[] = {"libname", "relative_to", NULL};
+ char *libname, *relative_to = NULL;
+ char *relative_dir;
+ PyObject *path;
+ ZefLibObject *lib;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|z", keywords,
+ &libname, &relative_to))
+ return NULL;
+
+ if (relative_to == NULL) {
+ relative_dir = strdup("");
+ }
+ else {
+ char *last_slash = strrchr(relative_to, '/');
+ if (last_slash == NULL)
+ relative_dir = strdup("./");
+ else
+ relative_dir = strndup(relative_to, last_slash + 1 - relative_to);
+ }
+ if (relative_dir == NULL)
+ return PyErr_NoMemory();
+
+ path = PyString_FromFormat("%slib%s.so", relative_dir, libname);
+ free(relative_dir);
+ if (path == NULL)
+ return NULL;
+
+ lib = lib_create(path);
+ Py_DECREF(path);
+
+ if (load_creflect_main(self, lib) < 0) {
+ Py_DECREF(lib);
+ return NULL;
+ }
+ return (PyObject *)lib;
+}
+
+static PyObject *ffi_close_library(PyObject *no_self, PyObject *args)
+{
+ ZefLibObject *lib;
+
+ if (!PyArg_ParseTuple(args, "O!", &lib, &ZefLib_Type))
+ return NULL;
+
+ if (lib_close(lib) < 0)
+ return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef ffi_methods[] = {
+ {"load_library", (PyCFunction)ffi_load_library,
+ METH_VARARGS | METH_KEYWORDS},
+ {"close_library", ffi_close_library, METH_VARARGS | METH_STATIC},
+ {NULL}
+};
+
+static PyMemberDef ffi_members[] = {
+ {"types", T_OBJECT, offsetof(ZefFFIObject, types_dict), READONLY},
+ {NULL}
+};
+
static PyTypeObject ZefFFI_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"zeffir.FFI",
@@ -29,7 +130,7 @@
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
- (reprfunc)ffi_repr, /* tp_repr */
+ 0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
@@ -39,14 +140,24 @@
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
0, /* tp_doc */
- 0, /* tp_traverse */
+ (traverseproc)ffi_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
- 0, /* tp_methods */
- 0, /* tp_members */
+ ffi_methods, /* tp_methods */
+ ffi_members, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ ffiobj_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
};
diff --git a/zeffir/zef_lib_obj.c b/zeffir/lib_obj.c
rename from zeffir/zef_lib_obj.c
rename to zeffir/lib_obj.c
--- a/zeffir/zef_lib_obj.c
+++ b/zeffir/lib_obj.c
@@ -1,21 +1,47 @@
+
+/* A Lib object is special in the sense that it has a custom __getattr__
+ which only returns objects from the internal, inaccessible 'l_dict'.
+ (It raises AttributeError for anything else, like '__class__'.)
+*/
struct ZefLibObject_s {
PyObject_HEAD
- PyObject *l_dict;
- ZefFFIObject *ffi;
+ PyObject *l_dict; /* functions, global variables and constants */
+ void *l_dl_lib; /* keep the library returned by 'dlopen()' */
+ char *l_libname; /* the original argument to 'dlopen()' */
+ PyObject *l_libname_obj; /* same, as a PyObject */
};
static void lib_dealloc(ZefLibObject *lib)
{
- Py_DECREF(lib->l_dict);
- Py_DECREF(lib->ffi);
+ (void)lib_close(lib);
PyObject_Del(lib);
}
static PyObject *lib_repr(ZefLibObject *lib)
{
- return PyString_FromFormat("<zeffir.Lib object for '%s'>",
- lib->ffi->f_libname);
+ return PyString_FromFormat("<zeffir.Lib object for '%.200s'%s>",
+ lib->l_libname,
+ lib->l_dl_lib == NULL ? " (closed)" : "");
+}
+
+static PyObject *lib_getattr(ZefLibObject *lib, PyObject *name)
+{
+ if (lib->l_dict == NULL) {
+ PyErr_Format(PyExc_ValueError, "lib '%.200s' was closed",
+ lib->l_libname);
+ return NULL;
+ }
+
+ PyObject *x = PyDict_GetItem(lib->l_dict, name);
+ if (x == NULL) {
+ PyErr_Format(PyExc_AttributeError,
+ "lib '%.200s' has no function,"
+ " global variable or constant '%.200s'",
+ lib->l_libname,
+ PyString_Check(name) ? PyString_AS_STRING(name) : "?");
+ }
+ return x;
}
static PyObject *lib_dir(PyObject *lib, PyObject *noarg)
@@ -28,11 +54,6 @@
{NULL, NULL} /* sentinel */
};
-static PyMemberDef lib_members[] = {
- {"__dict__", T_OBJECT, offsetof(ZefLibObject, l_dict), READONLY},
- {NULL}
-};
-
static PyTypeObject ZefLib_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"zeffir.Lib",
@@ -50,7 +71,7 @@
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
- PyObject_GenericGetAttr, /* tp_getattro */
+ (getattrofunc)lib_getattr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
@@ -62,7 +83,7 @@
0, /* tp_iter */
0, /* tp_iternext */
lib_methods, /* tp_methods */
- lib_members, /* tp_members */
+ 0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
@@ -70,3 +91,54 @@
0, /* tp_descr_set */
offsetof(ZefLibObject, l_dict), /* tp_dictoffset */
};
+
+static void lib_dlerror(ZefLibObject *lib)
+{
+ char *error = dlerror();
+ if (error == NULL)
+ error = "(no error reported)";
+ PyErr_Format(PyExc_OSError, "%s: %s", lib->l_libname, error);
+}
+
+static ZefLibObject *lib_create(PyObject *path)
+{
+ ZefLibObject *lib;
+
+ lib = PyObject_New(ZefLibObject, &ZefLib_Type);
+ if (lib == NULL)
+ return NULL;
+
+ lib->l_dl_lib = NULL;
+ lib->l_libname = PyString_AS_STRING(path);
+ Py_INCREF(path);
+ lib->l_libname_obj = path;
+ lib->l_dict = PyDict_New();
+ if (lib->l_dict == NULL) {
+ Py_DECREF(lib);
+ return NULL;
+ }
+
+ lib->l_dl_lib = dlopen(lib->l_libname, RTLD_LAZY);
+ if (lib->l_dl_lib == NULL) {
+ lib_dlerror(lib);
+ Py_DECREF(lib);
+ return NULL;
+ }
+ return lib;
+}
+
+static int lib_close(ZefLibObject *lib)
+{
+ void *dl_lib;
+ Py_CLEAR(lib->l_dict);
+
+ dl_lib = lib->l_dl_lib;
+ if (dl_lib != NULL) {
+ lib->l_dl_lib = NULL;
+ if (dlclose(dl_lib) != 0) {
+ lib_dlerror(lib);
+ return -1;
+ }
+ }
+ return 0;
+}
diff --git a/zeffir/test/support.py b/zeffir/test/support.py
--- a/zeffir/test/support.py
+++ b/zeffir/test/support.py
@@ -11,9 +11,8 @@
if err:
raise OSError("%r\n==> error code %s" % (cmd, err))
-def compile_and_open(modname):
- """Process with creflect 'modname.crx', compile the result, and load it."""
+def new_ffi():
if not os.path.exists(zeffir_lib_path):
run("cd '%s' && "
"gcc -g -I'%s' -Wall -Werror -fPIC -shared zeffir.c -o '%s'" %
@@ -24,6 +23,13 @@
import zeffir
del sys.path[0]
+ return zeffir.FFI()
+
+
+def compile_and_open(modname):
+ """Process with creflect 'modname.crx', compile the result, and load it."""
+
+ ffi = new_ffi()
mod_c_path = str(udir.join('%s.c' % modname))
mod_lib_path = str(udir.join('lib%s.so' % modname))
if not os.path.exists(mod_lib_path):
@@ -33,4 +39,5 @@
(zeffir_dir, modname, mod_c_path, mod_c_path, mod_lib_path))
assert os.path.exists(mod_lib_path)
- return zeffir.open(modname, relative_to=zeffir_lib_path)
+ lib = ffi.load_library(modname, relative_to=zeffir_lib_path)
+ return ffi, lib
diff --git a/zeffir/test/test_basic.py b/zeffir/test/test_basic.py
--- a/zeffir/test/test_basic.py
+++ b/zeffir/test/test_basic.py
@@ -1,3 +1,4 @@
+import py
import os
import support
@@ -6,7 +7,7 @@
ffi, lib = support.compile_and_open('basic')
assert type(ffi).__module__ == 'zeffir'
assert type(ffi).__name__ == 'FFI'
- assert repr(ffi) == "<zeffir.FFI object for '%s/libbasic.so'>" % (
+ assert repr(lib) == "<zeffir.Lib object for '%s/libbasic.so'>" % (
os.path.dirname(support.zeffir_lib_path),)
def test_forty_two():
@@ -17,3 +18,7 @@
def test_dir():
ffi, lib = support.compile_and_open('basic')
assert dir(lib) == ['forty_two']
+
+def test_no_special_attribute():
+ ffi, lib = support.compile_and_open('basic')
+ py.test.raises(AttributeError, getattr, lib, '__class__')
diff --git a/zeffir/zeffir.c b/zeffir/zeffir.c
--- a/zeffir/zeffir.c
+++ b/zeffir/zeffir.c
@@ -5,98 +5,21 @@
#include "../creflect/creflect_cdecl.h"
-typedef struct _crx_type_s CTypeDescrObject;
-typedef struct ZefLibObject_s ZefLibObject;
-typedef struct ZefFFIObject_s ZefFFIObject;
-
-
/************************************************************/
/* Works by including all other .c files. */
/* Allows all function and global symbols to remain static. */
-#include "zef_ctype.c"
-#include "zef_cdata.c"
-#include "zef_ffi_obj.c"
-#include "zef_lib_obj.c"
-#include "zef_cfunc.c"
-#include "zef_builder.c"
+#include "zeffir.h"
+#include "ctype.c"
+#include "cdata.c"
+#include "lib_obj.c"
+#include "ffi_obj.c"
+#include "cfunc.c"
+#include "builder.c"
/************************************************************/
-
-static PyObject *z_open(PyObject *self, PyObject *args, PyObject *kwds)
-{
- char *keywords[] = {"libname", "relative_to", NULL};
- char *libname, *relative_to, *relative_dir;
- PyObject *path;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss", keywords,
- &libname, &relative_to))
- return NULL;
-
- char *last_slash = strrchr(relative_to, '/');
- if (last_slash == NULL)
- relative_dir = strdup(".");
- else
- relative_dir = strndup(relative_to, last_slash - relative_to);
- if (relative_dir == NULL)
- return PyErr_NoMemory();
-
- path = PyString_FromFormat("%s/lib%s.so", relative_dir, libname);
- free(relative_dir);
- if (path == NULL)
- return NULL;
-
- ZefFFIObject *ffi = NULL;
- ZefLibObject *lib = NULL;
- PyObject *dict = NULL;
-
- dlerror(); /* clear errors */
- void *dl_lib = dlopen(PyString_AS_STRING(path), RTLD_LAZY);
- if (dl_lib == NULL) {
- char *error = dlerror();
- if (error == NULL)
- error = "failed to open";
- PyErr_Format(PyExc_OSError, "%s: %s", PyString_AS_STRING(path), error);
- goto error;
- }
-
- ffi = PyObject_New(ZefFFIObject, &ZefFFI_Type);
- if (ffi == NULL)
- goto error;
- ffi->f_dl_lib = dl_lib; dl_lib = NULL;
- ffi->f_libname = PyString_AS_STRING(path);
- ffi->f_libname_obj = path; path = NULL;
-
- dict = PyDict_New();
- if (dict == NULL)
- goto error;
-
- lib = PyObject_New(ZefLibObject, &ZefLib_Type);
- if (lib == NULL)
- goto error;
- lib->ffi = ffi; ffi = NULL;
- lib->l_dict = dict; dict = NULL;
-
- if (load_creflect_main(lib) < 0)
- goto error;
-
- PyObject *result = Py_BuildValue("OO", lib->ffi, lib);
- Py_DECREF(lib);
- return result;
-
- error:
- Py_XDECREF(dict);
- Py_XDECREF(lib);
- Py_XDECREF(ffi);
- if (dl_lib != NULL)
- dlclose(dl_lib);
- Py_XDECREF(path);
- return NULL;
-}
-
static PyMethodDef ZeffirMethods[] = {
- {"open", (PyCFunction)z_open, METH_KEYWORDS},
{NULL, NULL} /* Sentinel */
};
@@ -106,10 +29,7 @@
PyObject *m;
m = Py_InitModule("zeffir", ZeffirMethods);
- (void)m;
-
- init_caches();
- if (PyErr_Occurred())
+ if (m == NULL)
return;
if (PyType_Ready(&ZefFFI_Type) < 0)
@@ -120,4 +40,7 @@
return;
if (PyType_Ready(&ZefFuncSupport_Type) < 0)
return;
+
+ if (PyModule_AddObject(m, "FFI", (PyObject *)&ZefFFI_Type) < 0)
+ return;
}
diff --git a/zeffir/zeffir.h b/zeffir/zeffir.h
new file mode 100644
--- /dev/null
+++ b/zeffir/zeffir.h
@@ -0,0 +1,9 @@
+
+typedef struct _crx_type_s CTypeDescrObject;
+typedef struct ZefLibObject_s ZefLibObject;
+typedef struct ZefFFIObject_s ZefFFIObject;
+
+static PyTypeObject ZefFFI_Type;
+
+static int lib_close(ZefLibObject *);
+static int load_creflect_main(ZefFFIObject *, ZefLibObject *);
More information about the pypy-commit
mailing list