[pypy-commit] cffi cffi-1.0: Make ffi->types_builder an inlined struct; add a ref from the lib to the ffi

arigo noreply at buildbot.pypy.org
Mon May 11 12:10:05 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r1970:03470b52f5a3
Date: 2015-05-11 12:10 +0200
http://bitbucket.org/cffi/cffi/changeset/03470b52f5a3/

Log:	Make ffi->types_builder an inlined struct; add a ref from the lib to
	the ffi

diff --git a/_cffi1/cffi1_module.c b/_cffi1/cffi1_module.c
--- a/_cffi1/cffi1_module.c
+++ b/_cffi1/cffi1_module.c
@@ -169,12 +169,12 @@
     if (ffi == NULL || PyModule_AddObject(m, "ffi", (PyObject *)ffi) < 0)
         return NULL;
 
-    lib = lib_internal_new(ffi->types_builder, module_name);
+    lib = lib_internal_new(ffi, module_name);
     if (lib == NULL || PyModule_AddObject(m, "lib", (PyObject *)lib) < 0)
         return NULL;
 
     if (make_included_tuples(module_name, ctx->includes,
-                             &ffi->types_builder->included_ffis,
+                             &ffi->types_builder.included_ffis,
                              &lib->l_includes) < 0)
         return NULL;
 
diff --git a/_cffi1/ffi_obj.c b/_cffi1/ffi_obj.c
--- a/_cffi1/ffi_obj.c
+++ b/_cffi1/ffi_obj.c
@@ -25,7 +25,7 @@
     PyObject *gc_wrefs;
     struct _cffi_parse_info_s info;
     int ctx_is_static;
-    builder_c_t *types_builder;
+    builder_c_t types_builder;
 };
 
 static FFIObject *ffi_internal_new(PyTypeObject *ffitype,
@@ -45,13 +45,12 @@
     if (ffi == NULL)
         return NULL;
 
-    ffi->types_builder = new_builder_c(static_ctx);
-    if (ffi->types_builder == NULL) {
+    if (init_builder_c(&ffi->types_builder, static_ctx) < 0) {
         Py_DECREF(ffi);
         return NULL;
     }
     ffi->gc_wrefs = NULL;
-    ffi->info.ctx = &ffi->types_builder->ctx;
+    ffi->info.ctx = &ffi->types_builder.ctx;
     ffi->info.output = internal_output;
     ffi->info.output_size = FFI_COMPLEXITY_OUTPUT;
     ffi->ctx_is_static = (static_ctx != NULL);
@@ -70,15 +69,15 @@
 #endif
 
     if (!ffi->ctx_is_static)
-        free_builder_c(ffi->types_builder);
+        free_dynamic_builder_c(&ffi->types_builder);
 
     Py_TYPE(ffi)->tp_free((PyObject *)ffi);
 }
 
 static int ffi_traverse(FFIObject *ffi, visitproc visit, void *arg)
 {
-    Py_VISIT(ffi->types_builder->types_dict);
-    Py_VISIT(ffi->types_builder->included_ffis);
+    Py_VISIT(ffi->types_builder.types_dict);
+    Py_VISIT(ffi->types_builder.included_ffis);
     Py_VISIT(ffi->gc_wrefs);
     return 0;
 }
@@ -110,7 +109,7 @@
        Does not return a new reference!
     */
     if ((accept & ACCEPT_STRING) && PyText_Check(arg)) {
-        PyObject *types_dict = ffi->types_builder->types_dict;
+        PyObject *types_dict = ffi->types_builder.types_dict;
         PyObject *x = PyDict_GetItem(types_dict, arg);
 
         if (x == NULL) {
@@ -125,7 +124,7 @@
                              input_text, spaces);
                 return NULL;
             }
-            x = realize_c_type_or_func(ffi->types_builder,
+            x = realize_c_type_or_func(&ffi->types_builder,
                                        ffi->info.output, index);
             if (x == NULL)
                 return NULL;
@@ -749,12 +748,12 @@
     Py_INCREF(args);     /* to keep alive the strings in '.name' */
     Py_XDECREF(self->dynamic_types);
     self->dynamic_types = args;
-    self->types_builder->ctx.types = types;
-    self->types_builder->num_types_imported = lst1_length + lst2_length;
-    self->types_builder->ctx.struct_unions = struct_unions;
-    self->types_builder->ctx.num_struct_unions = lst1_length;
-    self->types_builder->ctx.typenames = typenames;
-    self->types_builder->ctx.num_typenames = lst2_length;
+    self->types_builder.ctx.types = types;
+    self->types_builder.num_types_imported = lst1_length + lst2_length;
+    self->types_builder.ctx.struct_unions = struct_unions;
+    self->types_builder.ctx.num_struct_unions = lst1_length;
+    self->types_builder.ctx.typenames = typenames;
+    self->types_builder.ctx.num_typenames = lst2_length;
 
     Py_INCREF(Py_None);
     return Py_None;
@@ -855,19 +854,19 @@
         PyObject *x;
 
         ffi1 = (FFIObject *)PyTuple_GET_ITEM(included_ffis, i);
-        sindex = search_in_struct_unions(&ffi1->types_builder->ctx, s->name,
+        sindex = search_in_struct_unions(&ffi1->types_builder.ctx, s->name,
                                          strlen(s->name));
         if (sindex < 0)  /* not found at all */
             continue;
-        s1 = &ffi1->types_builder->ctx.struct_unions[sindex];
+        s1 = &ffi1->types_builder.ctx.struct_unions[sindex];
         if ((s1->flags & (_CFFI_F_EXTERNAL | _CFFI_F_UNION))
                 == (s->flags & _CFFI_F_UNION)) {
             /* s1 is not external, and the same kind (struct or union) as s */
-            return _realize_c_struct_or_union(ffi1->types_builder, sindex);
+            return _realize_c_struct_or_union(&ffi1->types_builder, sindex);
         }
         /* not found, look more recursively */
         x = _fetch_external_struct_or_union(
-                s, ffi1->types_builder->included_ffis, recursion + 1);
+                s, ffi1->types_builder.included_ffis, recursion + 1);
         if (x != NULL || PyErr_Occurred())
             return x;   /* either found, or got an error */
     }
diff --git a/_cffi1/lib_obj.c b/_cffi1/lib_obj.c
--- a/_cffi1/lib_obj.c
+++ b/_cffi1/lib_obj.c
@@ -24,6 +24,7 @@
     PyObject *l_dict;           /* content, built lazily */
     PyObject *l_libname;        /* some string that gives the name of the lib */
     PyObject *l_includes;       /* tuple of LibObjects included here */
+    FFIObject *l_ffi;           /* reference back to the ffi object */
 };
 
 #define LibObject_Check(ob)  ((Py_TYPE(ob) == &Lib_Type))
@@ -67,9 +68,19 @@
     Py_DECREF(lib->l_dict);
     Py_DECREF(lib->l_libname);
     Py_XDECREF(lib->l_includes);
+    Py_DECREF(lib->l_ffi);
     PyObject_Del(lib);
 }
 
+static int lib_traverse(LibObject *lib, visitproc visit, void *arg)
+{
+    Py_VISIT(lib->l_dict);
+    Py_VISIT(lib->l_libname);
+    Py_VISIT(lib->l_includes);
+    Py_VISIT(lib->l_ffi);
+    return 0;
+}
+
 static PyObject *lib_repr(LibObject *lib)
 {
     return PyText_FromFormat("<Lib object for '%.200s'>",
@@ -344,7 +355,7 @@
     0,                                          /* tp_as_buffer */
     Py_TPFLAGS_DEFAULT,                         /* tp_flags */
     0,                                          /* tp_doc */
-    0,                                          /* tp_traverse */
+    (traverseproc)lib_traverse,                 /* tp_traverse */
     0,                                          /* tp_clear */
     0,                                          /* tp_richcompare */
     0,                                          /* tp_weaklistoffset */
@@ -360,8 +371,7 @@
     offsetof(LibObject, l_dict),                /* tp_dictoffset */
 };
 
-static LibObject *lib_internal_new(builder_c_t *types_builder,
-                                   char *module_name)
+static LibObject *lib_internal_new(FFIObject *ffi, char *module_name)
 {
     LibObject *lib;
     PyObject *libname, *dict;
@@ -378,9 +388,11 @@
     if (lib == NULL)
         return NULL;
 
-    lib->l_types_builder = types_builder;
+    lib->l_types_builder = &ffi->types_builder;
     lib->l_dict = dict;
     lib->l_libname = libname;
     lib->l_includes = NULL;
+    Py_INCREF(ffi);
+    lib->l_ffi = ffi;
     return lib;
 }
diff --git a/_cffi1/realize_c_type.c b/_cffi1/realize_c_type.c
--- a/_cffi1/realize_c_type.c
+++ b/_cffi1/realize_c_type.c
@@ -53,18 +53,9 @@
     return err;
 }
 
-static void cleanup_builder_c(builder_c_t *builder)
+static void free_dynamic_builder_c(builder_c_t *builder)
 {
     int i;
-#if 0
-    for (i = builder->num_types_imported; (--i) >= 0; ) {
-        _cffi_opcode_t x = builder->ctx.types[i];
-        if ((((uintptr_t)x) & 1) == 0) {
-            Py_XDECREF((PyObject *)x);
-        }
-    }
-#endif
-
     const void *mem[] = {builder->ctx.types,
                          builder->ctx.globals,
                          builder->ctx.struct_unions,
@@ -77,29 +68,16 @@
     }
 
     Py_XDECREF(builder->included_ffis);
-    builder->included_ffis = NULL;
+    Py_XDECREF(builder->types_dict);
 }
 
-static void free_builder_c(builder_c_t *builder)
+static int init_builder_c(builder_c_t *builder,
+                          const struct _cffi_type_context_s *ctx)
 {
-    Py_XDECREF(builder->types_dict);
-    cleanup_builder_c(builder);
-    PyMem_Free(builder);
-}
-
-static builder_c_t *new_builder_c(const struct _cffi_type_context_s *ctx)
-{
-    builder_c_t *builder;
     PyObject *ldict = PyDict_New();
     if (ldict == NULL)
-        return NULL;
+        return -1;
 
-    builder = PyMem_Malloc(sizeof(builder_c_t));
-    if (builder == NULL) {
-        Py_DECREF(ldict);
-        PyErr_NoMemory();
-        return NULL;
-    }
     if (ctx)
         builder->ctx = *ctx;
     else
@@ -107,10 +85,7 @@
 
     builder->types_dict = ldict;
     builder->included_ffis = NULL;
-#if 0
-    builder->num_types_imported = 0;
-#endif
-    return builder;
+    return 0;
 }
 
 static PyObject *build_primitive_type(int num)


More information about the pypy-commit mailing list