Author: Armin Rigo <[email protected]>
Branch: cffi-1.0
Changeset: r1705:e725f4ea7673
Date: 2015-04-14 18:19 +0200
http://bitbucket.org/cffi/cffi/changeset/e725f4ea7673/
Log: in-progress: decoding function types while only having a
CT_FUNCTIONPTR...
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -1902,7 +1902,7 @@
return cd->c_data + i * cd->c_type->ct_itemdescr->ct_size;
}
-static CTypeDescrObject *
+static PyObject *
new_array_type(CTypeDescrObject *ctptr, Py_ssize_t length); /* forward */
static CTypeDescrObject *
@@ -1968,7 +1968,7 @@
return NULL;
if (ct->ct_stuff == NULL) {
- ct->ct_stuff = (PyObject *)new_array_type(ct, -1);
+ ct->ct_stuff = new_array_type(ct, -1);
if (ct->ct_stuff == NULL)
return NULL;
}
@@ -2269,18 +2269,13 @@
static cif_description_t *
fb_prepare_cif(PyObject *fargs, CTypeDescrObject *, ffi_abi); /*forward*/
-static PyObject *
-b_new_primitive_type(PyObject *self, PyObject *args); /*forward*/
+static PyObject *new_primitive_type(const char *name); /*forward*/
static CTypeDescrObject *_get_ct_int(void)
{
static CTypeDescrObject *ct_int = NULL;
if (ct_int == NULL) {
- PyObject *args = Py_BuildValue("(s)", "int");
- if (args == NULL)
- return NULL;
- ct_int = (CTypeDescrObject *)b_new_primitive_type(NULL, args);
- Py_DECREF(args);
+ ct_int = (CTypeDescrObject *)new_primitive_type("int");
}
return ct_int;
}
@@ -3338,7 +3333,7 @@
/************************************************************/
-static CTypeDescrObject *new_primitive_type(const char *name)
+static PyObject *new_primitive_type(const char *name)
{
#define ENUM_PRIMITIVE_TYPES \
EPTYPE(c, char, CT_PRIMITIVE_CHAR) \
@@ -3483,7 +3478,7 @@
td->ct_flags |= CT_PRIMITIVE_FITS_LONG;
}
td->ct_name_position = strlen(td->ct_name);
- return td;
+ return (PyObject *)td;
bad_ffi_type:
PyErr_Format(PyExc_NotImplementedError,
@@ -3498,10 +3493,10 @@
char *name;
if (!PyArg_ParseTuple(args, "s:new_primitive_type", &name))
return NULL;
- return (PyObject *)new_primitive_type(name);
-}
-
-static CTypeDescrObject *new_pointer_type(CTypeDescrObject *ctitem)
+ return new_primitive_type(name);
+}
+
+static PyObject *new_pointer_type(CTypeDescrObject *ctitem)
{
CTypeDescrObject *td;
const char *extra;
@@ -3525,7 +3520,7 @@
((ctitem->ct_flags & CT_PRIMITIVE_CHAR) &&
ctitem->ct_size == sizeof(char)))
td->ct_flags |= CT_CAST_ANYTHING; /* 'void *' or 'char *' only */
- return td;
+ return (PyObject *)td;
}
static PyObject *b_new_pointer_type(PyObject *self, PyObject *args)
@@ -3534,7 +3529,7 @@
if (!PyArg_ParseTuple(args, "O!:new_pointer_type",
&CTypeDescr_Type, &ctitem))
return NULL;
- return (PyObject *)new_pointer_type(ctitem);
+ return new_pointer_type(ctitem);
}
static PyObject *b_new_array_type(PyObject *self, PyObject *args)
@@ -3558,10 +3553,10 @@
return NULL;
}
}
- return (PyObject *)new_array_type(ctptr, length);
-}
-
-static CTypeDescrObject *
+ return new_array_type(ctptr, length);
+}
+
+static PyObject *
new_array_type(CTypeDescrObject *ctptr, Py_ssize_t length)
{
CTypeDescrObject *td, *ctitem;
@@ -3606,10 +3601,10 @@
td->ct_size = arraysize;
td->ct_length = length;
td->ct_flags = flags;
- return td;
-}
-
-static CTypeDescrObject *new_void_type(void)
+ return (PyObject *)td;
+}
+
+static PyObject *new_void_type(void)
{
int name_size = strlen("void") + 1;
CTypeDescrObject *td = ctypedescr_new(name_size);
@@ -3620,12 +3615,12 @@
td->ct_size = -1;
td->ct_flags = CT_VOID | CT_IS_OPAQUE;
td->ct_name_position = strlen("void");
- return td;
+ return (PyObject *)td;
}
static PyObject *b_new_void_type(PyObject *self, PyObject *args)
{
- return (PyObject *)new_void_type();
+ return new_void_type();
}
static PyObject *_b_struct_or_union_type(const char *name, int flag)
@@ -4389,22 +4384,15 @@
return NULL;
}
-static PyObject *b_new_function_type(PyObject *self, PyObject *args)
-{
- PyObject *fargs, *fabiobj;
- CTypeDescrObject *fresult;
+static PyObject *new_function_type(PyObject *fargs, /* tuple */
+ CTypeDescrObject *fresult,
+ int ellipsis, int fabi)
+{
+ PyObject *fabiobj;
CTypeDescrObject *fct;
- int ellipsis = 0, fabi = FFI_DEFAULT_ABI;
struct funcbuilder_s funcbuilder;
Py_ssize_t i;
- if (!PyArg_ParseTuple(args, "O!O!|ii:new_function_type",
- &PyTuple_Type, &fargs,
- &CTypeDescr_Type, &fresult,
- &ellipsis,
- &fabi))
- return NULL;
-
if ((fresult->ct_size < 0 && !(fresult->ct_flags & CT_VOID)) ||
(fresult->ct_flags & CT_ARRAY)) {
char *msg;
@@ -4468,6 +4456,22 @@
return NULL;
}
+static PyObject *b_new_function_type(PyObject *self, PyObject *args)
+{
+ PyObject *fargs;
+ CTypeDescrObject *fresult;
+ int ellipsis = 0, fabi = FFI_DEFAULT_ABI;
+
+ if (!PyArg_ParseTuple(args, "O!O!|ii:new_function_type",
+ &PyTuple_Type, &fargs,
+ &CTypeDescr_Type, &fresult,
+ &ellipsis,
+ &fabi))
+ return NULL;
+
+ return new_function_type(fargs, fresult, ellipsis, fabi);
+}
+
static int convert_from_object_fficallback(char *result,
CTypeDescrObject *ctype,
PyObject *pyobj)
diff --git a/new/ffi_obj.c b/new/ffi_obj.c
--- a/new/ffi_obj.c
+++ b/new/ffi_obj.c
@@ -101,19 +101,23 @@
input_text, spaces);
return NULL;
}
- CTypeDescrObject *ct = realize_c_type(ffi->info.ctx,
- ffi->info.output, index);
+ PyObject *ct = realize_c_type(ffi->info.ctx,
+ ffi->info.output, index);
if (ct == NULL)
return NULL;
- x = PyDict_GetItemString(ffi->types_dict, ct->ct_name);
- if (x != NULL) {
+
+ char *normalized_text = ((CTypeDescrObject *)ct)->ct_name;
+ x = PyDict_GetItemString(ffi->types_dict, normalized_text);
+ if (x == NULL) {
+ PyDict_SetItemString(ffi->types_dict, normalized_text, ct);
+ }
+ else {
Py_INCREF(x);
Py_DECREF(ct);
- ct = (CTypeDescrObject *)x;
+ ct = x;
}
- PyDict_SetItemString(ffi->types_dict, ct->ct_name, (PyObject *)ct);
- PyDict_SetItem(ffi->types_dict, arg, (PyObject *)ct);
- return ct;
+ PyDict_SetItem(ffi->types_dict, arg, ct);
+ return (CTypeDescrObject *)ct;
}
else if ((accept & ACCEPT_CTYPE) && CTypeDescr_Check(arg)) {
return (CTypeDescrObject *)arg;
diff --git a/new/lib_obj.c b/new/lib_obj.c
--- a/new/lib_obj.c
+++ b/new/lib_obj.c
@@ -66,7 +66,7 @@
xfunc->md.ml_meth = (PyCFunction)g->address;
xfunc->md.ml_flags = flags;
- xfunc->md.ml_name = strdup(s);
+ xfunc->md.ml_name = g->name;
/*xfunc->md.ml_doc = ... */
if (xfunc->md.ml_name == NULL)
goto no_memory;
diff --git a/new/realize_c_type.c b/new/realize_c_type.c
--- a/new/realize_c_type.c
+++ b/new/realize_c_type.c
@@ -1,10 +1,10 @@
-static CTypeDescrObject *all_primitives[_CFFI__NUM_PRIM];
+static PyObject *all_primitives[_CFFI__NUM_PRIM];
-CTypeDescrObject *build_primitive_type(int num)
+PyObject *build_primitive_type(int num)
{
- CTypeDescrObject *x;
+ PyObject *x;
switch (num) {
@@ -30,22 +30,39 @@
}
+static PyObject *
+_realize_c_type(const struct _cffi_type_context_s *ctx,
+ _cffi_opcode_t opcodes[], int index); /* forward */
+
+
/* Interpret an opcodes[] array. If opcodes == ctx->types, store all
the intermediate types back in the opcodes[]. Returns a new
reference.
*/
-CTypeDescrObject *realize_c_type(const struct _cffi_type_context_s *ctx,
- _cffi_opcode_t opcodes[], int index)
+static PyObject *
+realize_c_type(const struct _cffi_type_context_s *ctx,
+ _cffi_opcode_t opcodes[], int index)
{
- CTypeDescrObject *ct;
- CTypeDescrObject *x, *y, *z;
+ PyObject *x = _realize_c_type(ctx, opcodes, index);
+ if (x != NULL && !CTypeDescr_Check(x)) {
+ PyErr_SetString(PyExc_NotImplementedError, "unexpected type");
+ x = NULL;
+ }
+ return x;
+}
+
+static PyObject *
+_realize_c_type(const struct _cffi_type_context_s *ctx,
+ _cffi_opcode_t opcodes[], int index)
+{
+ PyObject *x, *y, *z;
_cffi_opcode_t op = opcodes[index];
Py_ssize_t length = -1;
if ((((uintptr_t)op) & 1) == 0) {
- ct = (CTypeDescrObject *)op;
- Py_INCREF(ct);
- return ct;
+ x = (PyObject *)op;
+ Py_INCREF(x);
+ return x;
}
switch (_CFFI_GETOP(op)) {
@@ -58,10 +75,17 @@
break;
case _CFFI_OP_POINTER:
- y = realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
+ y = _realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
if (y == NULL)
return NULL;
- x = new_pointer_type(y);
+ if (CTypeDescr_Check(y)) {
+ x = new_pointer_type((CTypeDescrObject *)y);
+ }
+ else {
+ assert(PyTuple_Check(y)); /* from _CFFI_OP_FUNCTION */
+ x = PyTuple_GET_ITEM(y, 0);
+ Py_INCREF(x);
+ }
Py_DECREF(y);
break;
@@ -72,16 +96,36 @@
y = realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
if (y == NULL)
return NULL;
- z = new_pointer_type(y);
+ z = new_pointer_type((CTypeDescrObject *)y);
Py_DECREF(y);
if (z == NULL)
return NULL;
- x = new_array_type(z, length);
+ x = new_array_type((CTypeDescrObject *)z, length);
Py_DECREF(z);
break;
+ case _CFFI_OP_FUNCTION:
+ {
+ PyObject *fargs;
+
+ y = realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
+ if (y == NULL)
+ return NULL;
+ fargs = PyTuple_New(0); // XXX NULL
+ z = new_function_type(fargs, (CTypeDescrObject *)y, 0,
FFI_DEFAULT_ABI);
+ Py_DECREF(fargs);
+ Py_DECREF(y);
+ if (z == NULL)
+ return NULL;
+
+ x = PyTuple_Pack(1, z); /* hack: hide the CT_FUNCTIONPTR. it will
+ be revealed again by the OP_POINTER */
+ Py_DECREF(z);
+ break;
+ }
+
case _CFFI_OP_NOOP:
- x = realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
+ x = _realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
break;
default:
diff --git a/new/test_realize_c_type.py b/new/test_realize_c_type.py
--- a/new/test_realize_c_type.py
+++ b/new/test_realize_c_type.py
@@ -23,3 +23,6 @@
def test_array():
check("int[5]")
+
+def test_funcptr():
+ check("int(*)(long)")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit