[pypy-commit] cffi cffi-1.0: progress on enums
arigo
noreply at buildbot.pypy.org
Fri Apr 24 17:15:19 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r1805:7231fd7eae98
Date: 2015-04-24 17:15 +0200
http://bitbucket.org/cffi/cffi/changeset/7231fd7eae98/
Log: progress on enums
diff --git a/_cffi1/_cffi_include.h b/_cffi1/_cffi_include.h
--- a/_cffi1/_cffi_include.h
+++ b/_cffi1/_cffi_include.h
@@ -162,10 +162,12 @@
#define _cffi_array_len(array) (sizeof(array) / sizeof((array)[0]))
#define _cffi_prim_int(size, sign) \
- ((size) == 1 ? ((sign) ? _CFFI_PRIM_INT8 : _CFFI_PRIM_UINT8) : \
- (size) == 2 ? ((sign) ? _CFFI_PRIM_INT16 : _CFFI_PRIM_UINT16) : \
- (size) == 4 ? ((sign) ? _CFFI_PRIM_INT32 : _CFFI_PRIM_UINT32) : \
- (size) == 8 ? ((sign) ? _CFFI_PRIM_INT64 : _CFFI_PRIM_UINT64) : \
+ ((size) == sizeof(int) ? ((sign) ? _CFFI_PRIM_INT : _CFFI_PRIM_UINT) : \
+ (size) == sizeof(long)? ((sign) ? _CFFI_PRIM_LONG : _CFFI_PRIM_ULONG) : \
+ (size) == 1 ? ((sign) ? _CFFI_PRIM_INT8 : _CFFI_PRIM_UINT8) : \
+ (size) == 2 ? ((sign) ? _CFFI_PRIM_INT16 : _CFFI_PRIM_UINT16) : \
+ (size) == 4 ? ((sign) ? _CFFI_PRIM_INT32 : _CFFI_PRIM_UINT32) : \
+ (size) == 8 ? ((sign) ? _CFFI_PRIM_INT64 : _CFFI_PRIM_UINT64) : \
0)
diff --git a/_cffi1/parse_c_type.h b/_cffi1/parse_c_type.h
--- a/_cffi1/parse_c_type.h
+++ b/_cffi1/parse_c_type.h
@@ -90,7 +90,8 @@
struct _cffi_enum_s {
const char *name;
- int type_prim; /* _CFFI_PRIM_xxx */
+ int type_index; // -> _cffi_types, on a OP_ENUM
+ int type_prim; // _CFFI_PRIM_xxx
};
struct _cffi_typename_s {
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
@@ -11,6 +11,10 @@
static PyObject *build_primitive_type(int num); /* forward */
+#define get_primitive_type(num) \
+ (all_primitives[num] != NULL ? all_primitives[num] \
+ : build_primitive_type(num))
+
static int init_global_types_dict(PyObject *ffi_type_dict)
{
int err;
@@ -20,7 +24,7 @@
if (global_types_dict == NULL)
return -1;
- ct = build_primitive_type(_CFFI_PRIM_VOID); // 'void'
+ ct = get_primitive_type(_CFFI_PRIM_VOID); // 'void'
if (ct == NULL)
return -1;
if (PyDict_SetItemString(global_types_dict,
@@ -260,9 +264,7 @@
switch (_CFFI_GETOP(op)) {
case _CFFI_OP_PRIMITIVE:
- x = all_primitives[_CFFI_GETARG(op)];
- if (x == NULL)
- x = build_primitive_type(_CFFI_GETARG(op));
+ x = get_primitive_type(_CFFI_GETARG(op));
Py_XINCREF(x);
break;
@@ -334,7 +336,7 @@
ct->ct_extra = builder;
}
- /* Update the "primary" OP_STRUCT_OR_UNION slot, which
+ /* Update the "primary" OP_STRUCT_UNION slot, which
may be the same or a different slot than the "current" one */
assert((((uintptr_t)x) & 1) == 0);
assert(builder->ctx.types[s->type_index] == op2);
@@ -363,12 +365,40 @@
case _CFFI_OP_ENUM:
{
const struct _cffi_enum_s *e;
+ _cffi_opcode_t op2;
e = &builder->ctx.enums[_CFFI_GETARG(op)];
- x = all_primitives[e->type_prim];
- if (x == NULL)
- x = build_primitive_type(e->type_prim);
- Py_XINCREF(x);
+ op2 = builder->ctx.types[e->type_index];
+ if ((((uintptr_t)op2) & 1) == 0) {
+ x = (PyObject *)op2;
+ Py_INCREF(x);
+ }
+ else {
+ PyObject *basetd = get_primitive_type(e->type_prim);
+ if (basetd == NULL)
+ return NULL;
+
+ PyObject *args = Py_BuildValue("(s()()O)", e->name, basetd);
+ if (args == NULL)
+ return NULL;
+
+ x = b_new_enum_type(NULL, args);
+ Py_DECREF(args);
+ if (x == NULL)
+ return NULL;
+
+ /* Update the "primary" _CFFI_OP_ENUM slot, which
+ may be the same or a different slot than the "current" one */
+ assert((((uintptr_t)x) & 1) == 0);
+ assert(builder->ctx.types[e->type_index] == op2);
+ Py_INCREF(x);
+ builder->ctx.types[e->type_index] = x;
+
+ /* Done, leave without updating the "current" slot because
+ it may be done already above. If not, never mind, the
+ next call to realize_c_type() will do it. */
+ return x;
+ }
break;
}
diff --git a/_cffi1/recompiler.py b/_cffi1/recompiler.py
--- a/_cffi1/recompiler.py
+++ b/_cffi1/recompiler.py
@@ -589,19 +589,14 @@
is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type()
self._generate_cpy_const(is_int, name, tp)
- def _generate_const_int_ctx(self, name):
- self._lsts["global"].append(
- ' { "%s", _cffi_const_%s, _CFFI_OP(_CFFI_OP_CONSTANT_INT, 0) },' %
- (name, name))
-
def _generate_cpy_constant_ctx(self, tp, name):
if isinstance(tp, model.PrimitiveType) and tp.is_integer_type():
- self._generate_const_int_ctx(name)
+ type_op = '_CFFI_OP(_CFFI_OP_CONSTANT_INT, 0)'
else:
type_index = self._typesdict[tp]
type_op = '_CFFI_OP(_CFFI_OP_CONSTANT, %d)' % type_index
- self._lsts["global"].append(
- ' { "%s", _cffi_const_%s, %s },' % (name, name, type_op))
+ self._lsts["global"].append(
+ ' { "%s", _cffi_const_%s, %s },' % (name, name, type_op))
# ----------
# enums
@@ -614,8 +609,13 @@
self._generate_cpy_const(True, enumerator)
def _enum_ctx(self, tp, cname):
+ type_index = self._typesdict[tp]
+ type_op = '_CFFI_OP(_CFFI_OP_ENUM, %d)' % type_index
for enumerator in tp.enumerators:
- self._generate_const_int_ctx(enumerator)
+ self._lsts["global"].append(
+ ' { "%s", _cffi_const_%s, %s },' % (enumerator, enumerator,
+ type_op))
+ #
if cname is not None:
size = "sizeof(%s)" % cname
signed = "((%s)-1) <= 0" % cname
@@ -623,7 +623,7 @@
else:
size = xxxx
self._lsts["enum"].append(
- ' { "%s", %s },' % (tp.name, prim))
+ ' { "%s", %d, %s },' % (tp.name, type_index, prim))
def _generate_cpy_enum_ctx(self, tp, name):
if tp.has_c_name():
More information about the pypy-commit
mailing list