Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r128:25439df4dc03
Date: 2014-11-30 11:15 +0100
http://bitbucket.org/cffi/creflect/changeset/25439df4dc03/

Log:    Split zeffir.c into pieces, to avoid ending up like _cffi_backend.c

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
@@ -33,3 +33,7 @@
     ffi, lib = zeffir.open('basic', relative_to=zeffir_lib_path)
     assert lib.forty_two == 42
     assert type(lib.forty_two) is int
+
+def test_dir():
+    ffi, lib = zeffir.open('basic', relative_to=zeffir_lib_path)
+    assert dir(lib) == ['forty_two']
diff --git a/zeffir/zef_builder.c b/zeffir/zef_builder.c
new file mode 100644
--- /dev/null
+++ b/zeffir/zef_builder.c
@@ -0,0 +1,248 @@
+
+#define MAGIC_CREFLECT_TAG  0x54822e00
+#define CREFLECT_VERSION    0x01
+
+typedef struct {
+    _crx_builder_t cb;
+    PyLibObject *lib;
+    PyFFIObject *ffi;
+    PyObject *dict;
+} zeffir_builder_t;
+
+static PyObject *zef_cache_primitive_signed;
+
+static _crx_type_t *zef_get_void_type(_crx_builder_t *cb)
+{
+    abort();
+}
+
+static _crx_type_t *zef_get_char_type(_crx_builder_t *cb)
+{
+    abort();
+}
+
+static _crx_type_t *zef_get_bool_type(_crx_builder_t *cb)
+{
+    abort();
+}
+
+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;
+
+    if (td == NULL) {
+        int err;
+        size_t name_length = strlen(name);
+
+        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;
+
+        x = (PyObject *)td;
+        err = PyDict_SetItemString(zef_cache_primitive_signed, name, x);
+        Py_DECREF(x);
+        if (err < 0)
+            return NULL;
+    }
+    return td;
+}
+
+static _crx_type_t *zef_get_unsigned_type(_crx_builder_t *cb, size_t sz,
+                                          const char *g)
+{
+    abort();
+}
+
+static _crx_type_t *zef_get_float_type(_crx_builder_t *cb, size_t sz,
+                                       const char *g)
+{
+    abort();
+}
+
+static _crx_type_t *zef_get_function_type(_crx_builder_t *cb, _crx_type_t *ret,
+                                          _crx_type_t *args[], int nargs,
+                                          _crx_trampoline1_fn trampl)
+{
+    abort();
+}
+
+static _crx_type_t *zef_get_ellipsis_function_type(_crx_builder_t *cb,
+                                                   _crx_type_t *ret,
+                                                   _crx_type_t *args[],
+                                                   int nargs)
+{
+    abort();
+}
+
+static _crx_type_t *zef_get_pointer_type(_crx_builder_t *cb, _crx_type_t *t)
+{
+    abort();
+}
+
+static _crx_type_t *zef_get_const_type(_crx_builder_t *cb, _crx_type_t *t)
+{
+    abort();
+}
+
+static _crx_type_t *zef_get_array_type(_crx_builder_t *cb, _crx_type_t *t,
+                                       size_t len)
+{
+    abort();
+}
+
+static _crx_type_t *zef_get_incomplete_array_type(_crx_builder_t *cb,
+                                                  _crx_type_t *t)
+{
+    abort();
+}
+
+static _crx_type_t *zef_get_struct_type(_crx_builder_t *cb, const char *name)
+{
+    abort();
+}
+
+static _crx_type_t *zef_get_union_type(_crx_builder_t *cb, const char *name)
+{
+    abort();
+}
+
+static _crx_type_t *zef_get_enum_type(_crx_builder_t *cb, const char *name)
+{
+    abort();
+}
+
+static _crx_type_t *zef_get_user_type(_crx_builder_t *cb, const char *name)
+{
+    abort();
+}
+
+static _crx_type_t *zef_get_unknown_type(_crx_builder_t *cb, const char *name)
+{
+    abort();
+}
+
+static void zef_complete(_crx_builder_t *cb, _crx_type_t *t,
+                         size_t sz, size_t align,
+                         _crx_field_t fields[], int nfields)
+{
+    abort();
+}
+
+static void zef_complete_enum(_crx_builder_t *cb, _crx_type_t *t,
+                              _crx_type_t *inttype)
+{
+    abort();
+}
+
+static void zef_define_type(_crx_builder_t *cb, const char *name,
+                            _crx_type_t *t)
+{
+    abort();
+}
+
+static void zef_define_var(_crx_builder_t *cb, const char *name,
+                           _crx_type_t *t, void *addr)
+{
+    abort();
+}
+
+static void zef_define_func(_crx_builder_t *cb, const char *name,
+                            _crx_type_t *ret, _crx_type_t *args[], int nargs,
+                            _crx_trampoline0_fn trampl, void *directcall)
+{
+    abort();
+}
+
+static void zef_define_num_const(_crx_builder_t *cb, const char *name,
+                                 _crx_type_t *t, _crx_num_const_t *value)
+{
+    PyObject *dict = ((zeffir_builder_t *)cb)->dict;
+
+    PyObject *x = PyInt_FromLong(value->as_int);
+    if (x == NULL)
+        return;
+
+    PyDict_SetItemString(dict, name, x);
+    Py_DECREF(x);
+}
+
+static void zef_error(_crx_builder_t *cb, const char *msg)
+{
+    abort();
+}
+
+static int load_creflect_main(PyLibObject *lib)
+{
+    const char *creflect_main = "_creflect_main";   /* XXX fixed for now */
+    int (*crxmain)(_crx_builder_t *);
+    crxmain = (int(*)(_crx_builder_t *))dlsym(lib->ffi->dl_lib, creflect_main);
+    if (crxmain == NULL) {
+        PyErr_Format(PyExc_OSError, "%s: symbol '%s' not found",
+                     lib->ffi->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->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->libname, result & 0xFF,
+                     CREFLECT_VERSION);
+        return -1;
+    }
+
+    zeffir_builder_t builder = {
+        {
+            zef_get_void_type,
+            zef_get_char_type,
+            zef_get_bool_type,
+            zef_get_signed_type,
+            zef_get_unsigned_type,
+            zef_get_float_type,
+            zef_get_function_type,
+            zef_get_ellipsis_function_type,
+            zef_get_pointer_type,
+            zef_get_const_type,
+            zef_get_array_type,
+            zef_get_incomplete_array_type,
+            zef_get_struct_type,
+            zef_get_union_type,
+            zef_get_enum_type,
+            zef_get_user_type,
+            zef_get_unknown_type,
+            zef_complete,
+            zef_complete_enum,
+            zef_define_type,
+            zef_define_var,
+            zef_define_func,
+            zef_define_num_const,
+            zef_error,
+        },
+        lib,        /* lib */
+        lib->ffi,   /* ffi */
+        lib->dict,  /* 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_ctype.c b/zeffir/zef_ctype.c
new file mode 100644
--- /dev/null
+++ b/zeffir/zef_ctype.c
@@ -0,0 +1,141 @@
+
+/* base type flag: exactly one of the following: */
+#define CT_PRIMITIVE_SIGNED   1    /* signed integer */
+#define CT_PRIMITIVE_UNSIGNED 2    /* unsigned integer, bool */
+#define CT_PRIMITIVE_CHAR     4    /* char */
+#define CT_PRIMITIVE_FLOAT    8    /* float, double, long double */
+#define CT_POINTER           16    /* pointer, excluding ptr-to-func */
+#define CT_ARRAY             32    /* array */
+#define CT_STRUCT            64    /* struct */
+#define CT_UNION            128    /* union */
+#define CT_FUNCTIONPTR      256    /* pointer to function */
+#define CT_VOID             512    /* void */
+
+/* other flags that may also be set in addition to the base flag: */
+#define CT_CAST_ANYTHING         1024    /* 'char *' and 'void *' only */
+#define CT_PRIMITIVE_FITS_LONG   2048
+#define CT_IS_OPAQUE             4096
+#define CT_IS_ENUM               8192
+#define CT_IS_PTR_TO_OWNED      16384
+#define CT_IS_LONGDOUBLE        65536
+#define CT_IS_BOOL             131072
+#define CT_IS_VOID_PTR         524288
+#define CT_WITH_VAR_ARRAY     1048576
+#define CT_PRIMITIVE_ANY  (CT_PRIMITIVE_SIGNED |        \
+                           CT_PRIMITIVE_UNSIGNED |      \
+                           CT_PRIMITIVE_CHAR |          \
+                           CT_PRIMITIVE_FLOAT)
+
+struct _crx_type_s {
+    PyObject_VAR_HEAD
+
+    CTypeDescrObject *ct_itemdescr;    /* ptrs and arrays: the item type */
+    PyObject *ct_stuff;                /* structs: dict of the fields
+                                          arrays: ctypedescr of the ptr type
+                                          function: tuple(abi, ctres, ctargs..)
+                                          enum: pair {"name":x},{x:"name"}
+                                          ptrs: lazily, ctypedescr of array */
+    //void *ct_extra;                    /* structs: first field (not a ref!)
+    //                                      function types: cif_description
+    //                                      primitives: prebuilt "cif" object 
*/
+
+    PyObject *ct_weakreflist;    /* weakref support */
+
+    Py_ssize_t ct_size;     /* size of instances, or -1 if unknown */
+    Py_ssize_t ct_length;   /* length of arrays, or -1 if unknown */
+    int ct_flags;           /* CT_xxx flags */
+
+    int ct_name_position;   /* index in ct_name of where to put a var name */
+    char ct_name[1];        /* string, e.g. "int *" for pointers to ints */
+};
+
+static PyTypeObject CTypeDescr_Type;
+//static PyTypeObject CField_Type;
+//static PyTypeObject CData_Type;
+//static PyTypeObject CDataOwning_Type;
+//static PyTypeObject CDataOwningGC_Type;
+
+#define CTypeDescr_Check(ob)  (Py_TYPE(ob) == &CTypeDescr_Type)
+#define CData_Check(ob)       (Py_TYPE(ob) == &CData_Type ||            \
+                               Py_TYPE(ob) == &CDataOwning_Type ||      \
+                               Py_TYPE(ob) == &CDataOwningGC_Type)
+#define CDataOwn_Check(ob)    (Py_TYPE(ob) == &CDataOwning_Type ||      \
+                               Py_TYPE(ob) == &CDataOwningGC_Type)
+
+/************************************************************/
+
+static CTypeDescrObject *ctypedescr_new(size_t name_size)
+{
+    CTypeDescrObject *ct = PyObject_GC_NewVar(CTypeDescrObject,
+                                              &CTypeDescr_Type,
+                                              name_size);
+    if (ct == NULL)
+        return NULL;
+
+    ct->ct_itemdescr = NULL;
+    ct->ct_stuff = NULL;
+    ct->ct_weakreflist = NULL;
+    ct->ct_size = -1;
+    ct->ct_length = -1;
+    PyObject_GC_Track(ct);
+    return ct;
+}
+
+static void ctypedescr_dealloc(CTypeDescrObject *ct)
+{
+    PyObject_GC_UnTrack(ct);
+    if (ct->ct_weakreflist != NULL)
+        PyObject_ClearWeakRefs((PyObject *) ct);
+    Py_XDECREF(ct->ct_itemdescr);
+    Py_XDECREF(ct->ct_stuff);
+    //if (ct->ct_flags & CT_FUNCTIONPTR)
+    //    PyObject_Free(ct->ct_extra);
+    Py_TYPE(ct)->tp_free((PyObject *)ct);
+}
+
+static int ctypedescr_traverse(CTypeDescrObject *ct, visitproc visit, void 
*arg)
+{
+    Py_VISIT(ct->ct_itemdescr);
+    Py_VISIT(ct->ct_stuff);
+    return 0;
+}
+
+static int ctypedescr_clear(CTypeDescrObject *ct)
+{
+    Py_CLEAR(ct->ct_itemdescr);
+    Py_CLEAR(ct->ct_stuff);
+    return 0;
+}
+
+static PyTypeObject CTypeDescr_Type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "_cffi_backend.CTypeDescr",
+    offsetof(CTypeDescrObject, ct_name),
+    sizeof(char),
+    (destructor)ctypedescr_dealloc,             /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    0,//(reprfunc)ctypedescr_repr,                  /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)ctypedescr_traverse,          /* tp_traverse */
+    (inquiry)ctypedescr_clear,                  /* tp_clear */
+    0,                                          /* tp_richcompare */
+    offsetof(CTypeDescrObject, ct_weakreflist), /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,//ctypedescr_methods,                         /* tp_methods */
+    0,                                          /* tp_members */
+    0,//ctypedescr_getsets,                         /* tp_getset */
+};
diff --git a/zeffir/zef_ffi_obj.c b/zeffir/zef_ffi_obj.c
new file mode 100644
--- /dev/null
+++ b/zeffir/zef_ffi_obj.c
@@ -0,0 +1,51 @@
+
+struct PyFFIObject_s {
+    PyObject_HEAD
+    void *dl_lib;
+    char *libname;
+};
+
+static void ffi_dealloc(PyFFIObject *ffi)
+{
+    if (ffi->dl_lib != NULL)
+        dlclose(ffi->dl_lib);
+    free(ffi->libname);
+    PyObject_Del(ffi);
+}
+
+static PyObject *ffi_repr(PyFFIObject *ffi)
+{
+    return PyString_FromFormat("<zeffir.FFI object for '%s'>", ffi->libname);
+}
+
+static PyTypeObject FFI_Type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "zeffir.FFI",
+    sizeof(PyFFIObject),
+    0,
+    (destructor)ffi_dealloc,                    /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)ffi_repr,                         /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
+    0,                                          /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    0,                                          /* tp_members */
+};
diff --git a/zeffir/zef_funcs.c b/zeffir/zef_funcs.c
new file mode 100644
--- /dev/null
+++ b/zeffir/zef_funcs.c
@@ -0,0 +1,77 @@
+
+static PyObject *b_open(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    char *keywords[] = {"libname", "relative_to", NULL};
+    char *libname, *relative_to;
+    char *path;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss", keywords,
+                                     &libname, &relative_to))
+        return NULL;
+
+    char *last_slash = strrchr(relative_to, '/');
+    if (last_slash == NULL) {
+        relative_to = "./";
+        last_slash = relative_to + 1;
+    }
+    size_t n = last_slash + 1 - relative_to;
+    path = malloc(n + strlen(libname) + 16);
+    if (path == NULL)
+        return PyErr_NoMemory();
+    memcpy(path, relative_to, n);
+    strcpy(path + n, "lib");
+    strcat(path + n, libname);
+    strcat(path + n, ".so");
+
+    PyFFIObject *ffi = NULL;
+    PyLibObject *lib = NULL;
+    PyObject *dict = NULL;
+
+    dlerror();   /* clear errors */
+    void *dl_lib = dlopen(path, RTLD_LAZY);
+    if (dl_lib == NULL) {
+        char *error = dlerror();
+        if (error == NULL)
+            error = "failed to open";
+        PyErr_Format(PyExc_OSError, "%s: %s", path, error);
+        goto error;
+    }
+
+    ffi = PyObject_New(PyFFIObject, &FFI_Type);
+    if (ffi == NULL)
+        goto error;
+    ffi->dl_lib = dl_lib;  dl_lib = NULL;
+    ffi->libname = path;   path = NULL;
+
+    dict = PyDict_New();
+    if (dict == NULL)
+        goto error;
+
+    lib = PyObject_New(PyLibObject, &Lib_Type);
+    if (lib == NULL)
+        goto error;
+    lib->ffi = ffi;    ffi = NULL;
+    lib->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);
+    free(path);
+    return NULL;
+}
+
+
+static PyMethodDef ZeffirMethods[] = {
+    {"open",   (PyCFunction)b_open, METH_KEYWORDS},
+    {NULL,     NULL}    /* Sentinel */
+};
diff --git a/zeffir/zef_lib_obj.c b/zeffir/zef_lib_obj.c
new file mode 100644
--- /dev/null
+++ b/zeffir/zef_lib_obj.c
@@ -0,0 +1,72 @@
+
+struct PyLibObject_s {
+    PyObject_HEAD
+    PyObject *dict;
+    PyFFIObject *ffi;
+};
+
+static void lib_dealloc(PyLibObject *lib)
+{
+    Py_DECREF(lib->dict);
+    Py_DECREF(lib->ffi);
+    PyObject_Del(lib);
+}
+
+static PyObject *lib_repr(PyLibObject *lib)
+{
+    return PyString_FromFormat("<zeffir.Lib object for '%s'>",
+                               lib->ffi->libname);
+}
+
+static PyObject *lib_dir(PyObject *lib, PyObject *noarg)
+{
+    return PyDict_Keys(((PyLibObject *)lib)->dict);
+}
+
+static PyMethodDef lib_methods[] = {
+    {"__dir__",   lib_dir,  METH_NOARGS},
+    {NULL,        NULL}           /* sentinel */
+};
+
+static PyMemberDef lib_members[] = {
+    {"__dict__", T_OBJECT, offsetof(PyLibObject, dict), READONLY},
+    {NULL}
+};
+
+static PyTypeObject Lib_Type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "zeffir.Lib",
+    sizeof(PyLibObject),
+    0,
+    (destructor)lib_dealloc,                    /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)lib_repr,                         /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
+    0,                                          /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    lib_methods,                                /* tp_methods */
+    lib_members,                                /* tp_members */
+    0,                                          /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    offsetof(PyLibObject, dict),                /* tp_dictoffset */
+};
diff --git a/zeffir/zeffir.c b/zeffir/zeffir.c
--- a/zeffir/zeffir.c
+++ b/zeffir/zeffir.c
@@ -5,417 +5,23 @@
 #include "../creflect/creflect_cdecl.h"
 
 
