[pypy-commit] pypy cpyext-macros-cast2: first try at generating casting macros, but must remove second macro from pypy_macros.h
mattip
pypy.commits at gmail.com
Wed May 11 03:15:57 EDT 2016
Author: Matti Picus <matti.picus at gmail.com>
Branch: cpyext-macros-cast2
Changeset: r84359:463b5eaaf35d
Date: 2016-05-11 01:04 +0300
http://bitbucket.org/pypy/pypy/changeset/463b5eaaf35d/
Log: first try at generating casting macros, but must remove second macro
from pypy_macros.h
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -301,7 +301,7 @@
DEFAULT_HEADER = 'pypy_decl.h'
def cpython_api(argtypes, restype, error=_NOT_SPECIFIED, header=DEFAULT_HEADER,
- gil=None, result_borrowed=False, result_is_ll=False):
+ gil=None, result_borrowed=False, result_is_ll=False, cast=False):
"""
Declares a function to be exported.
- `argtypes`, `restype` are lltypes and describe the function signature.
@@ -313,6 +313,8 @@
a C function pointer, but not exported by the API headers.
- set `gil` to "acquire", "release" or "around" to acquire the GIL,
release the GIL, or both
+ - 'cast' if True will create an UPPER CASE macro definition that casts
+ the first argument to the proper PyObject* type
"""
if isinstance(restype, lltype.Typedef):
real_restype = restype.OF
@@ -433,6 +435,8 @@
if header == DEFAULT_HEADER:
FUNCTIONS[func_name] = api_function
FUNCTIONS_BY_HEADER.setdefault(header, {})[func_name] = api_function
+ if cast:
+ CASTS.setdefault(header, {})[func_name] = api_function
INTERPLEVEL_API[func_name] = unwrapper_catch # used in tests
return unwrapper_raise # used in 'normal' RPython code.
return decorate
@@ -451,6 +455,7 @@
INTERPLEVEL_API = {}
FUNCTIONS = {}
+CASTS = {}
FUNCTIONS_BY_HEADER = {}
# These are C symbols which cpyext will export, but which are defined in .c
@@ -995,7 +1000,6 @@
arg = db.gettype(argtype)
arg = arg.replace('@', 'arg%d' % (i,)).strip()
args.append(arg)
- args = ', '.join(args) or "void"
return restype, args
#_____________________________________________________
@@ -1023,6 +1027,7 @@
# added only for the macro, not the decl
continue
restype, args = c_function_signature(db, func)
+ args = ', '.join(args) or "void"
members.append('%s (*%s)(%s);' % (restype, name, args))
structindex[name] = len(structindex)
structmembers = '\n'.join(members)
@@ -1254,6 +1259,25 @@
for decl in FORWARD_DECLS:
pypy_decls.append("%s;" % (decl,))
+ casts = []
+ for header_name, header_functions in CASTS.iteritems():
+ header = decls[header_name]
+ for name, func in sorted(header_functions.iteritems()):
+ # create define casts like
+ # #define PyInt_AS_LONG(a1) PyPyInt_AS_LONG(PyObject *)a1)
+ if not func:
+ continue
+ casts.append(name)
+ _name = mangle_name(prefix, name)
+ assert _name is not None, 'error converting %s' % name
+ restype, args = c_function_signature(db, func)
+ l_args = ', '.join(['a%d' % i for i in xrange(len(args))])
+ r_args = ', '.join(['(%s)a%d' % (a.split('arg')[0], i)
+ for i,a in enumerate(args)])
+ _name = mangle_name(prefix, name)
+ header.append("#define %s(%s) %s(%s)" % (name, l_args, _name, r_args))
+ print casts
+ xxxx
for header_name, header_functions in FUNCTIONS_BY_HEADER.iteritems():
if header_name not in decls:
header = decls[header_name] = []
@@ -1265,14 +1289,12 @@
for name, func in sorted(header_functions.iteritems()):
if not func:
continue
- if header == DEFAULT_HEADER:
- _name = name
- else:
- # this name is not included in pypy_macros.h
+ if name not in casts:
_name = mangle_name(prefix, name)
assert _name is not None, 'error converting %s' % name
header.append("#define %s %s" % (name, _name))
restype, args = c_function_signature(db, func)
+ args = ', '.join(args) or "void"
header.append("PyAPI_FUNC(%s) %s(%s);" % (restype, _name, args))
if api_struct:
callargs = ', '.join('arg%d' % (i,)
@@ -1408,7 +1430,7 @@
def setup_library(space):
"NOT_RPYTHON"
use_micronumpy = setup_micronumpy(space)
- export_symbols = sorted(FUNCTIONS) + sorted(SYMBOLS_C) + sorted(GLOBALS)
+ export_symbols = sorted(FUNCTIONS) + sorted(SYMBOLS_C) + sorted(GLOBALS) # dict -> list
from rpython.translator.c.database import LowLevelDatabase
db = LowLevelDatabase()
prefix = 'PyPy'
diff --git a/pypy/module/cpyext/intobject.py b/pypy/module/cpyext/intobject.py
--- a/pypy/module/cpyext/intobject.py
+++ b/pypy/module/cpyext/intobject.py
@@ -104,7 +104,7 @@
num = space.bigint_w(w_int)
return num.ulonglongmask()
- at cpython_api([PyObject], lltype.Signed, error=CANNOT_FAIL)
+ at cpython_api([PyObject], lltype.Signed, error=CANNOT_FAIL, cast=True)
def PyInt_AS_LONG(space, w_int):
"""Return the value of the object w_int. No error checking is performed."""
return space.int_w(w_int)
More information about the pypy-commit
mailing list