[pypy-commit] creflect default: The minimum (hum) to make the "assert lib.forty_two == 42" pass

arigo noreply at buildbot.pypy.org
Sun Nov 30 01:31:19 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r127:7464b4e4b27d
Date: 2014-11-30 01:31 +0100
http://bitbucket.org/cffi/creflect/changeset/7464b4e4b27d/

Log:	The minimum (hum) to make the "assert lib.forty_two == 42" pass

diff --git a/zeffir/zeffir.c b/zeffir/zeffir.c
--- a/zeffir/zeffir.c
+++ b/zeffir/zeffir.c
@@ -1,9 +1,14 @@
-#include <Python.h>
+#include "Python.h"
+#include "structmember.h"
 #include <dlfcn.h>
 #include "../creflect/creflect.h"
 #include "../creflect/creflect_cdecl.h"
 
 
+#define MAGIC_CREFLECT_TAG  0x54822e00
+#define CREFLECT_VERSION    0x01
+
+
 /************************************************************/
 
 typedef struct {
@@ -59,6 +64,281 @@
 
 /************************************************************/
 
+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};
@@ -83,6 +363,10 @@
     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) {
@@ -93,17 +377,33 @@
         goto error;
     }
 
-    PyFFIObject *ffi = PyObject_New(PyFFIObject, &FFI_Type);
+    ffi = PyObject_New(PyFFIObject, &FFI_Type);
     if (ffi == NULL)
         goto error;
-    ffi->dl_lib = dl_lib;
-    ffi->libname = path;
+    ffi->dl_lib = dl_lib;  dl_lib = NULL;
+    ffi->libname = path;   path = NULL;
 
-    PyObject *result = Py_BuildValue("OO", ffi, Py_None);
-    Py_DECREF(ffi);
+    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);
@@ -125,4 +425,5 @@
     (void)m;
 
     PyType_Ready(&FFI_Type);
+    PyType_Ready(&Lib_Type);
 }


More information about the pypy-commit mailing list