/pypy/rpython/lltypesystem/rffi.py

http://github.com/pypy/pypy · Python · 1100 lines · 839 code · 85 blank · 176 comment · 106 complexity · 61752a13110d791c7d11d0978903e0ca MD5 · raw file

  1. import py
  2. from pypy.annotation import model as annmodel
  3. from pypy.rpython.lltypesystem import lltype
  4. from pypy.rpython.lltypesystem import ll2ctypes
  5. from pypy.rpython.lltypesystem.llmemory import cast_adr_to_ptr, cast_ptr_to_adr
  6. from pypy.rpython.lltypesystem.llmemory import itemoffsetof, raw_memcopy
  7. from pypy.annotation.model import lltype_to_annotation
  8. from pypy.tool.sourcetools import func_with_new_name
  9. from pypy.rlib.objectmodel import Symbolic, CDefinedIntSymbolic
  10. from pypy.rlib.objectmodel import keepalive_until_here
  11. from pypy.rlib import rarithmetic, rgc
  12. from pypy.rpython.extregistry import ExtRegistryEntry
  13. from pypy.rlib.unroll import unrolling_iterable
  14. from pypy.rpython.tool.rfficache import platform
  15. from pypy.translator.tool.cbuild import ExternalCompilationInfo
  16. from pypy.rpython.annlowlevel import llhelper
  17. from pypy.rlib.objectmodel import we_are_translated
  18. from pypy.rlib.rstring import StringBuilder, UnicodeBuilder, assert_str0
  19. from pypy.rlib import jit
  20. from pypy.rpython.lltypesystem import llmemory
  21. from pypy.rlib.rarithmetic import maxint, LONG_BIT
  22. import os, sys
  23. class CConstant(Symbolic):
  24. """ A C-level constant, maybe #define, rendered directly.
  25. """
  26. def __init__(self, c_name, TP):
  27. self.c_name = c_name
  28. self.TP = TP
  29. def __repr__(self):
  30. return '%s(%r, %s)' % (self.__class__.__name__,
  31. self.c_name, self.TP)
  32. def annotation(self):
  33. return lltype_to_annotation(self.TP)
  34. def lltype(self):
  35. return self.TP
  36. def _isfunctype(TP):
  37. """ Evil hack to get rid of flow objspace inability
  38. to accept .TO when TP is not a pointer
  39. """
  40. return isinstance(TP, lltype.Ptr) and isinstance(TP.TO, lltype.FuncType)
  41. _isfunctype._annspecialcase_ = 'specialize:memo'
  42. def _isllptr(p):
  43. """ Second evil hack to detect if 'p' is a low-level pointer or not """
  44. return isinstance(p, lltype._ptr)
  45. class _IsLLPtrEntry(ExtRegistryEntry):
  46. _about_ = _isllptr
  47. def compute_result_annotation(self, s_p):
  48. result = isinstance(s_p, annmodel.SomePtr)
  49. return self.bookkeeper.immutablevalue(result)
  50. def specialize_call(self, hop):
  51. hop.exception_cannot_occur()
  52. return hop.inputconst(lltype.Bool, hop.s_result.const)
  53. def llexternal(name, args, result, _callable=None,
  54. compilation_info=ExternalCompilationInfo(),
  55. sandboxsafe=False, threadsafe='auto',
  56. _nowrapper=False, calling_conv='c',
  57. oo_primitive=None, elidable_function=False,
  58. macro=None, random_effects_on_gcobjs='auto'):
  59. """Build an external function that will invoke the C function 'name'
  60. with the given 'args' types and 'result' type.
  61. You get by default a wrapper that casts between number types as needed
  62. to match the arguments. You can also pass an RPython string when a
  63. CCHARP argument is expected, and the C function receives a 'const char*'
  64. pointing to a read-only null-terminated character of arrays, as usual
  65. for C.
  66. The C function can have callbacks, but they must be specified explicitly
  67. as constant RPython functions. We don't support yet C functions that
  68. invoke callbacks passed otherwise (e.g. set by a previous C call).
  69. threadsafe: whether it's ok to release the GIL around the call.
  70. Default is yes, unless sandboxsafe is set, in which case
  71. we consider that the function is really short-running and
  72. don't bother releasing the GIL. An explicit True or False
  73. overrides this logic.
  74. """
  75. if _callable is not None:
  76. assert callable(_callable)
  77. ext_type = lltype.FuncType(args, result)
  78. if _callable is None:
  79. if macro is not None:
  80. if macro is True:
  81. macro = name
  82. _callable = generate_macro_wrapper(
  83. name, macro, ext_type, compilation_info)
  84. else:
  85. _callable = ll2ctypes.LL2CtypesCallable(ext_type, calling_conv)
  86. if elidable_function:
  87. _callable._elidable_function_ = True
  88. kwds = {}
  89. if oo_primitive:
  90. kwds['oo_primitive'] = oo_primitive
  91. has_callback = False
  92. for ARG in args:
  93. if _isfunctype(ARG):
  94. has_callback = True
  95. if has_callback:
  96. kwds['_callbacks'] = callbackholder = CallbackHolder()
  97. else:
  98. callbackholder = None
  99. if threadsafe in (False, True):
  100. # invoke the around-handlers, which release the GIL, if and only if
  101. # the C function is thread-safe.
  102. invoke_around_handlers = threadsafe
  103. else:
  104. # default case:
  105. # invoke the around-handlers only for "not too small" external calls;
  106. # sandboxsafe is a hint for "too-small-ness" (e.g. math functions).
  107. invoke_around_handlers = not sandboxsafe
  108. if random_effects_on_gcobjs not in (False, True):
  109. random_effects_on_gcobjs = (
  110. invoke_around_handlers or # because it can release the GIL
  111. has_callback) # because the callback can do it
  112. funcptr = lltype.functionptr(ext_type, name, external='C',
  113. compilation_info=compilation_info,
  114. _callable=_callable,
  115. _safe_not_sandboxed=sandboxsafe,
  116. _debugexc=True, # on top of llinterp
  117. canraise=False,
  118. random_effects_on_gcobjs=
  119. random_effects_on_gcobjs,
  120. calling_conv=calling_conv,
  121. **kwds)
  122. if isinstance(_callable, ll2ctypes.LL2CtypesCallable):
  123. _callable.funcptr = funcptr
  124. if _nowrapper:
  125. return funcptr
  126. if invoke_around_handlers:
  127. # The around-handlers are releasing the GIL in a threaded pypy.
  128. # We need tons of care to ensure that no GC operation and no
  129. # exception checking occurs while the GIL is released.
  130. # The actual call is done by this small piece of non-inlinable
  131. # generated code in order to avoid seeing any GC pointer:
  132. # neither '*args' nor the GC objects originally passed in as
  133. # argument to wrapper(), if any (e.g. RPython strings).
  134. argnames = ', '.join(['a%d' % i for i in range(len(args))])
  135. source = py.code.Source("""
  136. def call_external_function(%(argnames)s):
  137. before = aroundstate.before
  138. if before: before()
  139. # NB. it is essential that no exception checking occurs here!
  140. res = funcptr(%(argnames)s)
  141. after = aroundstate.after
  142. if after: after()
  143. return res
  144. """ % locals())
  145. miniglobals = {'aroundstate': aroundstate,
  146. 'funcptr': funcptr,
  147. '__name__': __name__, # for module name propagation
  148. }
  149. exec source.compile() in miniglobals
  150. call_external_function = miniglobals['call_external_function']
  151. call_external_function._dont_inline_ = True
  152. call_external_function._annspecialcase_ = 'specialize:ll'
  153. call_external_function._gctransformer_hint_close_stack_ = True
  154. call_external_function = func_with_new_name(call_external_function,
  155. 'ccall_' + name)
  156. # don't inline, as a hack to guarantee that no GC pointer is alive
  157. # anywhere in call_external_function
  158. else:
  159. # if we don't have to invoke the aroundstate, we can just call
  160. # the low-level function pointer carelessly
  161. call_external_function = funcptr
  162. unrolling_arg_tps = unrolling_iterable(enumerate(args))
  163. def wrapper(*args):
  164. # XXX the next line is a workaround for the annotation bug
  165. # shown in rpython.test.test_llann:test_pbctype. Remove it
  166. # when the test is fixed...
  167. assert isinstance(lltype.Signed, lltype.Number)
  168. real_args = ()
  169. to_free = ()
  170. for i, TARGET in unrolling_arg_tps:
  171. arg = args[i]
  172. freeme = None
  173. if TARGET == CCHARP:
  174. if arg is None:
  175. arg = lltype.nullptr(CCHARP.TO) # None => (char*)NULL
  176. freeme = arg
  177. elif isinstance(arg, str):
  178. arg = str2charp(arg)
  179. # XXX leaks if a str2charp() fails with MemoryError
  180. # and was not the first in this function
  181. freeme = arg
  182. elif TARGET == CWCHARP:
  183. if arg is None:
  184. arg = lltype.nullptr(CWCHARP.TO) # None => (wchar_t*)NULL
  185. freeme = arg
  186. elif isinstance(arg, unicode):
  187. arg = unicode2wcharp(arg)
  188. # XXX leaks if a unicode2wcharp() fails with MemoryError
  189. # and was not the first in this function
  190. freeme = arg
  191. elif TARGET is VOIDP:
  192. if arg is None:
  193. arg = lltype.nullptr(VOIDP.TO)
  194. elif isinstance(arg, str):
  195. arg = str2charp(arg)
  196. freeme = arg
  197. elif isinstance(arg, unicode):
  198. arg = unicode2wcharp(arg)
  199. freeme = arg
  200. elif _isfunctype(TARGET) and not _isllptr(arg):
  201. # XXX pass additional arguments
  202. if invoke_around_handlers:
  203. arg = llhelper(TARGET, _make_wrapper_for(TARGET, arg,
  204. callbackholder,
  205. aroundstate))
  206. else:
  207. arg = llhelper(TARGET, _make_wrapper_for(TARGET, arg,
  208. callbackholder))
  209. else:
  210. SOURCE = lltype.typeOf(arg)
  211. if SOURCE != TARGET:
  212. if TARGET is lltype.Float:
  213. arg = float(arg)
  214. elif ((isinstance(SOURCE, lltype.Number)
  215. or SOURCE is lltype.Bool)
  216. and (isinstance(TARGET, lltype.Number)
  217. or TARGET is lltype.Bool)):
  218. arg = cast(TARGET, arg)
  219. real_args = real_args + (arg,)
  220. to_free = to_free + (freeme,)
  221. res = call_external_function(*real_args)
  222. for i, TARGET in unrolling_arg_tps:
  223. if to_free[i]:
  224. lltype.free(to_free[i], flavor='raw')
  225. if rarithmetic.r_int is not r_int:
  226. if result is INT:
  227. return cast(lltype.Signed, res)
  228. elif result is UINT:
  229. return cast(lltype.Unsigned, res)
  230. return res
  231. wrapper._annspecialcase_ = 'specialize:ll'
  232. wrapper._always_inline_ = True
  233. # for debugging, stick ll func ptr to that
  234. wrapper._ptr = funcptr
  235. wrapper = func_with_new_name(wrapper, name)
  236. if calling_conv != "c":
  237. wrapper = jit.dont_look_inside(wrapper)
  238. return wrapper
  239. class CallbackHolder:
  240. def __init__(self):
  241. self.callbacks = {}
  242. def _make_wrapper_for(TP, callable, callbackholder=None, aroundstate=None):
  243. """ Function creating wrappers for callbacks. Note that this is
  244. cheating as we assume constant callbacks and we just memoize wrappers
  245. """
  246. from pypy.rpython.lltypesystem import lltype
  247. from pypy.rpython.lltypesystem.lloperation import llop
  248. if hasattr(callable, '_errorcode_'):
  249. errorcode = callable._errorcode_
  250. else:
  251. errorcode = TP.TO.RESULT._defl()
  252. callable_name = getattr(callable, '__name__', '?')
  253. if callbackholder is not None:
  254. callbackholder.callbacks[callable] = True
  255. args = ', '.join(['a%d' % i for i in range(len(TP.TO.ARGS))])
  256. source = py.code.Source(r"""
  257. def wrapper(%s): # no *args - no GIL for mallocing the tuple
  258. llop.gc_stack_bottom(lltype.Void) # marker for trackgcroot.py
  259. if aroundstate is not None:
  260. after = aroundstate.after
  261. if after:
  262. after()
  263. # from now on we hold the GIL
  264. stackcounter.stacks_counter += 1
  265. try:
  266. result = callable(%s)
  267. except Exception, e:
  268. os.write(2,
  269. "Warning: uncaught exception in callback: %%s %%s\n" %%
  270. (callable_name, str(e)))
  271. if not we_are_translated():
  272. import traceback
  273. traceback.print_exc()
  274. result = errorcode
  275. stackcounter.stacks_counter -= 1
  276. if aroundstate is not None:
  277. before = aroundstate.before
  278. if before:
  279. before()
  280. # here we don't hold the GIL any more. As in the wrapper() produced
  281. # by llexternal, it is essential that no exception checking occurs
  282. # after the call to before().
  283. return result
  284. """ % (args, args))
  285. miniglobals = locals().copy()
  286. miniglobals['Exception'] = Exception
  287. miniglobals['os'] = os
  288. miniglobals['we_are_translated'] = we_are_translated
  289. miniglobals['stackcounter'] = stackcounter
  290. exec source.compile() in miniglobals
  291. return miniglobals['wrapper']
  292. _make_wrapper_for._annspecialcase_ = 'specialize:memo'
  293. AroundFnPtr = lltype.Ptr(lltype.FuncType([], lltype.Void))
  294. class AroundState:
  295. def _freeze_(self):
  296. self.before = None # or a regular RPython function
  297. self.after = None # or a regular RPython function
  298. return False
  299. aroundstate = AroundState()
  300. aroundstate._freeze_()
  301. class StackCounter:
  302. def _freeze_(self):
  303. self.stacks_counter = 1 # number of "stack pieces": callbacks
  304. return False # and threads increase it by one
  305. stackcounter = StackCounter()
  306. stackcounter._freeze_()
  307. def llexternal_use_eci(compilation_info):
  308. """Return a dummy function that, if called in a RPython program,
  309. adds the given ExternalCompilationInfo to it."""
  310. eci = ExternalCompilationInfo(post_include_bits=['#define PYPY_NO_OP()'])
  311. eci = eci.merge(compilation_info)
  312. return llexternal('PYPY_NO_OP', [], lltype.Void,
  313. compilation_info=eci, sandboxsafe=True, _nowrapper=True,
  314. _callable=lambda: None)
  315. def generate_macro_wrapper(name, macro, functype, eci):
  316. """Wraps a function-like macro inside a real function, and expose
  317. it with llexternal."""
  318. # Generate the function call
  319. from pypy.translator.c.database import LowLevelDatabase
  320. from pypy.translator.c.support import cdecl
  321. wrapper_name = 'pypy_macro_wrapper_%s' % (name,)
  322. argnames = ['arg%d' % (i,) for i in range(len(functype.ARGS))]
  323. db = LowLevelDatabase()
  324. implementationtypename = db.gettype(functype, argnames=argnames)
  325. if functype.RESULT is lltype.Void:
  326. pattern = '%s { %s(%s); }'
  327. else:
  328. pattern = '%s { return %s(%s); }'
  329. source = pattern % (
  330. cdecl(implementationtypename, wrapper_name),
  331. macro, ', '.join(argnames))
  332. # Now stuff this source into a "companion" eci that will be used
  333. # by ll2ctypes. We replace eci._with_ctypes, so that only one
  334. # shared library is actually compiled (when ll2ctypes calls the
  335. # first function)
  336. ctypes_eci = eci.merge(ExternalCompilationInfo(
  337. separate_module_sources=[source],
  338. export_symbols=[wrapper_name],
  339. ))
  340. if hasattr(eci, '_with_ctypes'):
  341. ctypes_eci = eci._with_ctypes.merge(ctypes_eci)
  342. eci._with_ctypes = ctypes_eci
  343. func = llexternal(wrapper_name, functype.ARGS, functype.RESULT,
  344. compilation_info=eci, _nowrapper=True)
  345. # _nowrapper=True returns a pointer which is not hashable
  346. return lambda *args: func(*args)
  347. # ____________________________________________________________
  348. # Few helpers for keeping callback arguments alive
  349. # this makes passing opaque objects possible (they don't even pass
  350. # through C, only integer specifying number passes)
  351. _KEEPER_CACHE = {}
  352. def _keeper_for_type(TP):
  353. try:
  354. return _KEEPER_CACHE[TP]
  355. except KeyError:
  356. tp_str = str(TP) # make annotator happy
  357. class KeepaliveKeeper(object):
  358. def __init__(self):
  359. self.stuff_to_keepalive = []
  360. self.free_positions = []
  361. keeper = KeepaliveKeeper()
  362. _KEEPER_CACHE[TP] = keeper
  363. return keeper
  364. _keeper_for_type._annspecialcase_ = 'specialize:memo'
  365. def register_keepalive(obj):
  366. """ Register object obj to be kept alive,
  367. returns a position for that object
  368. """
  369. keeper = _keeper_for_type(lltype.typeOf(obj))
  370. if len(keeper.free_positions):
  371. pos = keeper.free_positions.pop()
  372. keeper.stuff_to_keepalive[pos] = obj
  373. return pos
  374. # we don't have any free positions
  375. pos = len(keeper.stuff_to_keepalive)
  376. keeper.stuff_to_keepalive.append(obj)
  377. return pos
  378. register_keepalive._annspecialcase_ = 'specialize:argtype(0)'
  379. def get_keepalive_object(pos, TP):
  380. keeper = _keeper_for_type(TP)
  381. return keeper.stuff_to_keepalive[pos]
  382. get_keepalive_object._annspecialcase_ = 'specialize:arg(1)'
  383. def unregister_keepalive(pos, TP):
  384. """ Unregister an object of type TP, stored at position
  385. pos (position previously returned by register_keepalive)
  386. """
  387. keeper = _keeper_for_type(TP)
  388. keeper.stuff_to_keepalive[pos] = None
  389. keeper.free_positions.append(pos)
  390. unregister_keepalive._annspecialcase_ = 'specialize:arg(1)'
  391. # ____________________________________________________________
  392. TYPES = []
  393. for _name in 'short int long'.split():
  394. for name in (_name, 'unsigned ' + _name):
  395. TYPES.append(name)
  396. TYPES += ['signed char', 'unsigned char',
  397. 'long long', 'unsigned long long',
  398. 'size_t', 'time_t', 'wchar_t',
  399. 'uintptr_t', 'intptr_t']
  400. _TYPES_ARE_UNSIGNED = set(['size_t', 'uintptr_t']) # plus "unsigned *"
  401. if os.name != 'nt':
  402. TYPES.append('mode_t')
  403. TYPES.append('pid_t')
  404. TYPES.append('ssize_t')
  405. else:
  406. MODE_T = lltype.Signed
  407. PID_T = lltype.Signed
  408. SSIZE_T = lltype.Signed
  409. def populate_inttypes():
  410. names = []
  411. populatelist = []
  412. for name in TYPES:
  413. c_name = name
  414. if name.startswith('unsigned'):
  415. name = 'u' + name[9:]
  416. signed = False
  417. else:
  418. signed = (name not in _TYPES_ARE_UNSIGNED)
  419. name = name.replace(' ', '')
  420. names.append(name)
  421. populatelist.append((name.upper(), c_name, signed))
  422. platform.populate_inttypes(populatelist)
  423. return names
  424. def setup():
  425. """ creates necessary c-level types
  426. """
  427. names = populate_inttypes()
  428. result = []
  429. for name in names:
  430. tp = platform.types[name.upper()]
  431. globals()['r_' + name] = platform.numbertype_to_rclass[tp]
  432. globals()[name.upper()] = tp
  433. tpp = lltype.Ptr(lltype.Array(tp, hints={'nolength': True}))
  434. globals()[name.upper()+'P'] = tpp
  435. result.append(tp)
  436. return result
  437. NUMBER_TYPES = setup()
  438. platform.numbertype_to_rclass[lltype.Signed] = int # avoid "r_long" for common cases
  439. r_int_real = rarithmetic.build_int("r_int_real", r_int.SIGN, r_int.BITS, True)
  440. INT_real = lltype.build_number("INT", r_int_real)
  441. platform.numbertype_to_rclass[INT_real] = r_int_real
  442. NUMBER_TYPES.append(INT_real)
  443. # ^^^ this creates at least the following names:
  444. # --------------------------------------------------------------------
  445. # Type RPython integer class doing wrap-around
  446. # --------------------------------------------------------------------
  447. # SIGNEDCHAR r_signedchar
  448. # UCHAR r_uchar
  449. # SHORT r_short
  450. # USHORT r_ushort
  451. # INT r_int
  452. # UINT r_uint
  453. # LONG r_long
  454. # ULONG r_ulong
  455. # LONGLONG r_longlong
  456. # ULONGLONG r_ulonglong
  457. # WCHAR_T r_wchar_t
  458. # SIZE_T r_size_t
  459. # SSIZE_T r_ssize_t
  460. # TIME_T r_time_t
  461. # --------------------------------------------------------------------
  462. # Note that rffi.r_int is not necessarily the same as
  463. # rarithmetic.r_int, etc! rffi.INT/r_int correspond to the C-level
  464. # 'int' type, whereas rarithmetic.r_int corresponds to the
  465. # Python-level int type (which is a C long). Fun.
  466. def CStruct(name, *fields, **kwds):
  467. """ A small helper to create external C structure, not the
  468. pypy one
  469. """
  470. hints = kwds.get('hints', {})
  471. hints = hints.copy()
  472. kwds['hints'] = hints
  473. hints['external'] = 'C'
  474. hints['c_name'] = name
  475. # Hack: prefix all attribute names with 'c_' to cope with names starting
  476. # with '_'. The genc backend removes the 'c_' prefixes...
  477. c_fields = [('c_' + key, value) for key, value in fields]
  478. return lltype.Struct(name, *c_fields, **kwds)
  479. def CStructPtr(*args, **kwds):
  480. return lltype.Ptr(CStruct(*args, **kwds))
  481. def CFixedArray(tp, size):
  482. return lltype.FixedSizeArray(tp, size)
  483. CFixedArray._annspecialcase_ = 'specialize:memo'
  484. def CArray(tp):
  485. return lltype.Array(tp, hints={'nolength': True})
  486. CArray._annspecialcase_ = 'specialize:memo'
  487. def CArrayPtr(tp):
  488. return lltype.Ptr(CArray(tp))
  489. CArrayPtr._annspecialcase_ = 'specialize:memo'
  490. def CCallback(args, res):
  491. return lltype.Ptr(lltype.FuncType(args, res))
  492. CCallback._annspecialcase_ = 'specialize:memo'
  493. def COpaque(name=None, ptr_typedef=None, hints=None, compilation_info=None):
  494. if compilation_info is None:
  495. compilation_info = ExternalCompilationInfo()
  496. if hints is None:
  497. hints = {}
  498. else:
  499. hints = hints.copy()
  500. hints['external'] = 'C'
  501. if name is not None:
  502. hints['c_name'] = name
  503. if ptr_typedef is not None:
  504. hints['c_pointer_typedef'] = ptr_typedef
  505. def lazy_getsize(cache={}):
  506. from pypy.rpython.tool import rffi_platform
  507. try:
  508. return cache[name]
  509. except KeyError:
  510. val = rffi_platform.sizeof(name, compilation_info)
  511. cache[name] = val
  512. return val
  513. hints['getsize'] = lazy_getsize
  514. return lltype.OpaqueType(name, hints)
  515. def COpaquePtr(*args, **kwds):
  516. typedef = kwds.pop('typedef', None)
  517. return lltype.Ptr(COpaque(ptr_typedef=typedef, *args, **kwds))
  518. def CExternVariable(TYPE, name, eci, _CConstantClass=CConstant,
  519. sandboxsafe=False, _nowrapper=False,
  520. c_type=None):
  521. """Return a pair of functions - a getter and a setter - to access
  522. the given global C variable.
  523. """
  524. from pypy.translator.c.primitive import PrimitiveType
  525. from pypy.translator.tool.cbuild import ExternalCompilationInfo
  526. # XXX we cannot really enumerate all C types here, do it on a case-by-case
  527. # basis
  528. if c_type is None:
  529. if TYPE == CCHARPP:
  530. c_type = 'char **'
  531. elif TYPE == CCHARP:
  532. c_type = 'char *'
  533. elif TYPE == INT or TYPE == LONG:
  534. assert False, "ambiguous type on 32-bit machines: give a c_type"
  535. else:
  536. c_type = PrimitiveType[TYPE]
  537. assert c_type.endswith(' @')
  538. c_type = c_type[:-2] # cut the trailing ' @'
  539. getter_name = 'get_' + name
  540. setter_name = 'set_' + name
  541. getter_prototype = "%(c_type)s %(getter_name)s ();" % locals()
  542. setter_prototype = "void %(setter_name)s (%(c_type)s v);" % locals()
  543. c_getter = "%(c_type)s %(getter_name)s () { return %(name)s; }" % locals()
  544. c_setter = "void %(setter_name)s (%(c_type)s v) { %(name)s = v; }" % locals()
  545. lines = ["#include <%s>" % i for i in eci.includes]
  546. if sys.platform != 'win32':
  547. lines.append('extern %s %s;' % (c_type, name))
  548. lines.append(c_getter)
  549. lines.append(c_setter)
  550. sources = ('\n'.join(lines),)
  551. new_eci = eci.merge(ExternalCompilationInfo(
  552. separate_module_sources = sources,
  553. post_include_bits = [getter_prototype, setter_prototype],
  554. export_symbols = [getter_name, setter_name],
  555. ))
  556. getter = llexternal(getter_name, [], TYPE, compilation_info=new_eci,
  557. sandboxsafe=sandboxsafe, _nowrapper=_nowrapper)
  558. setter = llexternal(setter_name, [TYPE], lltype.Void,
  559. compilation_info=new_eci, sandboxsafe=sandboxsafe,
  560. _nowrapper=_nowrapper)
  561. return getter, setter
  562. # char, represented as a Python character
  563. # (use SIGNEDCHAR or UCHAR for the small integer types)
  564. CHAR = lltype.Char
  565. # double
  566. DOUBLE = lltype.Float
  567. LONGDOUBLE = lltype.LongFloat
  568. # float - corresponds to pypy.rlib.rarithmetic.r_float, and supports no
  569. # operation except rffi.cast() between FLOAT and DOUBLE
  570. FLOAT = lltype.SingleFloat
  571. r_singlefloat = rarithmetic.r_singlefloat
  572. # void * - for now, represented as char *
  573. VOIDP = lltype.Ptr(lltype.Array(lltype.Char, hints={'nolength': True, 'render_as_void': True}))
  574. NULL = None
  575. # void **
  576. VOIDPP = CArrayPtr(VOIDP)
  577. # char *
  578. CCHARP = lltype.Ptr(lltype.Array(lltype.Char, hints={'nolength': True}))
  579. # wchar_t *
  580. CWCHARP = lltype.Ptr(lltype.Array(lltype.UniChar, hints={'nolength': True}))
  581. # int *, unsigned int *, etc.
  582. #INTP = ... see setup() above
  583. # double *
  584. DOUBLEP = lltype.Ptr(lltype.Array(DOUBLE, hints={'nolength': True}))
  585. # float *
  586. FLOATP = lltype.Ptr(lltype.Array(FLOAT, hints={'nolength': True}))
  587. # Signed, Signed *
  588. SIGNED = lltype.Signed
  589. SIGNEDP = lltype.Ptr(lltype.Array(SIGNED, hints={'nolength': True}))
  590. # various type mapping
  591. # conversions between str and char*
  592. # conversions between unicode and wchar_t*
  593. def make_string_mappings(strtype):
  594. if strtype is str:
  595. from pypy.rpython.lltypesystem.rstr import STR as STRTYPE
  596. from pypy.rpython.annlowlevel import llstr as llstrtype
  597. from pypy.rpython.annlowlevel import hlstr as hlstrtype
  598. TYPEP = CCHARP
  599. ll_char_type = lltype.Char
  600. lastchar = '\x00'
  601. builder_class = StringBuilder
  602. else:
  603. from pypy.rpython.lltypesystem.rstr import UNICODE as STRTYPE
  604. from pypy.rpython.annlowlevel import llunicode as llstrtype
  605. from pypy.rpython.annlowlevel import hlunicode as hlstrtype
  606. TYPEP = CWCHARP
  607. ll_char_type = lltype.UniChar
  608. lastchar = u'\x00'
  609. builder_class = UnicodeBuilder
  610. # str -> char*
  611. def str2charp(s):
  612. """ str -> char*
  613. """
  614. array = lltype.malloc(TYPEP.TO, len(s) + 1, flavor='raw')
  615. i = len(s)
  616. array[i] = lastchar
  617. i -= 1
  618. while i >= 0:
  619. array[i] = s[i]
  620. i -= 1
  621. return array
  622. str2charp._annenforceargs_ = [strtype]
  623. def free_charp(cp):
  624. lltype.free(cp, flavor='raw')
  625. # char* -> str
  626. # doesn't free char*
  627. def charp2str(cp):
  628. b = builder_class()
  629. i = 0
  630. while cp[i] != lastchar:
  631. b.append(cp[i])
  632. i += 1
  633. return assert_str0(b.build())
  634. # str -> char*
  635. # Can't inline this because of the raw address manipulation.
  636. @jit.dont_look_inside
  637. def get_nonmovingbuffer(data):
  638. """
  639. Either returns a non-moving copy or performs neccessary pointer
  640. arithmetic to return a pointer to the characters of a string if the
  641. string is already nonmovable. Must be followed by a
  642. free_nonmovingbuffer call.
  643. """
  644. if rgc.can_move(data):
  645. count = len(data)
  646. buf = lltype.malloc(TYPEP.TO, count, flavor='raw')
  647. for i in range(count):
  648. buf[i] = data[i]
  649. return buf
  650. else:
  651. data_start = cast_ptr_to_adr(llstrtype(data)) + \
  652. offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0)
  653. return cast(TYPEP, data_start)
  654. get_nonmovingbuffer._annenforceargs_ = [strtype]
  655. # (str, char*) -> None
  656. # Can't inline this because of the raw address manipulation.
  657. @jit.dont_look_inside
  658. def free_nonmovingbuffer(data, buf):
  659. """
  660. Either free a non-moving buffer or keep the original storage alive.
  661. """
  662. # We cannot rely on rgc.can_move(data) here, because its result
  663. # might have changed since get_nonmovingbuffer(). Instead we check
  664. # if 'buf' points inside 'data'. This is only possible if we
  665. # followed the 2nd case in get_nonmovingbuffer(); in the first case,
  666. # 'buf' points to its own raw-malloced memory.
  667. data = llstrtype(data)
  668. data_start = cast_ptr_to_adr(data) + \
  669. offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0)
  670. followed_2nd_path = (buf == cast(TYPEP, data_start))
  671. keepalive_until_here(data)
  672. if not followed_2nd_path:
  673. lltype.free(buf, flavor='raw')
  674. free_nonmovingbuffer._annenforceargs_ = [strtype, None]
  675. # int -> (char*, str)
  676. def alloc_buffer(count):
  677. """
  678. Returns a (raw_buffer, gc_buffer) pair, allocated with count bytes.
  679. The raw_buffer can be safely passed to a native function which expects
  680. it to not move. Call str_from_buffer with the returned values to get a
  681. safe high-level string. When the garbage collector cooperates, this
  682. allows for the process to be performed without an extra copy.
  683. Make sure to call keep_buffer_alive_until_here on the returned values.
  684. """
  685. raw_buf = lltype.malloc(TYPEP.TO, count, flavor='raw')
  686. return raw_buf, lltype.nullptr(STRTYPE)
  687. alloc_buffer._always_inline_ = True # to get rid of the returned tuple
  688. alloc_buffer._annenforceargs_ = [int]
  689. # (char*, str, int, int) -> None
  690. @jit.dont_look_inside
  691. def str_from_buffer(raw_buf, gc_buf, allocated_size, needed_size):
  692. """
  693. Converts from a pair returned by alloc_buffer to a high-level string.
  694. The returned string will be truncated to needed_size.
  695. """
  696. assert allocated_size >= needed_size
  697. if gc_buf and (allocated_size == needed_size):
  698. return hlstrtype(gc_buf)
  699. new_buf = lltype.malloc(STRTYPE, needed_size)
  700. str_chars_offset = (offsetof(STRTYPE, 'chars') + \
  701. itemoffsetof(STRTYPE.chars, 0))
  702. if gc_buf:
  703. src = cast_ptr_to_adr(gc_buf) + str_chars_offset
  704. else:
  705. src = cast_ptr_to_adr(raw_buf) + itemoffsetof(TYPEP.TO, 0)
  706. dest = cast_ptr_to_adr(new_buf) + str_chars_offset
  707. raw_memcopy(src, dest,
  708. llmemory.sizeof(ll_char_type) * needed_size)
  709. keepalive_until_here(gc_buf)
  710. keepalive_until_here(new_buf)
  711. return hlstrtype(new_buf)
  712. # (char*, str) -> None
  713. @jit.dont_look_inside
  714. def keep_buffer_alive_until_here(raw_buf, gc_buf):
  715. """
  716. Keeps buffers alive or frees temporary buffers created by alloc_buffer.
  717. This must be called after a call to alloc_buffer, usually in a
  718. try/finally block.
  719. """
  720. if gc_buf:
  721. keepalive_until_here(gc_buf)
  722. elif raw_buf:
  723. lltype.free(raw_buf, flavor='raw')
  724. # char* -> str, with an upper bound on the length in case there is no \x00
  725. def charp2strn(cp, maxlen):
  726. b = builder_class(maxlen)
  727. i = 0
  728. while i < maxlen and cp[i] != lastchar:
  729. b.append(cp[i])
  730. i += 1
  731. return assert_str0(b.build())
  732. # char* and size -> str (which can contain null bytes)
  733. def charpsize2str(cp, size):
  734. b = builder_class(size)
  735. b.append_charpsize(cp, size)
  736. return b.build()
  737. charpsize2str._annenforceargs_ = [None, int]
  738. return (str2charp, free_charp, charp2str,
  739. get_nonmovingbuffer, free_nonmovingbuffer,
  740. alloc_buffer, str_from_buffer, keep_buffer_alive_until_here,
  741. charp2strn, charpsize2str,
  742. )
  743. (str2charp, free_charp, charp2str,
  744. get_nonmovingbuffer, free_nonmovingbuffer,
  745. alloc_buffer, str_from_buffer, keep_buffer_alive_until_here,
  746. charp2strn, charpsize2str,
  747. ) = make_string_mappings(str)
  748. (unicode2wcharp, free_wcharp, wcharp2unicode,
  749. get_nonmoving_unicodebuffer, free_nonmoving_unicodebuffer,
  750. alloc_unicodebuffer, unicode_from_buffer, keep_unicodebuffer_alive_until_here,
  751. wcharp2unicoden, wcharpsize2unicode,
  752. ) = make_string_mappings(unicode)
  753. # char**
  754. CCHARPP = lltype.Ptr(lltype.Array(CCHARP, hints={'nolength': True}))
  755. def liststr2charpp(l):
  756. """ list[str] -> char**, NULL terminated
  757. """
  758. array = lltype.malloc(CCHARPP.TO, len(l) + 1, flavor='raw')
  759. for i in range(len(l)):
  760. array[i] = str2charp(l[i])
  761. array[len(l)] = lltype.nullptr(CCHARP.TO)
  762. return array
  763. liststr2charpp._annenforceargs_ = [[annmodel.s_Str0]] # List of strings
  764. def free_charpp(ref):
  765. """ frees list of char**, NULL terminated
  766. """
  767. i = 0
  768. while ref[i]:
  769. free_charp(ref[i])
  770. i += 1
  771. lltype.free(ref, flavor='raw')
  772. def charpp2liststr(p):
  773. """ char** NULL terminated -> list[str]. No freeing is done.
  774. """
  775. result = []
  776. i = 0
  777. while p[i]:
  778. result.append(charp2str(p[i]))
  779. i += 1
  780. return result
  781. cast = ll2ctypes.force_cast # a forced, no-checking cast
  782. ptradd = ll2ctypes.force_ptradd # equivalent of "ptr + n" in C.
  783. # the ptr must point to an array.
  784. def size_and_sign(tp):
  785. size = sizeof(tp)
  786. try:
  787. unsigned = not tp._type.SIGNED
  788. except AttributeError:
  789. if not isinstance(tp, lltype.Primitive):
  790. unsigned = False
  791. elif tp in (lltype.Signed, FLOAT, DOUBLE, llmemory.Address):
  792. unsigned = False
  793. elif tp in (lltype.Char, lltype.UniChar, lltype.Bool):
  794. unsigned = True
  795. else:
  796. raise AssertionError("size_and_sign(%r)" % (tp,))
  797. return size, unsigned
  798. def sizeof(tp):
  799. """Similar to llmemory.sizeof() but tries hard to return a integer
  800. instead of a symbolic value.
  801. """
  802. if isinstance(tp, lltype.Typedef):
  803. tp = tp.OF
  804. if isinstance(tp, lltype.FixedSizeArray):
  805. return sizeof(tp.OF) * tp.length
  806. if isinstance(tp, lltype.Struct):
  807. # the hint is present in structures probed by rffi_platform.
  808. size = tp._hints.get('size')
  809. if size is None:
  810. size = llmemory.sizeof(tp) # a symbolic result in this case
  811. return size
  812. if isinstance(tp, lltype.Ptr) or tp is llmemory.Address:
  813. tp = lltype.Signed
  814. if tp is lltype.Char or tp is lltype.Bool:
  815. return 1
  816. if tp is lltype.UniChar:
  817. return r_wchar_t.BITS/8
  818. if tp is lltype.Float:
  819. return 8
  820. if tp is lltype.SingleFloat:
  821. return 4
  822. assert isinstance(tp, lltype.Number)
  823. if tp is lltype.Signed:
  824. return LONG_BIT/8
  825. return tp._type.BITS/8
  826. sizeof._annspecialcase_ = 'specialize:memo'
  827. def offsetof(STRUCT, fieldname):
  828. """Similar to llmemory.offsetof() but tries hard to return a integer
  829. instead of a symbolic value.
  830. """
  831. # the hint is present in structures probed by rffi_platform.
  832. fieldoffsets = STRUCT._hints.get('fieldoffsets')
  833. if fieldoffsets is not None:
  834. # a numeric result when known
  835. for index, name in enumerate(STRUCT._names):
  836. if name == fieldname:
  837. return fieldoffsets[index]
  838. # a symbolic result as a fallback
  839. return llmemory.offsetof(STRUCT, fieldname)
  840. offsetof._annspecialcase_ = 'specialize:memo'
  841. # check that we have a sane configuration
  842. assert maxint == (1 << (8 * sizeof(lltype.Signed) - 1)) - 1, (
  843. "Mixed configuration of the word size of the machine:\n\t"
  844. "the underlying Python was compiled with maxint=%d,\n\t"
  845. "but the C compiler says that 'long' is %d bytes" % (
  846. maxint, sizeof(lltype.Signed)))
  847. # ********************** some helpers *******************
  848. def make(STRUCT, **fields):
  849. """ Malloc a structure and populate it's fields
  850. """
  851. ptr = lltype.malloc(STRUCT, flavor='raw')
  852. for name, value in fields.items():
  853. setattr(ptr, name, value)
  854. return ptr
  855. class MakeEntry(ExtRegistryEntry):
  856. _about_ = make
  857. def compute_result_annotation(self, s_type, **s_fields):
  858. TP = s_type.const
  859. if not isinstance(TP, lltype.Struct):
  860. raise TypeError("make called with %s instead of Struct as first argument" % TP)
  861. return annmodel.SomePtr(lltype.Ptr(TP))
  862. def specialize_call(self, hop, **fields):
  863. assert hop.args_s[0].is_constant()
  864. vlist = [hop.inputarg(lltype.Void, arg=0)]
  865. flags = {'flavor':'raw'}
  866. vlist.append(hop.inputconst(lltype.Void, flags))
  867. hop.has_implicit_exception(MemoryError) # record that we know about it
  868. hop.exception_is_here()
  869. v_ptr = hop.genop('malloc', vlist, resulttype=hop.r_result.lowleveltype)
  870. for name, i in fields.items():
  871. name = name[2:]
  872. v_arg = hop.inputarg(hop.args_r[i], arg=i)
  873. v_name = hop.inputconst(lltype.Void, name)
  874. hop.genop('setfield', [v_ptr, v_name, v_arg])
  875. return v_ptr
  876. def structcopy(pdst, psrc):
  877. """Copy all the fields of the structure given by 'psrc'
  878. into the structure given by 'pdst'.
  879. """
  880. copy_fn = _get_structcopy_fn(lltype.typeOf(pdst), lltype.typeOf(psrc))
  881. copy_fn(pdst, psrc)
  882. structcopy._annspecialcase_ = 'specialize:ll'
  883. def _get_structcopy_fn(PDST, PSRC):
  884. assert PDST == PSRC
  885. if isinstance(PDST.TO, lltype.Struct):
  886. STRUCT = PDST.TO
  887. padding = STRUCT._hints.get('padding', ())
  888. fields = [(name, STRUCT._flds[name]) for name in STRUCT._names
  889. if name not in padding]
  890. unrollfields = unrolling_iterable(fields)
  891. def copyfn(pdst, psrc):
  892. for name, TYPE in unrollfields:
  893. if isinstance(TYPE, lltype.ContainerType):
  894. structcopy(getattr(pdst, name), getattr(psrc, name))
  895. else:
  896. setattr(pdst, name, getattr(psrc, name))
  897. return copyfn
  898. else:
  899. raise NotImplementedError('structcopy: type %r' % (PDST.TO,))
  900. _get_structcopy_fn._annspecialcase_ = 'specialize:memo'
  901. def setintfield(pdst, fieldname, value):
  902. """Maybe temporary: a helper to set an integer field into a structure,
  903. transparently casting between the various integer types.
  904. """
  905. STRUCT = lltype.typeOf(pdst).TO
  906. TSRC = lltype.typeOf(value)
  907. TDST = getattr(STRUCT, fieldname)
  908. assert isinstance(TSRC, lltype.Number)
  909. assert isinstance(TDST, lltype.Number)
  910. setattr(pdst, fieldname, cast(TDST, value))
  911. setintfield._annspecialcase_ = 'specialize:ll_and_arg(1)'
  912. def getintfield(pdst, fieldname):
  913. """As temporary as previous: get integer from a field in structure,
  914. casting it to lltype.Signed
  915. """
  916. return cast(lltype.Signed, getattr(pdst, fieldname))
  917. getintfield._annspecialcase_ = 'specialize:ll_and_arg(1)'
  918. class scoped_str2charp:
  919. def __init__(self, value):
  920. if value is not None:
  921. self.buf = str2charp(value)
  922. else:
  923. self.buf = lltype.nullptr(CCHARP.TO)
  924. def __enter__(self):
  925. return self.buf
  926. def __exit__(self, *args):
  927. if self.buf:
  928. free_charp(self.buf)
  929. class scoped_unicode2wcharp:
  930. def __init__(self, value):
  931. if value is not None:
  932. self.buf = unicode2wcharp(value)
  933. else:
  934. self.buf = lltype.nullptr(CWCHARP.TO)
  935. def __enter__(self):
  936. return self.buf
  937. def __exit__(self, *args):
  938. if self.buf:
  939. free_wcharp(self.buf)
  940. class scoped_nonmovingbuffer:
  941. def __init__(self, data):
  942. self.data = data
  943. def __enter__(self):
  944. self.buf = get_nonmovingbuffer(self.data)
  945. return self.buf
  946. def __exit__(self, *args):
  947. free_nonmovingbuffer(self.data, self.buf)
  948. class scoped_nonmoving_unicodebuffer:
  949. def __init__(self, data):
  950. self.data = data
  951. def __enter__(self):
  952. self.buf = get_nonmoving_unicodebuffer(self.data)
  953. return self.buf
  954. def __exit__(self, *args):
  955. free_nonmoving_unicodebuffer(self.data, self.buf)
  956. class scoped_alloc_buffer:
  957. def __init__(self, size):
  958. self.size = size
  959. def __enter__(self):
  960. self.raw, self.gc_buf = alloc_buffer(self.size)
  961. return self
  962. def __exit__(self, *args):
  963. keep_buffer_alive_until_here(self.raw, self.gc_buf)
  964. def str(self, length):
  965. return str_from_buffer(self.raw, self.gc_buf, self.size, length)
  966. class scoped_alloc_unicodebuffer:
  967. def __init__(self, size):
  968. self.size = size
  969. def __enter__(self):
  970. self.raw, self.gc_buf = alloc_unicodebuffer(self.size)
  971. return self
  972. def __exit__(self, *args):
  973. keep_unicodebuffer_alive_until_here(self.raw, self.gc_buf)
  974. def str(self, length):
  975. return unicode_from_buffer(self.raw, self.gc_buf, self.size, length)
  976. # You would have to have a *huge* amount of data for this to block long enough
  977. # to be worth it to release the GIL.
  978. c_memcpy = llexternal("memcpy",
  979. [VOIDP, VOIDP, SIZE_T],
  980. lltype.Void,
  981. threadsafe=False
  982. )