[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