PageRenderTime 66ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/module/cpyext/api.py

https://bitbucket.org/shomah4a/pypy
Python | 1117 lines | 1059 code | 38 blank | 20 comment | 57 complexity | ad18e2f82d23b96b5ce0198f87ccb964 MD5 | raw file
  1. import ctypes
  2. import sys, os
  3. import atexit
  4. import py
  5. from pypy.translator.goal import autopath
  6. from pypy.rpython.lltypesystem import rffi, lltype
  7. from pypy.rpython.tool import rffi_platform
  8. from pypy.rpython.lltypesystem import ll2ctypes
  9. from pypy.rpython.annlowlevel import llhelper
  10. from pypy.rlib.objectmodel import we_are_translated
  11. from pypy.translator.tool.cbuild import ExternalCompilationInfo
  12. from pypy.translator.gensupp import NameManager
  13. from pypy.tool.udir import udir
  14. from pypy.translator import platform
  15. from pypy.module.cpyext.state import State
  16. from pypy.interpreter.error import OperationError, operationerrfmt
  17. from pypy.interpreter.baseobjspace import W_Root
  18. from pypy.interpreter.gateway import unwrap_spec
  19. from pypy.interpreter.nestedscope import Cell
  20. from pypy.interpreter.module import Module
  21. from pypy.interpreter.function import StaticMethod
  22. from pypy.objspace.std.sliceobject import W_SliceObject
  23. from pypy.module.__builtin__.descriptor import W_Property
  24. from pypy.rlib.entrypoint import entrypoint
  25. from pypy.rlib.unroll import unrolling_iterable
  26. from pypy.rlib.objectmodel import specialize
  27. from pypy.rlib.exports import export_struct
  28. from pypy.module import exceptions
  29. from pypy.module.exceptions import interp_exceptions
  30. # CPython 2.4 compatibility
  31. from py.builtin import BaseException
  32. from pypy.tool.sourcetools import func_with_new_name
  33. from pypy.rpython.lltypesystem.lloperation import llop
  34. DEBUG_WRAPPER = True
  35. # update these for other platforms
  36. Py_ssize_t = lltype.Typedef(rffi.SSIZE_T, 'Py_ssize_t')
  37. Py_ssize_tP = rffi.CArrayPtr(Py_ssize_t)
  38. size_t = rffi.ULONG
  39. ADDR = lltype.Signed
  40. pypydir = py.path.local(autopath.pypydir)
  41. include_dir = pypydir / 'module' / 'cpyext' / 'include'
  42. source_dir = pypydir / 'module' / 'cpyext' / 'src'
  43. include_dirs = [
  44. include_dir,
  45. udir,
  46. ]
  47. class CConfig:
  48. _compilation_info_ = ExternalCompilationInfo(
  49. include_dirs=include_dirs,
  50. includes=['Python.h', 'stdarg.h'],
  51. compile_extra=['-DPy_BUILD_CORE'],
  52. )
  53. class CConfig2:
  54. _compilation_info_ = CConfig._compilation_info_
  55. class CConfig_constants:
  56. _compilation_info_ = CConfig._compilation_info_
  57. VA_LIST_P = rffi.VOIDP # rffi.COpaquePtr('va_list')
  58. CONST_STRING = lltype.Ptr(lltype.Array(lltype.Char,
  59. hints={'nolength': True}),
  60. use_cache=False)
  61. CONST_WSTRING = lltype.Ptr(lltype.Array(lltype.UniChar,
  62. hints={'nolength': True}),
  63. use_cache=False)
  64. assert CONST_STRING is not rffi.CCHARP
  65. assert CONST_STRING == rffi.CCHARP
  66. assert CONST_WSTRING is not rffi.CWCHARP
  67. assert CONST_WSTRING == rffi.CWCHARP
  68. # FILE* interface
  69. FILEP = rffi.COpaquePtr('FILE')
  70. fopen = rffi.llexternal('fopen', [CONST_STRING, CONST_STRING], FILEP)
  71. fclose = rffi.llexternal('fclose', [FILEP], rffi.INT)
  72. fwrite = rffi.llexternal('fwrite',
  73. [rffi.VOIDP, rffi.SIZE_T, rffi.SIZE_T, FILEP],
  74. rffi.SIZE_T)
  75. fread = rffi.llexternal('fread',
  76. [rffi.VOIDP, rffi.SIZE_T, rffi.SIZE_T, FILEP],
  77. rffi.SIZE_T)
  78. feof = rffi.llexternal('feof', [FILEP], rffi.INT)
  79. if sys.platform == 'win32':
  80. fileno = rffi.llexternal('_fileno', [FILEP], rffi.INT)
  81. else:
  82. fileno = rffi.llexternal('fileno', [FILEP], rffi.INT)
  83. constant_names = """
  84. Py_TPFLAGS_READY Py_TPFLAGS_READYING Py_TPFLAGS_HAVE_GETCHARBUFFER
  85. METH_COEXIST METH_STATIC METH_CLASS
  86. METH_NOARGS METH_VARARGS METH_KEYWORDS METH_O
  87. Py_TPFLAGS_HEAPTYPE Py_TPFLAGS_HAVE_CLASS
  88. Py_LT Py_LE Py_EQ Py_NE Py_GT Py_GE
  89. """.split()
  90. for name in constant_names:
  91. setattr(CConfig_constants, name, rffi_platform.ConstantInteger(name))
  92. udir.join('pypy_decl.h').write("/* Will be filled later */")
  93. udir.join('pypy_macros.h').write("/* Will be filled later */")
  94. globals().update(rffi_platform.configure(CConfig_constants))
  95. def copy_header_files(dstdir):
  96. assert dstdir.check(dir=True)
  97. headers = include_dir.listdir('*.h') + include_dir.listdir('*.inl')
  98. for name in ("pypy_decl.h", "pypy_macros.h"):
  99. headers.append(udir.join(name))
  100. for header in headers:
  101. target = dstdir.join(header.basename)
  102. try:
  103. header.copy(dstdir)
  104. except py.error.EACCES:
  105. target.remove() # maybe it was a read-only file
  106. header.copy(dstdir)
  107. target.chmod(0444) # make the file read-only, to make sure that nobody
  108. # edits it by mistake
  109. _NOT_SPECIFIED = object()
  110. CANNOT_FAIL = object()
  111. # The same function can be called in three different contexts:
  112. # (1) from C code
  113. # (2) in the test suite, though the "api" object
  114. # (3) from RPython code, for example in the implementation of another function.
  115. #
  116. # In contexts (2) and (3), a function declaring a PyObject argument type will
  117. # receive a wrapped pypy object if the parameter name starts with 'w_', a
  118. # reference (= rffi pointer) otherwise; conversion is automatic. Context (2)
  119. # only allows calls with a wrapped object.
  120. #
  121. # Functions with a PyObject return type should return a wrapped object.
  122. #
  123. # Functions may raise exceptions. In context (3), the exception flows normally
  124. # through the calling function. In context (1) and (2), the exception is
  125. # caught; if it is an OperationError, it is stored in the thread state; other
  126. # exceptions generate a OperationError(w_SystemError); and the funtion returns
  127. # the error value specifed in the API.
  128. #
  129. cpyext_namespace = NameManager('cpyext_')
  130. class ApiFunction:
  131. def __init__(self, argtypes, restype, callable, error=_NOT_SPECIFIED,
  132. c_name=None):
  133. self.argtypes = argtypes
  134. self.restype = restype
  135. self.functype = lltype.Ptr(lltype.FuncType(argtypes, restype))
  136. self.callable = callable
  137. if error is not _NOT_SPECIFIED:
  138. self.error_value = error
  139. self.c_name = c_name
  140. # extract the signature from the (CPython-level) code object
  141. from pypy.interpreter import pycode
  142. argnames, varargname, kwargname = pycode.cpython_code_signature(callable.func_code)
  143. assert argnames[0] == 'space'
  144. self.argnames = argnames[1:]
  145. assert len(self.argnames) == len(self.argtypes)
  146. def _freeze_(self):
  147. return True
  148. def get_llhelper(self, space):
  149. llh = getattr(self, '_llhelper', None)
  150. if llh is None:
  151. llh = llhelper(self.functype, self.get_wrapper(space))
  152. self._llhelper = llh
  153. return llh
  154. @specialize.memo()
  155. def get_wrapper(self, space):
  156. wrapper = getattr(self, '_wrapper', None)
  157. if wrapper is None:
  158. wrapper = make_wrapper(space, self.callable)
  159. self._wrapper = wrapper
  160. wrapper.relax_sig_check = True
  161. if self.c_name is not None:
  162. wrapper.c_name = cpyext_namespace.uniquename(self.c_name)
  163. return wrapper
  164. def cpython_api(argtypes, restype, error=_NOT_SPECIFIED, external=True):
  165. """
  166. Declares a function to be exported.
  167. - `argtypes`, `restype` are lltypes and describe the function signature.
  168. - `error` is the value returned when an applevel exception is raised. The
  169. special value 'CANNOT_FAIL' (also when restype is Void) turns an eventual
  170. exception into a wrapped SystemError. Unwrapped exceptions also cause a
  171. SytemError.
  172. - set `external` to False to get a C function pointer, but not exported by
  173. the API headers.
  174. """
  175. if isinstance(restype, lltype.Typedef):
  176. real_restype = restype.OF
  177. else:
  178. real_restype = restype
  179. if error is _NOT_SPECIFIED:
  180. if isinstance(real_restype, lltype.Ptr):
  181. error = lltype.nullptr(real_restype.TO)
  182. elif real_restype is lltype.Void:
  183. error = CANNOT_FAIL
  184. if type(error) is int:
  185. error = rffi.cast(real_restype, error)
  186. expect_integer = (isinstance(real_restype, lltype.Primitive) and
  187. rffi.cast(restype, 0) == 0)
  188. def decorate(func):
  189. func_name = func.func_name
  190. if external:
  191. c_name = None
  192. else:
  193. c_name = func_name
  194. api_function = ApiFunction(argtypes, restype, func, error, c_name=c_name)
  195. func.api_func = api_function
  196. if external:
  197. assert func_name not in FUNCTIONS, (
  198. "%s already registered" % func_name)
  199. if error is _NOT_SPECIFIED:
  200. raise ValueError("function %s has no return value for exceptions"
  201. % func)
  202. def make_unwrapper(catch_exception):
  203. names = api_function.argnames
  204. types_names_enum_ui = unrolling_iterable(enumerate(
  205. zip(api_function.argtypes,
  206. [tp_name.startswith("w_") for tp_name in names])))
  207. @specialize.ll()
  208. def unwrapper(space, *args):
  209. from pypy.module.cpyext.pyobject import Py_DecRef
  210. from pypy.module.cpyext.pyobject import make_ref, from_ref
  211. from pypy.module.cpyext.pyobject import Reference
  212. newargs = ()
  213. to_decref = []
  214. assert len(args) == len(api_function.argtypes)
  215. for i, (ARG, is_wrapped) in types_names_enum_ui:
  216. input_arg = args[i]
  217. if is_PyObject(ARG) and not is_wrapped:
  218. # build a reference
  219. if input_arg is None:
  220. arg = lltype.nullptr(PyObject.TO)
  221. elif isinstance(input_arg, W_Root):
  222. ref = make_ref(space, input_arg)
  223. to_decref.append(ref)
  224. arg = rffi.cast(ARG, ref)
  225. else:
  226. arg = input_arg
  227. elif is_PyObject(ARG) and is_wrapped:
  228. # convert to a wrapped object
  229. if input_arg is None:
  230. arg = input_arg
  231. elif isinstance(input_arg, W_Root):
  232. arg = input_arg
  233. else:
  234. arg = from_ref(space,
  235. rffi.cast(PyObject, input_arg))
  236. else:
  237. arg = input_arg
  238. newargs += (arg, )
  239. try:
  240. try:
  241. res = func(space, *newargs)
  242. except OperationError, e:
  243. if not catch_exception:
  244. raise
  245. if not hasattr(api_function, "error_value"):
  246. raise
  247. state = space.fromcache(State)
  248. state.set_exception(e)
  249. if is_PyObject(restype):
  250. return None
  251. else:
  252. return api_function.error_value
  253. if not we_are_translated():
  254. got_integer = isinstance(res, (int, long, float))
  255. assert got_integer == expect_integer
  256. if res is None:
  257. return None
  258. elif isinstance(res, Reference):
  259. return res.get_wrapped(space)
  260. else:
  261. return res
  262. finally:
  263. for arg in to_decref:
  264. Py_DecRef(space, arg)
  265. unwrapper.func = func
  266. unwrapper.api_func = api_function
  267. unwrapper._always_inline_ = True
  268. return unwrapper
  269. unwrapper_catch = make_unwrapper(True)
  270. unwrapper_raise = make_unwrapper(False)
  271. if external:
  272. FUNCTIONS[func_name] = api_function
  273. INTERPLEVEL_API[func_name] = unwrapper_catch # used in tests
  274. return unwrapper_raise # used in 'normal' RPython code.
  275. return decorate
  276. def cpython_struct(name, fields, forward=None, level=1):
  277. configname = name.replace(' ', '__')
  278. if level == 1:
  279. config = CConfig
  280. else:
  281. config = CConfig2
  282. setattr(config, configname, rffi_platform.Struct(name, fields))
  283. if forward is None:
  284. forward = lltype.ForwardReference()
  285. TYPES[configname] = forward
  286. return forward
  287. INTERPLEVEL_API = {}
  288. FUNCTIONS = {}
  289. SYMBOLS_C = [
  290. 'Py_FatalError', 'PyOS_snprintf', 'PyOS_vsnprintf', 'PyArg_Parse',
  291. 'PyArg_ParseTuple', 'PyArg_UnpackTuple', 'PyArg_ParseTupleAndKeywords',
  292. 'PyArg_VaParse', 'PyArg_VaParseTupleAndKeywords', '_PyArg_NoKeywords',
  293. 'PyString_FromFormat', 'PyString_FromFormatV',
  294. 'PyModule_AddObject', 'PyModule_AddIntConstant', 'PyModule_AddStringConstant',
  295. 'Py_BuildValue', 'Py_VaBuildValue', 'PyTuple_Pack',
  296. 'PyErr_Format', 'PyErr_NewException', 'PyErr_NewExceptionWithDoc',
  297. 'PySys_WriteStdout', 'PySys_WriteStderr',
  298. 'PyEval_CallFunction', 'PyEval_CallMethod', 'PyObject_CallFunction',
  299. 'PyObject_CallMethod', 'PyObject_CallFunctionObjArgs', 'PyObject_CallMethodObjArgs',
  300. 'PyBuffer_FromMemory', 'PyBuffer_FromReadWriteMemory', 'PyBuffer_FromObject',
  301. 'PyBuffer_FromReadWriteObject', 'PyBuffer_New', 'PyBuffer_Type', 'init_bufferobject',
  302. 'PyCObject_FromVoidPtr', 'PyCObject_FromVoidPtrAndDesc', 'PyCObject_AsVoidPtr',
  303. 'PyCObject_GetDesc', 'PyCObject_Import', 'PyCObject_SetVoidPtr',
  304. 'PyCObject_Type', 'init_pycobject',
  305. 'PyCapsule_New', 'PyCapsule_IsValid', 'PyCapsule_GetPointer',
  306. 'PyCapsule_GetName', 'PyCapsule_GetDestructor', 'PyCapsule_GetContext',
  307. 'PyCapsule_SetPointer', 'PyCapsule_SetName', 'PyCapsule_SetDestructor',
  308. 'PyCapsule_SetContext', 'PyCapsule_Import', 'PyCapsule_Type', 'init_capsule',
  309. 'PyObject_AsReadBuffer', 'PyObject_AsWriteBuffer', 'PyObject_CheckReadBuffer',
  310. 'PyOS_getsig', 'PyOS_setsig',
  311. 'PyStructSequence_InitType', 'PyStructSequence_New',
  312. ]
  313. TYPES = {}
  314. GLOBALS = { # this needs to include all prebuilt pto, otherwise segfaults occur
  315. '_Py_NoneStruct#': ('PyObject*', 'space.w_None'),
  316. '_Py_TrueStruct#': ('PyObject*', 'space.w_True'),
  317. '_Py_ZeroStruct#': ('PyObject*', 'space.w_False'),
  318. '_Py_NotImplementedStruct#': ('PyObject*', 'space.w_NotImplemented'),
  319. '_Py_EllipsisObject#': ('PyObject*', 'space.w_Ellipsis'),
  320. 'PyDateTimeAPI': ('PyDateTime_CAPI*', 'None'),
  321. }
  322. FORWARD_DECLS = []
  323. INIT_FUNCTIONS = []
  324. BOOTSTRAP_FUNCTIONS = []
  325. def build_exported_objects():
  326. # Standard exceptions
  327. for exc_name in exceptions.Module.interpleveldefs.keys():
  328. GLOBALS['PyExc_' + exc_name] = (
  329. 'PyTypeObject*',
  330. 'space.gettypeobject(interp_exceptions.W_%s.typedef)'% (exc_name, ))
  331. # Common types with their own struct
  332. for cpyname, pypyexpr in {
  333. "Type": "space.w_type",
  334. "String": "space.w_str",
  335. "Unicode": "space.w_unicode",
  336. "BaseString": "space.w_basestring",
  337. "Dict": "space.w_dict",
  338. "Tuple": "space.w_tuple",
  339. "List": "space.w_list",
  340. "Int": "space.w_int",
  341. "Bool": "space.w_bool",
  342. "Float": "space.w_float",
  343. "Long": "space.w_long",
  344. "Complex": "space.w_complex",
  345. "BaseObject": "space.w_object",
  346. 'None': 'space.type(space.w_None)',
  347. 'NotImplemented': 'space.type(space.w_NotImplemented)',
  348. 'Cell': 'space.gettypeobject(Cell.typedef)',
  349. 'Module': 'space.gettypeobject(Module.typedef)',
  350. 'Property': 'space.gettypeobject(W_Property.typedef)',
  351. 'Slice': 'space.gettypeobject(W_SliceObject.typedef)',
  352. 'StaticMethod': 'space.gettypeobject(StaticMethod.typedef)',
  353. 'CFunction': 'space.gettypeobject(cpyext.methodobject.W_PyCFunctionObject.typedef)',
  354. 'WrapperDescr': 'space.gettypeobject(cpyext.methodobject.W_PyCMethodObject.typedef)'
  355. }.items():
  356. GLOBALS['Py%s_Type#' % (cpyname, )] = ('PyTypeObject*', pypyexpr)
  357. for cpyname in 'Method List Int Long Dict Tuple Class'.split():
  358. FORWARD_DECLS.append('typedef struct { PyObject_HEAD } '
  359. 'Py%sObject' % (cpyname, ))
  360. build_exported_objects()
  361. def get_structtype_for_ctype(ctype):
  362. from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr
  363. from pypy.module.cpyext.cdatetime import PyDateTime_CAPI
  364. return {"PyObject*": PyObject, "PyTypeObject*": PyTypeObjectPtr,
  365. "PyDateTime_CAPI*": lltype.Ptr(PyDateTime_CAPI)}[ctype]
  366. PyTypeObject = lltype.ForwardReference()
  367. PyTypeObjectPtr = lltype.Ptr(PyTypeObject)
  368. # It is important that these PyObjects are allocated in a raw fashion
  369. # Thus we cannot save a forward pointer to the wrapped object
  370. # So we need a forward and backward mapping in our State instance
  371. PyObjectStruct = lltype.ForwardReference()
  372. PyObject = lltype.Ptr(PyObjectStruct)
  373. PyObjectFields = (("ob_refcnt", lltype.Signed), ("ob_type", PyTypeObjectPtr))
  374. PyVarObjectFields = PyObjectFields + (("ob_size", Py_ssize_t), )
  375. cpython_struct('PyObject', PyObjectFields, PyObjectStruct)
  376. PyVarObjectStruct = cpython_struct("PyVarObject", PyVarObjectFields)
  377. PyVarObject = lltype.Ptr(PyVarObjectStruct)
  378. Py_buffer = cpython_struct(
  379. "Py_buffer", (
  380. ('buf', rffi.VOIDP),
  381. ('obj', PyObject),
  382. ('len', Py_ssize_t),
  383. # ('itemsize', Py_ssize_t),
  384. # ('readonly', lltype.Signed),
  385. # ('ndim', lltype.Signed),
  386. # ('format', rffi.CCHARP),
  387. # ('shape', Py_ssize_tP),
  388. # ('strides', Py_ssize_tP),
  389. # ('suboffets', Py_ssize_tP),
  390. # ('smalltable', rffi.CFixedArray(Py_ssize_t, 2)),
  391. # ('internal', rffi.VOIDP)
  392. ))
  393. @specialize.memo()
  394. def is_PyObject(TYPE):
  395. if not isinstance(TYPE, lltype.Ptr):
  396. return False
  397. return hasattr(TYPE.TO, 'c_ob_refcnt') and hasattr(TYPE.TO, 'c_ob_type')
  398. # a pointer to PyObject
  399. PyObjectP = rffi.CArrayPtr(PyObject)
  400. VA_TP_LIST = {}
  401. #{'int': lltype.Signed,
  402. # 'PyObject*': PyObject,
  403. # 'PyObject**': PyObjectP,
  404. # 'int*': rffi.INTP}
  405. def configure_types():
  406. for config in (CConfig, CConfig2):
  407. for name, TYPE in rffi_platform.configure(config).iteritems():
  408. if name in TYPES:
  409. TYPES[name].become(TYPE)
  410. def build_type_checkers(type_name, cls=None):
  411. """
  412. Builds two api functions: Py_XxxCheck() and Py_XxxCheckExact().
  413. - if `cls` is None, the type is space.w_[type].
  414. - if `cls` is a string, it is the name of a space attribute, e.g. 'w_str'.
  415. - else `cls` must be a W_Class with a typedef.
  416. """
  417. if cls is None:
  418. attrname = "w_" + type_name.lower()
  419. def get_w_type(space):
  420. return getattr(space, attrname)
  421. elif isinstance(cls, str):
  422. def get_w_type(space):
  423. return getattr(space, cls)
  424. else:
  425. def get_w_type(space):
  426. return space.gettypeobject(cls.typedef)
  427. check_name = "Py" + type_name + "_Check"
  428. def check(space, w_obj):
  429. "Implements the Py_Xxx_Check function"
  430. w_obj_type = space.type(w_obj)
  431. w_type = get_w_type(space)
  432. return (space.is_w(w_obj_type, w_type) or
  433. space.is_true(space.issubtype(w_obj_type, w_type)))
  434. def check_exact(space, w_obj):
  435. "Implements the Py_Xxx_CheckExact function"
  436. w_obj_type = space.type(w_obj)
  437. w_type = get_w_type(space)
  438. return space.is_w(w_obj_type, w_type)
  439. check = cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)(
  440. func_with_new_name(check, check_name))
  441. check_exact = cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)(
  442. func_with_new_name(check_exact, check_name + "Exact"))
  443. return check, check_exact
  444. pypy_debug_catch_fatal_exception = rffi.llexternal('pypy_debug_catch_fatal_exception', [], lltype.Void)
  445. # Make the wrapper for the cases (1) and (2)
  446. def make_wrapper(space, callable):
  447. "NOT_RPYTHON"
  448. names = callable.api_func.argnames
  449. argtypes_enum_ui = unrolling_iterable(enumerate(zip(callable.api_func.argtypes,
  450. [name.startswith("w_") for name in names])))
  451. fatal_value = callable.api_func.restype._defl()
  452. @specialize.ll()
  453. def wrapper(*args):
  454. from pypy.module.cpyext.pyobject import make_ref, from_ref
  455. from pypy.module.cpyext.pyobject import Reference
  456. # we hope that malloc removal removes the newtuple() that is
  457. # inserted exactly here by the varargs specializer
  458. llop.gc_stack_bottom(lltype.Void) # marker for trackgcroot.py
  459. rffi.stackcounter.stacks_counter += 1
  460. retval = fatal_value
  461. boxed_args = ()
  462. try:
  463. if not we_are_translated() and DEBUG_WRAPPER:
  464. print >>sys.stderr, callable,
  465. assert len(args) == len(callable.api_func.argtypes)
  466. for i, (typ, is_wrapped) in argtypes_enum_ui:
  467. arg = args[i]
  468. if is_PyObject(typ) and is_wrapped:
  469. if arg:
  470. arg_conv = from_ref(space, rffi.cast(PyObject, arg))
  471. else:
  472. arg_conv = None
  473. else:
  474. arg_conv = arg
  475. boxed_args += (arg_conv, )
  476. state = space.fromcache(State)
  477. try:
  478. result = callable(space, *boxed_args)
  479. if not we_are_translated() and DEBUG_WRAPPER:
  480. print >>sys.stderr, " DONE"
  481. except OperationError, e:
  482. failed = True
  483. state.set_exception(e)
  484. except BaseException, e:
  485. failed = True
  486. if not we_are_translated():
  487. message = repr(e)
  488. import traceback
  489. traceback.print_exc()
  490. else:
  491. message = str(e)
  492. state.set_exception(OperationError(space.w_SystemError,
  493. space.wrap(message)))
  494. else:
  495. failed = False
  496. if failed:
  497. error_value = callable.api_func.error_value
  498. if error_value is CANNOT_FAIL:
  499. raise SystemError("The function '%s' was not supposed to fail"
  500. % (callable.__name__,))
  501. retval = error_value
  502. elif is_PyObject(callable.api_func.restype):
  503. if result is None:
  504. retval = rffi.cast(callable.api_func.restype,
  505. make_ref(space, None))
  506. elif isinstance(result, Reference):
  507. retval = result.get_ref(space)
  508. elif not rffi._isllptr(result):
  509. retval = rffi.cast(callable.api_func.restype,
  510. make_ref(space, result))
  511. else:
  512. retval = result
  513. elif callable.api_func.restype is not lltype.Void:
  514. retval = rffi.cast(callable.api_func.restype, result)
  515. except Exception, e:
  516. print 'Fatal error in cpyext, CPython compatibility layer, calling', callable.__name__
  517. print 'Either report a bug or consider not using this particular extension'
  518. if not we_are_translated():
  519. import traceback
  520. traceback.print_exc()
  521. print str(e)
  522. # we can't do much here, since we're in ctypes, swallow
  523. else:
  524. print str(e)
  525. pypy_debug_catch_fatal_exception()
  526. rffi.stackcounter.stacks_counter -= 1
  527. return retval
  528. callable._always_inline_ = True
  529. wrapper.__name__ = "wrapper for %r" % (callable, )
  530. return wrapper
  531. def process_va_name(name):
  532. return name.replace('*', '_star')
  533. def setup_va_functions(eci):
  534. for name, TP in VA_TP_LIST.iteritems():
  535. name_no_star = process_va_name(name)
  536. func = rffi.llexternal('pypy_va_get_%s' % name_no_star, [VA_LIST_P],
  537. TP, compilation_info=eci)
  538. globals()['va_get_%s' % name_no_star] = func
  539. def setup_init_functions(eci):
  540. init_buffer = rffi.llexternal('init_bufferobject', [], lltype.Void, compilation_info=eci)
  541. init_pycobject = rffi.llexternal('init_pycobject', [], lltype.Void, compilation_info=eci)
  542. init_capsule = rffi.llexternal('init_capsule', [], lltype.Void, compilation_info=eci)
  543. INIT_FUNCTIONS.extend([
  544. lambda space: init_buffer(),
  545. lambda space: init_pycobject(),
  546. lambda space: init_capsule(),
  547. ])
  548. def init_function(func):
  549. INIT_FUNCTIONS.append(func)
  550. return func
  551. def bootstrap_function(func):
  552. BOOTSTRAP_FUNCTIONS.append(func)
  553. return func
  554. def run_bootstrap_functions(space):
  555. for func in BOOTSTRAP_FUNCTIONS:
  556. func(space)
  557. def c_function_signature(db, func):
  558. restype = db.gettype(func.restype).replace('@', '').strip()
  559. args = []
  560. for i, argtype in enumerate(func.argtypes):
  561. if argtype is CONST_STRING:
  562. arg = 'const char *@'
  563. elif argtype is CONST_WSTRING:
  564. arg = 'const wchar_t *@'
  565. else:
  566. arg = db.gettype(argtype)
  567. arg = arg.replace('@', 'arg%d' % (i,)).strip()
  568. args.append(arg)
  569. args = ', '.join(args) or "void"
  570. return restype, args
  571. #_____________________________________________________
  572. # Build the bridge DLL, Allow extension DLLs to call
  573. # back into Pypy space functions
  574. # Do not call this more than once per process
  575. def build_bridge(space):
  576. "NOT_RPYTHON"
  577. from pypy.module.cpyext.pyobject import make_ref
  578. export_symbols = list(FUNCTIONS) + SYMBOLS_C + list(GLOBALS)
  579. from pypy.translator.c.database import LowLevelDatabase
  580. db = LowLevelDatabase()
  581. generate_macros(export_symbols, rename=True, do_deref=True)
  582. # Structure declaration code
  583. members = []
  584. structindex = {}
  585. for name, func in sorted(FUNCTIONS.iteritems()):
  586. restype, args = c_function_signature(db, func)
  587. members.append('%s (*%s)(%s);' % (restype, name, args))
  588. structindex[name] = len(structindex)
  589. structmembers = '\n'.join(members)
  590. struct_declaration_code = """\
  591. struct PyPyAPI {
  592. %(members)s
  593. } _pypyAPI;
  594. struct PyPyAPI* pypyAPI = &_pypyAPI;
  595. """ % dict(members=structmembers)
  596. functions = generate_decls_and_callbacks(db, export_symbols)
  597. global_objects = []
  598. for name, (typ, expr) in GLOBALS.iteritems():
  599. if "#" in name:
  600. continue
  601. if typ == 'PyDateTime_CAPI*':
  602. continue
  603. elif name.startswith('PyExc_'):
  604. global_objects.append('%s _%s;' % (typ[:-1], name))
  605. else:
  606. global_objects.append('%s %s = NULL;' % (typ, name))
  607. global_code = '\n'.join(global_objects)
  608. prologue = "#include <Python.h>\n"
  609. code = (prologue +
  610. struct_declaration_code +
  611. global_code +
  612. '\n' +
  613. '\n'.join(functions))
  614. eci = build_eci(True, export_symbols, code)
  615. eci = eci.compile_shared_lib(
  616. outputfilename=str(udir / "module_cache" / "pypyapi"))
  617. modulename = py.path.local(eci.libraries[-1])
  618. run_bootstrap_functions(space)
  619. # load the bridge, and init structure
  620. import ctypes
  621. bridge = ctypes.CDLL(str(modulename), mode=ctypes.RTLD_GLOBAL)
  622. space.fromcache(State).install_dll(eci)
  623. # populate static data
  624. for name, (typ, expr) in GLOBALS.iteritems():
  625. from pypy.module import cpyext
  626. w_obj = eval(expr)
  627. if name.endswith('#'):
  628. name = name[:-1]
  629. isptr = False
  630. else:
  631. isptr = True
  632. if name.startswith('PyExc_'):
  633. isptr = False
  634. INTERPLEVEL_API[name] = w_obj
  635. name = name.replace('Py', 'PyPy')
  636. if isptr:
  637. ptr = ctypes.c_void_p.in_dll(bridge, name)
  638. if typ == 'PyObject*':
  639. value = make_ref(space, w_obj)
  640. elif typ == 'PyDateTime_CAPI*':
  641. value = w_obj
  642. else:
  643. assert False, "Unknown static pointer: %s %s" % (typ, name)
  644. ptr.value = ctypes.cast(ll2ctypes.lltype2ctypes(value),
  645. ctypes.c_void_p).value
  646. elif typ in ('PyObject*', 'PyTypeObject*'):
  647. if name.startswith('PyPyExc_'):
  648. # we already have the pointer
  649. in_dll = ll2ctypes.get_ctypes_type(PyObject).in_dll(bridge, name)
  650. py_obj = ll2ctypes.ctypes2lltype(PyObject, in_dll)
  651. else:
  652. # we have a structure, get its address
  653. in_dll = ll2ctypes.get_ctypes_type(PyObject.TO).in_dll(bridge, name)
  654. py_obj = ll2ctypes.ctypes2lltype(PyObject, ctypes.pointer(in_dll))
  655. from pypy.module.cpyext.pyobject import (
  656. track_reference, get_typedescr)
  657. w_type = space.type(w_obj)
  658. typedescr = get_typedescr(w_type.instancetypedef)
  659. py_obj.c_ob_refcnt = 1
  660. py_obj.c_ob_type = rffi.cast(PyTypeObjectPtr,
  661. make_ref(space, w_type))
  662. typedescr.attach(space, py_obj, w_obj)
  663. track_reference(space, py_obj, w_obj)
  664. else:
  665. assert False, "Unknown static object: %s %s" % (typ, name)
  666. pypyAPI = ctypes.POINTER(ctypes.c_void_p).in_dll(bridge, 'pypyAPI')
  667. # implement structure initialization code
  668. for name, func in FUNCTIONS.iteritems():
  669. if name.startswith('cpyext_'): # XXX hack
  670. continue
  671. pypyAPI[structindex[name]] = ctypes.cast(
  672. ll2ctypes.lltype2ctypes(func.get_llhelper(space)),
  673. ctypes.c_void_p)
  674. setup_va_functions(eci)
  675. setup_init_functions(eci)
  676. return modulename.new(ext='')
  677. def generate_macros(export_symbols, rename=True, do_deref=True):
  678. "NOT_RPYTHON"
  679. pypy_macros = []
  680. renamed_symbols = []
  681. for name in export_symbols:
  682. if name.startswith("PyPy"):
  683. renamed_symbols.append(name)
  684. continue
  685. if not rename:
  686. continue
  687. name = name.replace("#", "")
  688. newname = name.replace('Py', 'PyPy')
  689. if not rename:
  690. newname = name
  691. pypy_macros.append('#define %s %s' % (name, newname))
  692. if name.startswith("PyExc_"):
  693. pypy_macros.append('#define _%s _%s' % (name, newname))
  694. renamed_symbols.append(newname)
  695. if rename:
  696. export_symbols[:] = renamed_symbols
  697. else:
  698. export_symbols[:] = [sym.replace("#", "") for sym in export_symbols]
  699. # Generate defines
  700. for macro_name, size in [
  701. ("SIZEOF_LONG_LONG", rffi.LONGLONG),
  702. ("SIZEOF_VOID_P", rffi.VOIDP),
  703. ("SIZEOF_SIZE_T", rffi.SIZE_T),
  704. ("SIZEOF_TIME_T", rffi.TIME_T),
  705. ("SIZEOF_LONG", rffi.LONG),
  706. ("SIZEOF_SHORT", rffi.SHORT),
  707. ("SIZEOF_INT", rffi.INT)
  708. ]:
  709. pypy_macros.append("#define %s %s" % (macro_name, rffi.sizeof(size)))
  710. pypy_macros.append('')
  711. pypy_macros_h = udir.join('pypy_macros.h')
  712. pypy_macros_h.write('\n'.join(pypy_macros))
  713. def generate_decls_and_callbacks(db, export_symbols, api_struct=True):
  714. "NOT_RPYTHON"
  715. # implement function callbacks and generate function decls
  716. functions = []
  717. pypy_decls = []
  718. pypy_decls.append("#ifndef PYPY_STANDALONE\n")
  719. pypy_decls.append("#ifdef __cplusplus")
  720. pypy_decls.append("extern \"C\" {")
  721. pypy_decls.append("#endif\n")
  722. for decl in FORWARD_DECLS:
  723. pypy_decls.append("%s;" % (decl,))
  724. for name, func in sorted(FUNCTIONS.iteritems()):
  725. restype, args = c_function_signature(db, func)
  726. pypy_decls.append("PyAPI_FUNC(%s) %s(%s);" % (restype, name, args))
  727. if api_struct:
  728. callargs = ', '.join('arg%d' % (i,)
  729. for i in range(len(func.argtypes)))
  730. if func.restype is lltype.Void:
  731. body = "{ _pypyAPI.%s(%s); }" % (name, callargs)
  732. else:
  733. body = "{ return _pypyAPI.%s(%s); }" % (name, callargs)
  734. functions.append('%s %s(%s)\n%s' % (restype, name, args, body))
  735. for name in VA_TP_LIST:
  736. name_no_star = process_va_name(name)
  737. header = ('%s pypy_va_get_%s(va_list* vp)' %
  738. (name, name_no_star))
  739. pypy_decls.append(header + ';')
  740. functions.append(header + '\n{return va_arg(*vp, %s);}\n' % name)
  741. export_symbols.append('pypy_va_get_%s' % (name_no_star,))
  742. for name, (typ, expr) in GLOBALS.iteritems():
  743. if name.endswith('#'):
  744. name = name.replace("#", "")
  745. typ = typ.replace("*", "")
  746. elif name.startswith('PyExc_'):
  747. typ = 'PyObject*'
  748. pypy_decls.append('PyAPI_DATA(%s) %s;' % (typ, name))
  749. pypy_decls.append("#ifdef __cplusplus")
  750. pypy_decls.append("}")
  751. pypy_decls.append("#endif")
  752. pypy_decls.append("#endif /*PYPY_STANDALONE*/\n")
  753. pypy_decl_h = udir.join('pypy_decl.h')
  754. pypy_decl_h.write('\n'.join(pypy_decls))
  755. return functions
  756. def build_eci(building_bridge, export_symbols, code):
  757. "NOT_RPYTHON"
  758. # Build code and get pointer to the structure
  759. kwds = {}
  760. export_symbols_eci = export_symbols[:]
  761. compile_extra=['-DPy_BUILD_CORE']
  762. if building_bridge:
  763. if sys.platform == "win32":
  764. # '%s' undefined; assuming extern returning int
  765. compile_extra.append("/we4013")
  766. # Sometimes the library is wrapped into another DLL, ensure that
  767. # the correct bootstrap code is installed
  768. kwds["link_extra"] = ["msvcrt.lib"]
  769. elif sys.platform.startswith('linux'):
  770. compile_extra.append("-Werror=implicit-function-declaration")
  771. export_symbols_eci.append('pypyAPI')
  772. compile_extra.append('-g')
  773. else:
  774. kwds["includes"] = ['Python.h'] # this is our Python.h
  775. # Generate definitions for global structures
  776. structs = ["#include <Python.h>"]
  777. for name, (typ, expr) in GLOBALS.iteritems():
  778. if name.endswith('#'):
  779. structs.append('%s %s;' % (typ[:-1], name[:-1]))
  780. elif name.startswith('PyExc_'):
  781. structs.append('extern PyTypeObject _%s;' % (name,))
  782. structs.append('PyObject* %s = (PyObject*)&_%s;' % (name, name))
  783. elif typ == 'PyDateTime_CAPI*':
  784. structs.append('%s %s = NULL;' % (typ, name))
  785. struct_source = '\n'.join(structs)
  786. separate_module_sources = [code, struct_source]
  787. if sys.platform == 'win32':
  788. get_pythonapi_source = '''
  789. #include <windows.h>
  790. HANDLE pypy_get_pythonapi_handle() {
  791. MEMORY_BASIC_INFORMATION mi;
  792. memset(&mi, 0, sizeof(mi));
  793. if( !VirtualQueryEx(GetCurrentProcess(), &pypy_get_pythonapi_handle,
  794. &mi, sizeof(mi)) )
  795. return 0;
  796. return (HMODULE)mi.AllocationBase;
  797. }
  798. '''
  799. separate_module_sources.append(get_pythonapi_source)
  800. export_symbols_eci.append('pypy_get_pythonapi_handle')
  801. eci = ExternalCompilationInfo(
  802. include_dirs=include_dirs,
  803. separate_module_files=[source_dir / "varargwrapper.c",
  804. source_dir / "pyerrors.c",
  805. source_dir / "modsupport.c",
  806. source_dir / "getargs.c",
  807. source_dir / "stringobject.c",
  808. source_dir / "mysnprintf.c",
  809. source_dir / "pythonrun.c",
  810. source_dir / "sysmodule.c",
  811. source_dir / "bufferobject.c",
  812. source_dir / "object.c",
  813. source_dir / "cobject.c",
  814. source_dir / "structseq.c",
  815. source_dir / "capsule.c",
  816. source_dir / "pysignals.c",
  817. ],
  818. separate_module_sources=separate_module_sources,
  819. export_symbols=export_symbols_eci,
  820. compile_extra=compile_extra,
  821. **kwds
  822. )
  823. return eci
  824. def setup_library(space):
  825. "NOT_RPYTHON"
  826. from pypy.module.cpyext.pyobject import make_ref
  827. export_symbols = list(FUNCTIONS) + SYMBOLS_C + list(GLOBALS)
  828. from pypy.translator.c.database import LowLevelDatabase
  829. db = LowLevelDatabase()
  830. generate_macros(export_symbols, rename=False, do_deref=False)
  831. functions = generate_decls_and_callbacks(db, [], api_struct=False)
  832. code = "#include <Python.h>\n" + "\n".join(functions)
  833. eci = build_eci(False, export_symbols, code)
  834. space.fromcache(State).install_dll(eci)
  835. run_bootstrap_functions(space)
  836. setup_va_functions(eci)
  837. # populate static data
  838. for name, (typ, expr) in GLOBALS.iteritems():
  839. name = name.replace("#", "")
  840. if name.startswith('PyExc_'):
  841. name = '_' + name
  842. from pypy.module import cpyext
  843. w_obj = eval(expr)
  844. if typ in ('PyObject*', 'PyTypeObject*'):
  845. struct_ptr = make_ref(space, w_obj)
  846. elif typ == 'PyDateTime_CAPI*':
  847. continue
  848. else:
  849. assert False, "Unknown static data: %s %s" % (typ, name)
  850. struct = rffi.cast(get_structtype_for_ctype(typ), struct_ptr)._obj
  851. struct._compilation_info = eci
  852. export_struct(name, struct)
  853. for name, func in FUNCTIONS.iteritems():
  854. deco = entrypoint("cpyext", func.argtypes, name, relax=True)
  855. deco(func.get_wrapper(space))
  856. setup_init_functions(eci)
  857. trunk_include = pypydir.dirpath() / 'include'
  858. copy_header_files(trunk_include)
  859. initfunctype = lltype.Ptr(lltype.FuncType([], lltype.Void))
  860. @unwrap_spec(path=str, name=str)
  861. def load_extension_module(space, path, name):
  862. if os.sep not in path:
  863. path = os.curdir + os.sep + path # force a '/' in the path
  864. state = space.fromcache(State)
  865. if state.find_extension(name, path) is not None:
  866. return
  867. old_context = state.package_context
  868. state.package_context = name, path
  869. try:
  870. from pypy.rlib import rdynload
  871. try:
  872. ll_libname = rffi.str2charp(path)
  873. try:
  874. dll = rdynload.dlopen(ll_libname)
  875. finally:
  876. lltype.free(ll_libname, flavor='raw')
  877. except rdynload.DLOpenError, e:
  878. raise operationerrfmt(
  879. space.w_ImportError,
  880. "unable to load extension module '%s': %s",
  881. path, e.msg)
  882. try:
  883. initptr = rdynload.dlsym(dll, 'init%s' % (name.split('.')[-1],))
  884. except KeyError:
  885. raise operationerrfmt(
  886. space.w_ImportError,
  887. "function init%s not found in library %s",
  888. name, path)
  889. initfunc = rffi.cast(initfunctype, initptr)
  890. generic_cpy_call(space, initfunc)
  891. state.check_and_raise_exception()
  892. finally:
  893. state.package_context = old_context
  894. state.fixup_extension(name, path)
  895. @specialize.ll()
  896. def generic_cpy_call(space, func, *args):
  897. FT = lltype.typeOf(func).TO
  898. return make_generic_cpy_call(FT, True, False)(space, func, *args)
  899. @specialize.ll()
  900. def generic_cpy_call_dont_decref(space, func, *args):
  901. FT = lltype.typeOf(func).TO
  902. return make_generic_cpy_call(FT, False, False)(space, func, *args)
  903. @specialize.ll()
  904. def generic_cpy_call_expect_null(space, func, *args):
  905. FT = lltype.typeOf(func).TO
  906. return make_generic_cpy_call(FT, True, True)(space, func, *args)
  907. @specialize.memo()
  908. def make_generic_cpy_call(FT, decref_args, expect_null):
  909. from pypy.module.cpyext.pyobject import make_ref, from_ref, Py_DecRef
  910. from pypy.module.cpyext.pyobject import RefcountState
  911. from pypy.module.cpyext.pyerrors import PyErr_Occurred
  912. unrolling_arg_types = unrolling_iterable(enumerate(FT.ARGS))
  913. RESULT_TYPE = FT.RESULT
  914. # copied and modified from rffi.py
  915. # We need tons of care to ensure that no GC operation and no
  916. # exception checking occurs in call_external_function.
  917. argnames = ', '.join(['a%d' % i for i in range(len(FT.ARGS))])
  918. source = py.code.Source("""
  919. def cpy_call_external(funcptr, %(argnames)s):
  920. # NB. it is essential that no exception checking occurs here!
  921. res = funcptr(%(argnames)s)
  922. return res
  923. """ % locals())
  924. miniglobals = {'__name__': __name__, # for module name propagation
  925. }
  926. exec source.compile() in miniglobals
  927. call_external_function = miniglobals['cpy_call_external']
  928. call_external_function._dont_inline_ = True
  929. call_external_function._annspecialcase_ = 'specialize:ll'
  930. call_external_function._gctransformer_hint_close_stack_ = True
  931. # don't inline, as a hack to guarantee that no GC pointer is alive
  932. # anywhere in call_external_function
  933. @specialize.ll()
  934. def generic_cpy_call(space, func, *args):
  935. boxed_args = ()
  936. to_decref = []
  937. assert len(args) == len(FT.ARGS)
  938. for i, ARG in unrolling_arg_types:
  939. arg = args[i]
  940. if is_PyObject(ARG):
  941. if arg is None:
  942. boxed_args += (lltype.nullptr(PyObject.TO),)
  943. elif isinstance(arg, W_Root):
  944. ref = make_ref(space, arg)
  945. boxed_args += (ref,)
  946. if decref_args:
  947. to_decref.append(ref)
  948. else:
  949. boxed_args += (arg,)
  950. else:
  951. boxed_args += (arg,)
  952. try:
  953. # create a new container for borrowed references
  954. state = space.fromcache(RefcountState)
  955. old_container = state.swap_borrow_container(None)
  956. try:
  957. # Call the function
  958. result = call_external_function(func, *boxed_args)
  959. finally:
  960. state.swap_borrow_container(old_container)
  961. if is_PyObject(RESULT_TYPE):
  962. if result is None:
  963. ret = result
  964. elif isinstance(result, W_Root):
  965. ret = result
  966. else:
  967. ret = from_ref(space, result)
  968. # The object reference returned from a C function
  969. # that is called from Python must be an owned reference
  970. # - ownership is transferred from the function to its caller.
  971. if result:
  972. Py_DecRef(space, result)
  973. # Check for exception consistency
  974. has_error = PyErr_Occurred(space) is not None
  975. has_result = ret is not None
  976. if has_error and has_result:
  977. raise OperationError(space.w_SystemError, space.wrap(
  978. "An exception was set, but function returned a value"))
  979. elif not expect_null and not has_error and not has_result:
  980. raise OperationError(space.w_SystemError, space.wrap(
  981. "Function returned a NULL result without setting an exception"))
  982. if has_error:
  983. state = space.fromcache(State)
  984. state.check_and_raise_exception()
  985. return ret
  986. return result
  987. finally:
  988. if decref_args:
  989. for ref in to_decref:
  990. Py_DecRef(space, ref)
  991. return generic_cpy_call