-#define MAGIC_CREFLECT_TAG  0x54822e00
-#define CREFLECT_VERSION    0x01
+typedef struct _crx_type_s CTypeDescrObject;
+typedef struct PyLibObject_s PyLibObject;
+typedef struct PyFFIObject_s PyFFIObject;
 
 
 /************************************************************/
+/* Works by including all other .c files.                   */
+/* Allows all function and global symbols to remain static. */
 
-typedef struct {
-    PyObject_HEAD
-    void *dl_lib;
-    char *libname;
-} PyFFIObject;
-
-static void ffi_dealloc(PyFFIObject *ffi)
-{
-    if (ffi->dl_lib != NULL)
-        dlclose(ffi->dl_lib);
-    free(ffi->libname);
-    PyObject_Del(ffi);
-}
-
-static PyObject *ffi_repr(PyFFIObject *ffi)
-{
-    return PyString_FromFormat("<zeffir.FFI object for '%s'>", ffi->libname);
-}
-
-static PyTypeObject FFI_Type = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "zeffir.FFI",
-    sizeof(PyFFIObject),
-    0,
-    (destructor)ffi_dealloc,                    /* tp_dealloc */
-    0,                                          /* tp_print */
-    0,                                          /* tp_getattr */
-    0,                                          /* tp_setattr */
-    0,                                          /* tp_compare */
-    (reprfunc)ffi_repr,                         /* tp_repr */
-    0,                                          /* tp_as_number */
-    0,                                          /* tp_as_sequence */
-    0,                                          /* tp_as_mapping */
-    0,                                          /* tp_hash */
-    0,                                          /* tp_call */
-    0,                                          /* tp_str */
-    PyObject_GenericGetAttr,                    /* tp_getattro */
-    0,                                          /* tp_setattro */
-    0,                                          /* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
-    0,                                          /* tp_doc */
-    0,                                          /* tp_traverse */
-    0,                                          /* tp_clear */
-    0,                                          /* tp_richcompare */
-    0,                                          /* tp_weaklistoffset */
-    0,                                          /* tp_iter */
-    0,                                          /* tp_iternext */
-    0,                                          /* tp_methods */
-    0,                                          /* tp_members */
-};
+#include "zef_ctype.c"
+#include "zef_ffi_obj.c"
+#include "zef_lib_obj.c"
+#include "zef_builder.c"
+#include "zef_funcs.c"
 
 /************************************************************/
 
-typedef struct {
-    PyObject_HEAD
-    PyObject *dict;
-    PyFFIObject *ffi;
-} PyLibObject;
-
-static PyMemberDef lib_members[] = {
-    {"__dict__", T_OBJECT, offsetof(PyLibObject, dict), READONLY},
-    {NULL}
-};
-
-static void lib_dealloc(PyLibObject *lib)
-{
-    Py_DECREF(lib->dict);
-    Py_DECREF(lib->ffi);
-    PyObject_Del(lib);
-}
-
-static PyObject *lib_repr(PyLibObject *lib)
-{
-    return PyString_FromFormat("<zeffir.Lib object for '%s'>",
-                               lib->ffi->libname);
-}
-
-static PyTypeObject Lib_Type = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "zeffir.Lib",
-    sizeof(PyLibObject),
-    0,
-    (destructor)lib_dealloc,                    /* tp_dealloc */
-    0,                                          /* tp_print */
-    0,                                          /* tp_getattr */
-    0,                                          /* tp_setattr */
-    0,                                          /* tp_compare */
-    (reprfunc)lib_repr,                         /* tp_repr */
-    0,                                          /* tp_as_number */
-    0,                                          /* tp_as_sequence */
-    0,                                          /* tp_as_mapping */
-    0,                                          /* tp_hash */
-    0,                                          /* tp_call */
-    0,                                          /* tp_str */
-    PyObject_GenericGetAttr,                    /* tp_getattro */
-    0,                                          /* tp_setattro */
-    0,                                          /* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
-    0,                                          /* tp_doc */
-    0,                                          /* tp_traverse */
-    0,                                          /* tp_clear */
-    0,                                          /* tp_richcompare */
-    0,                                          /* tp_weaklistoffset */
-    0,                                          /* tp_iter */
-    0,                                          /* tp_iternext */
-    0,                                          /* tp_methods */
-    lib_members,                                /* tp_members */
-    0,                                          /* tp_getset */
-    0,                                          /* tp_base */
-    0,                                          /* tp_dict */
-    0,                                          /* tp_descr_get */
-    0,                                          /* tp_descr_set */
-    offsetof(PyLibObject, dict),                /* tp_dictoffset */
-};
-
-/************************************************************/
-
-typedef struct {
-    _crx_builder_t cb;
-    PyLibObject *lib;
-    PyFFIObject *ffi;
-    PyObject *dict;
-} zeffir_builder_t;
-
-static _crx_type_t *zef_get_void_type(_crx_builder_t *cb)
-{
-    abort();
-}
-
-static _crx_type_t *zef_get_char_type(_crx_builder_t *cb)
-{
-    abort();
-}
-
-static _crx_type_t *zef_get_bool_type(_crx_builder_t *cb)
-{
-    abort();
-}
-
-static _crx_type_t *zef_get_signed_type(_crx_builder_t *cb, size_t sz,
-                                        const char *g)
-{
-    return NULL;  // XXX
-}
-
-static _crx_type_t *zef_get_unsigned_type(_crx_builder_t *cb, size_t sz,
-                                          const char *g)
-{
-    abort();
-}
-
-static _crx_type_t *zef_get_float_type(_crx_builder_t *cb, size_t sz,
-                                       const char *g)
-{
-    abort();
-}
-
-static _crx_type_t *zef_get_function_type(_crx_builder_t *cb, _crx_type_t *ret,
-                                          _crx_type_t *args[], int nargs,
-                                          _crx_trampoline1_fn trampl)
-{
-    abort();
-}
-
-static _crx_type_t *zef_get_ellipsis_function_type(_crx_builder_t *cb,
-                                                   _crx_type_t *ret,
-                                                   _crx_type_t *args[],
-                                                   int nargs)
-{
-    abort();
-}
-
-static _crx_type_t *zef_get_pointer_type(_crx_builder_t *cb, _crx_type_t *t)
-{
-    abort();
-}
-
-static _crx_type_t *zef_get_const_type(_crx_builder_t *cb, _crx_type_t *t)
-{
-    abort();
-}
-
-static _crx_type_t *zef_get_array_type(_crx_builder_t *cb, _crx_type_t *t,
-                                       size_t len)
-{
-    abort();
-}
-
-static _crx_type_t *zef_get_incomplete_array_type(_crx_builder_t *cb,
-                                                  _crx_type_t *t)
-{
-    abort();
-}
-
-static _crx_type_t *zef_get_struct_type(_crx_builder_t *cb, const char *name)
-{
-    abort();
-}
-
-static _crx_type_t *zef_get_union_type(_crx_builder_t *cb, const char *name)
-{
-    abort();
-}
-
-static _crx_type_t *zef_get_enum_type(_crx_builder_t *cb, const char *name)
-{
-    abort();
-}
-
-static _crx_type_t *zef_get_user_type(_crx_builder_t *cb, const char *name)
-{
-    abort();
-}
-
-static _crx_type_t *zef_get_unknown_type(_crx_builder_t *cb, const char *name)
-{
-    abort();
-}
-
-static void zef_complete(_crx_builder_t *cb, _crx_type_t *t,
-                         size_t sz, size_t align,
-                         _crx_field_t fields[], int nfields)
-{
-    abort();
-}
-
-static void zef_complete_enum(_crx_builder_t *cb, _crx_type_t *t,
-                              _crx_type_t *inttype)
-{
-    abort();
-}
-
-static void zef_define_type(_crx_builder_t *cb, const char *name,
-                            _crx_type_t *t)
-{
-    abort();
-}
-
-static void zef_define_var(_crx_builder_t *cb, const char *name,
-                           _crx_type_t *t, void *addr)
-{
-    abort();
-}
-
-static void zef_define_func(_crx_builder_t *cb, const char *name,
-                            _crx_type_t *ret, _crx_type_t *args[], int nargs,
-                            _crx_trampoline0_fn trampl, void *directcall)
-{
-    abort();
-}
-
-static void zef_define_num_const(_crx_builder_t *cb, const char *name,
-                                 _crx_type_t *t, _crx_num_const_t *value)
-{
-    PyObject *dict = ((zeffir_builder_t *)cb)->dict;
-
-    PyObject *x = PyInt_FromLong(value->as_int);
-    if (x == NULL)
-        return;
-
-    PyDict_SetItemString(dict, name, x);
-    Py_DECREF(x);
-}
-
-static void zef_error(_crx_builder_t *cb, const char *msg)
-{
-    abort();
-}
-
-static int load_creflect_main(PyLibObject *lib)
-{
-    const char *creflect_main = "_creflect_main";   /* XXX fixed for now */
-    int (*crxmain)(_crx_builder_t *);
-    crxmain = (int(*)(_crx_builder_t *))dlsym(lib->ffi->dl_lib, creflect_main);
-    if (crxmain == NULL) {
-        PyErr_Format(PyExc_OSError, "%s: symbol '%s' not found",
-                     lib->ffi->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->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->libname, result & 0xFF,
-                     CREFLECT_VERSION);
-        return -1;
-    }
-
-    zeffir_builder_t builder = {
-        {
-            zef_get_void_type,
-            zef_get_char_type,
-            zef_get_bool_type,
-            zef_get_signed_type,
-            zef_get_unsigned_type,
-            zef_get_float_type,
-            zef_get_function_type,
-            zef_get_ellipsis_function_type,
-            zef_get_pointer_type,
-            zef_get_const_type,
-            zef_get_array_type,
-            zef_get_incomplete_array_type,
-            zef_get_struct_type,
-            zef_get_union_type,
-            zef_get_enum_type,
-            zef_get_user_type,
-            zef_get_unknown_type,
-            zef_complete,
-            zef_complete_enum,
-            zef_define_type,
-            zef_define_var,
-            zef_define_func,
-            zef_define_num_const,
-            zef_error,
-        },
-        lib,        /* lib */
-        lib->ffi,   /* ffi */
-        lib->dict,  /* dict */
-    };
-    crxmain(&builder.cb);
-    return PyErr_Occurred() ? -1 : 0;
-}
-
-static PyObject *b_open(PyObject *self, PyObject *args, PyObject *kwds)
-{
-    char *keywords[] = {"libname", "relative_to", NULL};
-    char *libname, *relative_to;
-    char *path;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss", keywords,
-                                     &libname, &relative_to))
-        return NULL;
-
-    char *last_slash = strrchr(relative_to, '/');
-    if (last_slash == NULL) {
-        relative_to = "./";
-        last_slash = relative_to + 1;
-    }
-    size_t n = last_slash + 1 - relative_to;
-    path = malloc(n + strlen(libname) + 16);
-    if (path == NULL)
-        return PyErr_NoMemory();
-    memcpy(path, relative_to, n);
-    strcpy(path + n, "lib");
-    strcat(path + n, libname);
-    strcat(path + n, ".so");
-
-    PyFFIObject *ffi = NULL;
-    PyLibObject *lib = NULL;
-    PyObject *dict = NULL;
-
-    dlerror();   /* clear errors */
-    void *dl_lib = dlopen(path, RTLD_LAZY);
-    if (dl_lib == NULL) {
-        char *error = dlerror();
-        if (error == NULL)
-            error = "failed to open";
-        PyErr_Format(PyExc_OSError, "%s: %s", path, error);
-        goto error;
-    }
-
-    ffi = PyObject_New(PyFFIObject, &FFI_Type);
-    if (ffi == NULL)
-        goto error;
-    ffi->dl_lib = dl_lib;  dl_lib = NULL;
-    ffi->libname = path;   path = NULL;
-
-    dict = PyDict_New();
-    if (dict == NULL)
-        goto error;
-
-    lib = PyObject_New(PyLibObject, &Lib_Type);
-    if (lib == NULL)
-        goto error;
-    lib->ffi = ffi;    ffi = NULL;
-    lib->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);
-    free(path);
-    return NULL;
-}
-
-
-static PyMethodDef ZeffirMethods[] = {
-    {"open",   (PyCFunction)b_open, METH_KEYWORDS},
-    {NULL,     NULL}    /* Sentinel */
-};
-
 PyMODINIT_FUNC
 initzeffir(void)
 {
@@ -424,6 +30,12 @@
     m = Py_InitModule("zeffir", ZeffirMethods);
     (void)m;
 
-    PyType_Ready(&FFI_Type);
-    PyType_Ready(&Lib_Type);
+    init_caches();
+    if (PyErr_Occurred())
+        return;
+
+    if (PyType_Ready(&FFI_Type) < 0)
+        return;
+    if (PyType_Ready(&Lib_Type) < 0)
+        return;
 }
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to