PageRenderTime 38ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/rpython/rtyper/lltypesystem/ll2ctypes.py

https://bitbucket.org/pypy/pypy/
Python | 1575 lines | 1345 code | 135 blank | 95 comment | 312 complexity | 08fa2372375a9b329cd85a8973689a43 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import sys
  2. try:
  3. import ctypes
  4. import ctypes.util
  5. if not hasattr(ctypes, 'c_longdouble'):
  6. ctypes.c_longdouble = ctypes.c_double
  7. except ImportError:
  8. ctypes = None
  9. if sys.version_info >= (2, 6):
  10. load_library_kwargs = {'use_errno': True}
  11. else:
  12. load_library_kwargs = {}
  13. import os, platform as host_platform
  14. from rpython.rtyper.lltypesystem import lltype, llmemory
  15. from rpython.rtyper.extfunc import ExtRegistryEntry
  16. from rpython.rlib.objectmodel import Symbolic, ComputedIntSymbolic
  17. from rpython.tool.uid import fixid
  18. from rpython.rlib.rarithmetic import r_singlefloat, r_longfloat, base_int, intmask
  19. from rpython.rlib.rarithmetic import is_emulated_long, maxint
  20. from rpython.annotator import model as annmodel
  21. from rpython.rtyper.llannotation import lltype_to_annotation
  22. from rpython.rtyper.llannotation import SomePtr
  23. from rpython.rtyper.llinterp import LLInterpreter, LLException
  24. from rpython.rtyper.rclass import OBJECT, OBJECT_VTABLE
  25. from rpython.rtyper import raddress
  26. from rpython.translator.platform import platform
  27. from array import array
  28. try:
  29. from thread import _local as tlsobject
  30. except ImportError:
  31. class tlsobject(object):
  32. pass
  33. try:
  34. from threading import RLock
  35. except ImportError:
  36. class RLock(object):
  37. def __enter__(self):
  38. pass
  39. def __exit__(self, *args):
  40. pass
  41. rlock = RLock()
  42. _POSIX = os.name == "posix"
  43. _MS_WINDOWS = os.name == "nt"
  44. _FREEBSD = sys.platform.startswith('freebsd')
  45. _64BIT = "64bit" in host_platform.architecture()[0]
  46. # ____________________________________________________________
  47. far_regions = None
  48. def allocate_ctypes(ctype):
  49. if far_regions:
  50. import random
  51. pieces = far_regions._ll2ctypes_pieces
  52. num = random.randrange(len(pieces)+1)
  53. if num == len(pieces):
  54. return ctype()
  55. i1, stop = pieces[num]
  56. i2 = i1 + ((ctypes.sizeof(ctype) or 1) + 7) & ~7
  57. if i2 > stop:
  58. raise MemoryError("out of memory in far_regions")
  59. pieces[num] = i2, stop
  60. p = lltype2ctypes(far_regions.getptr(i1))
  61. return ctypes.cast(p, ctypes.POINTER(ctype)).contents
  62. else:
  63. return ctype()
  64. def do_allocation_in_far_regions():
  65. """On 32 bits: this reserves 1.25GB of address space, or 2.5GB on POSIX,
  66. which helps test this module for address values that are signed or
  67. unsigned.
  68. On 64-bits: reserves 10 times 2GB of address space. This should help
  69. to find 32-vs-64-bit issues in the JIT. It is likely that objects
  70. are further apart than 32 bits can represent; it is also possible
  71. to hit the corner case of being precisely e.g. 2GB - 8 bytes apart.
  72. Avoid this function if your OS reserves actual RAM from mmap() eagerly.
  73. """
  74. global far_regions
  75. if not far_regions:
  76. from rpython.rlib import rmmap
  77. if _64BIT:
  78. PIECE_STRIDE = 0x80000000
  79. else:
  80. if _POSIX:
  81. PIECE_STRIDE = 0x10000000
  82. else:
  83. PIECE_STRIDE = 0x08000000
  84. if _POSIX:
  85. PIECE_SIZE = 0x04000000
  86. else:
  87. PIECE_SIZE = PIECE_STRIDE
  88. PIECES = 10
  89. flags = (0,)
  90. if _POSIX:
  91. flags = (rmmap.MAP_PRIVATE|rmmap.MAP_ANONYMOUS|rmmap.MAP_NORESERVE,
  92. rmmap.PROT_READ|rmmap.PROT_WRITE)
  93. elif _MS_WINDOWS:
  94. flags = (rmmap.MEM_RESERVE,)
  95. # XXX seems not to work
  96. else:
  97. assert False # should always generate flags
  98. # Map and unmap something just to exercise unmap so that we (lazily)
  99. # build the ctypes callable. Otherwise, when we reach unmap below
  100. # we may already have a giant map and be unable to fork, as for the
  101. # /sbin/ldconfig call inside ctypes.util.find_library().
  102. rmmap.mmap(-1, 4096, *flags).close()
  103. m = rmmap.mmap(-1, PIECES * PIECE_STRIDE, *flags)
  104. m.close = lambda : None # leak instead of giving a spurious
  105. # error at CPython's shutdown
  106. m._ll2ctypes_pieces = []
  107. for i in range(PIECES):
  108. start = i * PIECE_STRIDE
  109. m._ll2ctypes_pieces.append((start, start + PIECE_SIZE))
  110. if _POSIX:
  111. m.unmap_range(start + PIECE_SIZE, PIECE_STRIDE - PIECE_SIZE)
  112. far_regions = m
  113. # ____________________________________________________________
  114. _ctypes_cache = {}
  115. _eci_cache = {}
  116. def _setup_ctypes_cache():
  117. from rpython.rtyper.lltypesystem import rffi
  118. if is_emulated_long:
  119. signed_as_ctype = ctypes.c_longlong
  120. unsigned_as_ctypes = ctypes.c_ulonglong
  121. else:
  122. signed_as_ctype = ctypes.c_long
  123. unsigned_as_ctypes = ctypes.c_ulong
  124. _ctypes_cache.update({
  125. lltype.Signed: signed_as_ctype,
  126. lltype.Unsigned: unsigned_as_ctypes,
  127. lltype.Char: ctypes.c_ubyte,
  128. rffi.DOUBLE: ctypes.c_double,
  129. rffi.FLOAT: ctypes.c_float,
  130. rffi.LONGDOUBLE: ctypes.c_longdouble,
  131. rffi.SIGNEDCHAR: ctypes.c_byte,
  132. rffi.UCHAR: ctypes.c_ubyte,
  133. rffi.SHORT: ctypes.c_short,
  134. rffi.USHORT: ctypes.c_ushort,
  135. rffi.INT: ctypes.c_int,
  136. rffi.INT_real: ctypes.c_int,
  137. rffi.UINT: ctypes.c_uint,
  138. rffi.LONG: ctypes.c_long,
  139. rffi.ULONG: ctypes.c_ulong,
  140. rffi.LONGLONG: ctypes.c_longlong,
  141. rffi.ULONGLONG: ctypes.c_ulonglong,
  142. rffi.SIZE_T: ctypes.c_size_t,
  143. lltype.Bool: getattr(ctypes, "c_bool", ctypes.c_byte),
  144. llmemory.Address: ctypes.c_void_p,
  145. llmemory.GCREF: ctypes.c_void_p,
  146. llmemory.WeakRef: ctypes.c_void_p, # XXX
  147. })
  148. if '__int128_t' in rffi.TYPES:
  149. class c_int128(ctypes.Array): # based on 2 ulongs
  150. _type_ = ctypes.c_uint64
  151. _length_ = 2
  152. @property
  153. def value(self):
  154. res = self[0] | (self[1] << 64)
  155. if res >= (1 << 127):
  156. res -= 1 << 128
  157. return res
  158. _ctypes_cache[rffi.__INT128_T] = c_int128
  159. # for unicode strings, do not use ctypes.c_wchar because ctypes
  160. # automatically converts arrays into unicode strings.
  161. # Pick the unsigned int that has the same size.
  162. if ctypes.sizeof(ctypes.c_wchar) == ctypes.sizeof(ctypes.c_uint16):
  163. _ctypes_cache[lltype.UniChar] = ctypes.c_uint16
  164. else:
  165. _ctypes_cache[lltype.UniChar] = ctypes.c_uint32
  166. def build_ctypes_struct(S, delayed_builders, max_n=None):
  167. def builder():
  168. # called a bit later to fill in _fields_
  169. # (to handle recursive structure pointers)
  170. fields = []
  171. for fieldname in S._names:
  172. FIELDTYPE = S._flds[fieldname]
  173. if max_n is not None and fieldname == S._arrayfld:
  174. cls = get_ctypes_array_of_size(FIELDTYPE, max_n)
  175. else:
  176. if isinstance(FIELDTYPE, lltype.Ptr):
  177. cls = get_ctypes_type(FIELDTYPE, delayed_builders)
  178. else:
  179. cls = get_ctypes_type(FIELDTYPE, delayed_builders,
  180. cannot_delay=True)
  181. fields.append((fieldname, cls))
  182. CStruct._fields_ = fields
  183. if S._hints.get('union', False):
  184. base = ctypes.Union
  185. else:
  186. base = ctypes.Structure
  187. class CStruct(base):
  188. # no _fields_: filled later by builder()
  189. def _malloc(cls, n=None):
  190. if S._arrayfld is None:
  191. if n is not None:
  192. raise TypeError("%r is not variable-sized" % (S,))
  193. storage = allocate_ctypes(cls)
  194. return storage
  195. else:
  196. if n is None:
  197. raise TypeError("%r is variable-sized" % (S,))
  198. biggercls = build_ctypes_struct(S, None, n)
  199. bigstruct = allocate_ctypes(biggercls)
  200. array = getattr(bigstruct, S._arrayfld)
  201. if hasattr(array, 'length'):
  202. array.length = n
  203. return bigstruct
  204. _malloc = classmethod(_malloc)
  205. CStruct.__name__ = 'ctypes_%s' % (S,)
  206. if max_n is not None:
  207. CStruct._normalized_ctype = get_ctypes_type(S)
  208. builder() # no need to be lazy here
  209. else:
  210. delayed_builders.append((S, builder))
  211. return CStruct
  212. def build_ctypes_array(A, delayed_builders, max_n=0):
  213. assert max_n >= 0
  214. ITEM = A.OF
  215. ctypes_item = get_ctypes_type(ITEM, delayed_builders)
  216. ctypes_item_ptr = ctypes.POINTER(ctypes_item)
  217. class CArray(ctypes.Structure):
  218. if is_emulated_long:
  219. lentype = ctypes.c_longlong
  220. else:
  221. lentype = ctypes.c_long
  222. if not A._hints.get('nolength'):
  223. _fields_ = [('length', lentype),
  224. ('items',
  225. (max_n + A._hints.get('extra_item_after_alloc', 0))
  226. * ctypes_item)]
  227. else:
  228. _fields_ = [('items', max_n * ctypes_item)]
  229. @classmethod
  230. def _malloc(cls, n=None):
  231. if not isinstance(n, int):
  232. raise TypeError("array length must be an int")
  233. biggercls = get_ctypes_array_of_size(A, n)
  234. bigarray = allocate_ctypes(biggercls)
  235. if hasattr(bigarray, 'length'):
  236. bigarray.length = n
  237. return bigarray
  238. def _indexable(self, index):
  239. p = ctypes.cast(self.items, ctypes_item_ptr)
  240. return p
  241. def _getitem(self, index, boundscheck=True):
  242. if boundscheck:
  243. items = self.items
  244. else:
  245. items = self._indexable(index)
  246. cobj = items[index]
  247. if isinstance(ITEM, lltype.ContainerType):
  248. return ctypes2lltype(lltype.Ptr(ITEM), ctypes.pointer(cobj))
  249. else:
  250. return ctypes2lltype(ITEM, cobj)
  251. def _setitem(self, index, value, boundscheck=True):
  252. if boundscheck:
  253. items = self.items
  254. else:
  255. items = self._indexable(index)
  256. cobj = lltype2ctypes(value)
  257. items[index] = cobj
  258. CArray.__name__ = 'ctypes_%s*%d' % (A, max_n)
  259. if max_n > 0:
  260. CArray._normalized_ctype = get_ctypes_type(A)
  261. return CArray
  262. def get_ctypes_array_of_size(FIELDTYPE, max_n):
  263. if max_n > 0:
  264. # no need to cache the results in this case, because the exact
  265. # type is never seen - the array instances are cast to the
  266. # array's _normalized_ctype, which is always the same.
  267. return build_ctypes_array(FIELDTYPE, None, max_n)
  268. else:
  269. return get_ctypes_type(FIELDTYPE)
  270. def get_ctypes_type(T, delayed_builders=None, cannot_delay=False):
  271. # Check delayed builders
  272. if cannot_delay and delayed_builders:
  273. for T2, builder in delayed_builders:
  274. if T2 is T:
  275. builder()
  276. delayed_builders.remove((T2, builder))
  277. return _ctypes_cache[T]
  278. try:
  279. return _ctypes_cache[T]
  280. except KeyError:
  281. toplevel = cannot_delay or delayed_builders is None
  282. if toplevel:
  283. delayed_builders = []
  284. cls = build_new_ctypes_type(T, delayed_builders)
  285. if T not in _ctypes_cache:
  286. _ctypes_cache[T] = cls
  287. else:
  288. # check for buggy recursive structure logic
  289. assert _ctypes_cache[T] is cls
  290. if toplevel:
  291. complete_builders(delayed_builders)
  292. return cls
  293. def build_new_ctypes_type(T, delayed_builders):
  294. if isinstance(T, lltype.Typedef):
  295. T = T.OF
  296. if isinstance(T, lltype.Ptr):
  297. if isinstance(T.TO, lltype.FuncType):
  298. functype = ctypes.CFUNCTYPE
  299. if sys.platform == 'win32':
  300. from rpython.rlib.clibffi import FFI_STDCALL, FFI_DEFAULT_ABI
  301. if getattr(T.TO, 'ABI', FFI_DEFAULT_ABI) == FFI_STDCALL:
  302. # for win32 system call
  303. functype = ctypes.WINFUNCTYPE
  304. argtypes = [get_ctypes_type(ARG) for ARG in T.TO.ARGS
  305. if ARG is not lltype.Void]
  306. if T.TO.RESULT is lltype.Void:
  307. restype = None
  308. else:
  309. restype = get_ctypes_type(T.TO.RESULT)
  310. try:
  311. kwds = {'use_errno': True}
  312. return functype(restype, *argtypes, **kwds)
  313. except TypeError:
  314. # unexpected 'use_errno' argument, old ctypes version
  315. return functype(restype, *argtypes)
  316. elif isinstance(T.TO, lltype.OpaqueType):
  317. return ctypes.c_void_p
  318. else:
  319. return ctypes.POINTER(get_ctypes_type(T.TO, delayed_builders))
  320. elif T is lltype.Void:
  321. return ctypes.c_long # opaque pointer
  322. elif isinstance(T, lltype.Struct):
  323. return build_ctypes_struct(T, delayed_builders)
  324. elif isinstance(T, lltype.Array):
  325. return build_ctypes_array(T, delayed_builders)
  326. elif isinstance(T, lltype.OpaqueType):
  327. if T is lltype.RuntimeTypeInfo:
  328. return ctypes.c_char * 2
  329. if T.hints.get('external', None) != 'C':
  330. raise TypeError("%s is not external" % T)
  331. return ctypes.c_char * T.hints['getsize']()
  332. else:
  333. _setup_ctypes_cache()
  334. if T in _ctypes_cache:
  335. return _ctypes_cache[T]
  336. raise NotImplementedError(T)
  337. def complete_builders(delayed_builders):
  338. while delayed_builders:
  339. T, builder = delayed_builders[0]
  340. builder()
  341. delayed_builders.pop(0)
  342. def convert_struct(container, cstruct=None, delayed_converters=None):
  343. STRUCT = container._TYPE
  344. if cstruct is None:
  345. # if 'container' is an inlined substructure, convert the whole
  346. # bigger structure at once
  347. parent, parentindex = lltype.parentlink(container)
  348. if parent is not None:
  349. if isinstance(parent, lltype._struct):
  350. convert_struct(parent)
  351. elif isinstance(parent, lltype._array):
  352. convert_array(parent)
  353. else:
  354. raise AssertionError(type(parent))
  355. return
  356. # regular case: allocate a new ctypes Structure of the proper type
  357. cls = get_ctypes_type(STRUCT)
  358. if STRUCT._arrayfld is not None:
  359. n = getattr(container, STRUCT._arrayfld).getlength()
  360. else:
  361. n = None
  362. cstruct = cls._malloc(n)
  363. if isinstance(container, lltype._fixedsizearray):
  364. cls_mixin = _fixedsizedarray_mixin
  365. else:
  366. cls_mixin = _struct_mixin
  367. add_storage(container, cls_mixin, ctypes.pointer(cstruct))
  368. if delayed_converters is None:
  369. delayed_converters_was_None = True
  370. delayed_converters = []
  371. else:
  372. delayed_converters_was_None = False
  373. for field_name in STRUCT._names:
  374. FIELDTYPE = getattr(STRUCT, field_name)
  375. field_value = getattr(container, field_name)
  376. if not isinstance(FIELDTYPE, lltype.ContainerType):
  377. # regular field
  378. if FIELDTYPE != lltype.Void:
  379. def convert(field_name=field_name, field_value=field_value):
  380. setattr(cstruct, field_name, lltype2ctypes(field_value))
  381. if isinstance(FIELDTYPE, lltype.Ptr):
  382. delayed_converters.append(convert)
  383. else:
  384. convert()
  385. else:
  386. # inlined substructure/subarray
  387. if isinstance(FIELDTYPE, lltype.Struct):
  388. csubstruct = getattr(cstruct, field_name)
  389. convert_struct(field_value, csubstruct,
  390. delayed_converters=delayed_converters)
  391. elif field_name == STRUCT._arrayfld: # inlined var-sized part
  392. csubarray = getattr(cstruct, field_name)
  393. convert_array(field_value, csubarray)
  394. else:
  395. raise NotImplementedError('inlined field', FIELDTYPE)
  396. if delayed_converters_was_None:
  397. for converter in delayed_converters:
  398. converter()
  399. remove_regular_struct_content(container)
  400. def remove_regular_struct_content(container):
  401. STRUCT = container._TYPE
  402. if isinstance(STRUCT, lltype.FixedSizeArray):
  403. del container._items
  404. return
  405. for field_name in STRUCT._names:
  406. FIELDTYPE = getattr(STRUCT, field_name)
  407. if not isinstance(FIELDTYPE, lltype.ContainerType):
  408. delattr(container, field_name)
  409. def convert_array(container, carray=None):
  410. ARRAY = container._TYPE
  411. if carray is None:
  412. # if 'container' is an inlined substructure, convert the whole
  413. # bigger structure at once
  414. parent, parentindex = lltype.parentlink(container)
  415. if parent is not None:
  416. if not isinstance(parent, _parentable_mixin):
  417. convert_struct(parent)
  418. return
  419. # regular case: allocate a new ctypes array of the proper type
  420. cls = get_ctypes_type(ARRAY)
  421. carray = cls._malloc(container.getlength())
  422. add_storage(container, _array_mixin, ctypes.pointer(carray))
  423. if not isinstance(ARRAY.OF, lltype.ContainerType):
  424. # fish that we have enough space
  425. ctypes_array = ctypes.cast(carray.items,
  426. ctypes.POINTER(carray.items._type_))
  427. for i in range(container.getlength()):
  428. item_value = container.items[i] # fish fish
  429. ctypes_array[i] = lltype2ctypes(item_value)
  430. remove_regular_array_content(container)
  431. else:
  432. assert isinstance(ARRAY.OF, lltype.Struct)
  433. for i in range(container.getlength()):
  434. item_ptr = container.items[i] # fish fish
  435. convert_struct(item_ptr, carray.items[i])
  436. def remove_regular_array_content(container):
  437. for i in range(container.getlength()):
  438. container.items[i] = None
  439. def struct_use_ctypes_storage(container, ctypes_storage):
  440. STRUCT = container._TYPE
  441. assert isinstance(STRUCT, lltype.Struct)
  442. if isinstance(container, lltype._fixedsizearray):
  443. cls_mixin = _fixedsizedarray_mixin
  444. else:
  445. cls_mixin = _struct_mixin
  446. add_storage(container, cls_mixin, ctypes_storage)
  447. remove_regular_struct_content(container)
  448. for field_name in STRUCT._names:
  449. FIELDTYPE = getattr(STRUCT, field_name)
  450. if isinstance(FIELDTYPE, lltype.ContainerType):
  451. if isinstance(FIELDTYPE, lltype.Struct):
  452. struct_container = getattr(container, field_name)
  453. struct_storage = ctypes.pointer(
  454. getattr(ctypes_storage.contents, field_name))
  455. struct_use_ctypes_storage(struct_container, struct_storage)
  456. struct_container._setparentstructure(container, field_name)
  457. elif isinstance(FIELDTYPE, lltype.Array):
  458. if FIELDTYPE._hints.get('nolength', False):
  459. arraycontainer = _array_of_unknown_length(FIELDTYPE)
  460. else:
  461. arraycontainer = _array_of_known_length(FIELDTYPE)
  462. arraycontainer._storage = ctypes.pointer(
  463. getattr(ctypes_storage.contents, field_name))
  464. arraycontainer._setparentstructure(container, field_name)
  465. object.__setattr__(container, field_name, arraycontainer)
  466. else:
  467. raise NotImplementedError(FIELDTYPE)
  468. # ____________________________________________________________
  469. # Ctypes-aware subclasses of the _parentable classes
  470. ALLOCATED = {} # mapping {address: _container}
  471. DEBUG_ALLOCATED = False
  472. def get_common_subclass(cls1, cls2, cache={}):
  473. """Return a unique subclass with (cls1, cls2) as bases."""
  474. try:
  475. return cache[cls1, cls2]
  476. except KeyError:
  477. subcls = type('_ctypes_%s' % (cls1.__name__,),
  478. (cls1, cls2),
  479. {'__slots__': ()})
  480. cache[cls1, cls2] = subcls
  481. return subcls
  482. def add_storage(instance, mixin_cls, ctypes_storage):
  483. """Put ctypes_storage on the instance, changing its __class__ so that it
  484. sees the methods of the given mixin class."""
  485. # _storage is a ctypes pointer to a structure
  486. # except for Opaque objects which use a c_void_p.
  487. assert not isinstance(instance, _parentable_mixin) # not yet
  488. subcls = get_common_subclass(mixin_cls, instance.__class__)
  489. instance.__class__ = subcls
  490. instance._storage = ctypes_storage
  491. assert ctypes_storage # null pointer?
  492. class NotCtypesAllocatedStructure(ValueError):
  493. pass
  494. class _parentable_mixin(object):
  495. """Mixin added to _parentable containers when they become ctypes-based.
  496. (This is done by changing the __class__ of the instance to reference
  497. a subclass of both its original class and of this mixin class.)
  498. """
  499. __slots__ = ()
  500. def _ctypes_storage_was_allocated(self):
  501. addr = ctypes.cast(self._storage, ctypes.c_void_p).value
  502. if addr in ALLOCATED:
  503. raise Exception("internal ll2ctypes error - "
  504. "double conversion from lltype to ctypes?")
  505. # XXX don't store here immortal structures
  506. if DEBUG_ALLOCATED:
  507. print >> sys.stderr, "LL2CTYPES:", hex(addr)
  508. ALLOCATED[addr] = self
  509. def _addressof_storage(self):
  510. "Returns the storage address as an int"
  511. if self._storage is None or self._storage is True:
  512. raise NotCtypesAllocatedStructure("Not a ctypes allocated structure")
  513. return intmask(ctypes.cast(self._storage, ctypes.c_void_p).value)
  514. def _free(self):
  515. self._check() # no double-frees
  516. # allow the ctypes object to go away now
  517. addr = ctypes.cast(self._storage, ctypes.c_void_p).value
  518. if DEBUG_ALLOCATED:
  519. print >> sys.stderr, "LL2C FREE:", hex(addr)
  520. try:
  521. del ALLOCATED[addr]
  522. except KeyError:
  523. raise Exception("invalid free() - data already freed or "
  524. "not allocated from RPython at all")
  525. self._storage = None
  526. def _getid(self):
  527. return self._addressof_storage()
  528. def __eq__(self, other):
  529. if isinstance(other, _llgcopaque):
  530. addressof_other = other.intval
  531. else:
  532. if not isinstance(other, lltype._parentable):
  533. return False
  534. if self._storage is None or other._storage is None:
  535. raise RuntimeError("pointer comparison with a freed structure")
  536. if other._storage is True:
  537. return False # the other container is not ctypes-based
  538. addressof_other = other._addressof_storage()
  539. # both containers are ctypes-based, compare the addresses
  540. return self._addressof_storage() == addressof_other
  541. def __ne__(self, other):
  542. return not (self == other)
  543. def __hash__(self):
  544. if self._storage is not None:
  545. return self._addressof_storage()
  546. else:
  547. return object.__hash__(self)
  548. def __repr__(self):
  549. if '__str__' in self._TYPE._adtmeths:
  550. r = self._TYPE._adtmeths['__str__'](self)
  551. else:
  552. r = 'C object %s' % (self._TYPE,)
  553. if self._storage is None:
  554. return '<freed %s>' % (r,)
  555. else:
  556. return '<%s at 0x%x>' % (r, fixid(self._addressof_storage()))
  557. def __str__(self):
  558. return repr(self)
  559. def _setparentstructure(self, parent, parentindex):
  560. super(_parentable_mixin, self)._setparentstructure(parent, parentindex)
  561. self._keepparent = parent # always keep a strong ref
  562. class _struct_mixin(_parentable_mixin):
  563. """Mixin added to _struct containers when they become ctypes-based."""
  564. __slots__ = ()
  565. def __getattr__(self, field_name):
  566. T = getattr(self._TYPE, field_name)
  567. cobj = getattr(self._storage.contents, field_name)
  568. return ctypes2lltype(T, cobj)
  569. def __setattr__(self, field_name, value):
  570. if field_name.startswith('_'):
  571. object.__setattr__(self, field_name, value) # '_xxx' attributes
  572. else:
  573. cobj = lltype2ctypes(value)
  574. setattr(self._storage.contents, field_name, cobj)
  575. class _fixedsizedarray_mixin(_parentable_mixin):
  576. """Mixin added to _fixedsizearray containers when they become ctypes-based."""
  577. __slots__ = ()
  578. def __getattr__(self, field_name):
  579. if hasattr(self, '_items'):
  580. obj = lltype._fixedsizearray.__getattr__.im_func(self, field_name)
  581. return obj
  582. else:
  583. cobj = getattr(self._storage.contents, field_name)
  584. T = getattr(self._TYPE, field_name)
  585. return ctypes2lltype(T, cobj)
  586. def __setattr__(self, field_name, value):
  587. if field_name.startswith('_'):
  588. object.__setattr__(self, field_name, value) # '_xxx' attributes
  589. else:
  590. cobj = lltype2ctypes(value)
  591. if hasattr(self, '_items'):
  592. lltype._fixedsizearray.__setattr__.im_func(self, field_name, cobj)
  593. else:
  594. setattr(self._storage.contents, field_name, cobj)
  595. def getitem(self, index, uninitialized_ok=False):
  596. if hasattr(self, '_items'):
  597. obj = lltype._fixedsizearray.getitem.im_func(self,
  598. index, uninitialized_ok=uninitialized_ok)
  599. return obj
  600. else:
  601. return getattr(self, 'item%d' % index)
  602. def setitem(self, index, value):
  603. cobj = lltype2ctypes(value)
  604. if hasattr(self, '_items'):
  605. lltype._fixedsizearray.setitem.im_func(self, index, value)
  606. else:
  607. setattr(self, 'item%d' % index, cobj)
  608. class _array_mixin(_parentable_mixin):
  609. """Mixin added to _array containers when they become ctypes-based."""
  610. __slots__ = ()
  611. def getitem(self, index, uninitialized_ok=False):
  612. return self._storage.contents._getitem(index)
  613. def setitem(self, index, value):
  614. self._storage.contents._setitem(index, value)
  615. class _array_of_unknown_length(_parentable_mixin, lltype._parentable):
  616. _kind = "array"
  617. __slots__ = ()
  618. def getbounds(self):
  619. # we have no clue, so we allow whatever index
  620. return 0, maxint
  621. def shrinklength(self, newlength):
  622. raise NotImplementedError
  623. def getitem(self, index, uninitialized_ok=False):
  624. res = self._storage.contents._getitem(index, boundscheck=False)
  625. if isinstance(self._TYPE.OF, lltype.ContainerType):
  626. res._obj._setparentstructure(self, index)
  627. return res
  628. def setitem(self, index, value):
  629. self._storage.contents._setitem(index, value, boundscheck=False)
  630. def getitems(self):
  631. if self._TYPE.OF != lltype.Char:
  632. raise Exception("cannot get all items of an unknown-length "
  633. "array of %r" % self._TYPE.OF)
  634. _items = []
  635. i = 0
  636. while 1:
  637. nextitem = self.getitem(i)
  638. if nextitem == '\x00':
  639. _items.append('\x00')
  640. return _items
  641. _items.append(nextitem)
  642. i += 1
  643. items = property(getitems)
  644. class _array_of_known_length(_array_of_unknown_length):
  645. __slots__ = ()
  646. def getlength(self):
  647. return self._storage.contents.length
  648. def getbounds(self):
  649. return 0, self.getlength()
  650. # ____________________________________________________________
  651. def _find_parent(llobj):
  652. parent, parentindex = lltype.parentlink(llobj)
  653. if parent is None:
  654. return llobj, 0
  655. next_p, next_i = _find_parent(parent)
  656. if isinstance(parentindex, int):
  657. c_tp = get_ctypes_type(lltype.typeOf(parent))
  658. sizeof = ctypes.sizeof(get_ctypes_type(lltype.typeOf(parent).OF))
  659. ofs = c_tp.items.offset + parentindex * sizeof
  660. return next_p, next_i + ofs
  661. else:
  662. c_tp = get_ctypes_type(lltype.typeOf(parent))
  663. ofs = getattr(c_tp, parentindex).offset
  664. return next_p, next_i + ofs
  665. # ____________________________________________________________
  666. # XXX THIS IS A HACK XXX
  667. # ctypes does not keep callback arguments alive. So we do. Forever
  668. # we need to think deeper how to approach this problem
  669. # additionally, this adds mess to __del__ "semantics"
  670. _all_callbacks = {}
  671. _all_callbacks_results = []
  672. _int2obj = {}
  673. _callback_exc_info = None
  674. _opaque_objs = [None]
  675. _opaque_objs_seen = {}
  676. def get_rtyper():
  677. llinterp = LLInterpreter.current_interpreter
  678. if llinterp is not None:
  679. return llinterp.typer
  680. else:
  681. return None
  682. def lltype2ctypes(llobj, normalize=True):
  683. """Convert the lltype object 'llobj' to its ctypes equivalent.
  684. 'normalize' should only be False in tests, where we want to
  685. inspect the resulting ctypes object manually.
  686. """
  687. with rlock:
  688. if isinstance(llobj, lltype._uninitialized):
  689. return uninitialized2ctypes(llobj.TYPE)
  690. if isinstance(llobj, llmemory.AddressAsInt):
  691. cobj = ctypes.cast(lltype2ctypes(llobj.adr), ctypes.c_void_p)
  692. res = intmask(cobj.value)
  693. _int2obj[res] = llobj.adr.ptr._obj
  694. return res
  695. if isinstance(llobj, llmemory.fakeaddress):
  696. llobj = llobj.ptr or 0
  697. T = lltype.typeOf(llobj)
  698. if isinstance(T, lltype.Ptr):
  699. if not llobj: # NULL pointer
  700. if T == llmemory.GCREF:
  701. return ctypes.c_void_p(0)
  702. return get_ctypes_type(T)()
  703. if T == llmemory.GCREF:
  704. if isinstance(llobj._obj, _llgcopaque):
  705. return ctypes.c_void_p(llobj._obj.intval)
  706. if isinstance(llobj._obj, int): # tagged pointer
  707. return ctypes.c_void_p(llobj._obj)
  708. container = llobj._obj.container
  709. T = lltype.Ptr(lltype.typeOf(container))
  710. # otherwise it came from integer and we want a c_void_p with
  711. # the same value
  712. if getattr(container, 'llopaque', None):
  713. try:
  714. no = _opaque_objs_seen[container]
  715. except KeyError:
  716. no = len(_opaque_objs)
  717. _opaque_objs.append(container)
  718. _opaque_objs_seen[container] = no
  719. return no * 2 + 1
  720. else:
  721. container = llobj._obj
  722. if isinstance(T.TO, lltype.FuncType):
  723. # XXX a temporary workaround for comparison of lltype.FuncType
  724. key = llobj._obj.__dict__.copy()
  725. key['_TYPE'] = repr(key['_TYPE'])
  726. items = key.items()
  727. items.sort()
  728. key = tuple(items)
  729. if key in _all_callbacks:
  730. return _all_callbacks[key]
  731. v1voidlist = [(i, getattr(container, '_void' + str(i), None))
  732. for i in range(len(T.TO.ARGS))
  733. if T.TO.ARGS[i] is lltype.Void]
  734. def callback_internal(*cargs):
  735. cargs = list(cargs)
  736. for v1 in v1voidlist:
  737. cargs.insert(v1[0], v1[1])
  738. assert len(cargs) == len(T.TO.ARGS)
  739. llargs = []
  740. for ARG, carg in zip(T.TO.ARGS, cargs):
  741. if ARG is lltype.Void:
  742. llargs.append(carg)
  743. else:
  744. llargs.append(ctypes2lltype(ARG, carg))
  745. if hasattr(container, 'graph'):
  746. if LLInterpreter.current_interpreter is None:
  747. raise AssertionError
  748. llinterp = LLInterpreter.current_interpreter
  749. try:
  750. llres = llinterp.eval_graph(container.graph, llargs)
  751. except LLException as lle:
  752. llinterp._store_exception(lle)
  753. return 0
  754. #except:
  755. # import pdb
  756. # pdb.set_trace()
  757. else:
  758. try:
  759. llres = container._callable(*llargs)
  760. except LLException as lle:
  761. llinterp = LLInterpreter.current_interpreter
  762. llinterp._store_exception(lle)
  763. return 0
  764. assert lltype.typeOf(llres) == T.TO.RESULT
  765. if T.TO.RESULT is lltype.Void:
  766. return None
  767. res = lltype2ctypes(llres)
  768. if isinstance(T.TO.RESULT, lltype.Ptr):
  769. _all_callbacks_results.append(res)
  770. res = ctypes.cast(res, ctypes.c_void_p).value
  771. if res is None:
  772. return 0
  773. if T.TO.RESULT == lltype.SingleFloat:
  774. res = res.value # baaaah, cannot return a c_float()
  775. return res
  776. def callback(*cargs):
  777. try:
  778. return callback_internal(*cargs)
  779. except:
  780. import sys
  781. #if option.usepdb:
  782. # import pdb; pdb.post_mortem(sys.exc_traceback)
  783. global _callback_exc_info
  784. _callback_exc_info = sys.exc_info()
  785. raise
  786. if isinstance(T.TO.RESULT, lltype.Ptr):
  787. TMod = lltype.Ptr(lltype.FuncType(T.TO.ARGS,
  788. lltype.Signed))
  789. ctypes_func_type = get_ctypes_type(TMod)
  790. res = ctypes_func_type(callback)
  791. ctypes_func_type = get_ctypes_type(T)
  792. res = ctypes.cast(res, ctypes_func_type)
  793. else:
  794. ctypes_func_type = get_ctypes_type(T)
  795. res = ctypes_func_type(callback)
  796. _all_callbacks[key] = res
  797. key2 = intmask(ctypes.cast(res, ctypes.c_void_p).value)
  798. _int2obj[key2] = container
  799. return res
  800. index = 0
  801. if isinstance(container, lltype._subarray):
  802. topmost, index = _find_parent(container)
  803. container = topmost
  804. T = lltype.Ptr(lltype.typeOf(container))
  805. if container._storage is None:
  806. raise RuntimeError("attempting to pass a freed structure to C")
  807. if container._storage is True:
  808. # container has regular lltype storage, convert it to ctypes
  809. if isinstance(T.TO, lltype.Struct):
  810. convert_struct(container)
  811. elif isinstance(T.TO, lltype.Array):
  812. convert_array(container)
  813. elif isinstance(T.TO, lltype.OpaqueType):
  814. if T.TO != lltype.RuntimeTypeInfo:
  815. cbuf = ctypes.create_string_buffer(T.TO.hints['getsize']())
  816. else:
  817. cbuf = ctypes.create_string_buffer("\x00")
  818. cbuf = ctypes.cast(cbuf, ctypes.c_void_p)
  819. add_storage(container, _parentable_mixin, cbuf)
  820. else:
  821. raise NotImplementedError(T)
  822. container._ctypes_storage_was_allocated()
  823. if isinstance(T.TO, lltype.OpaqueType):
  824. return container._storage.value
  825. storage = container._storage
  826. p = storage
  827. if index:
  828. p = ctypes.cast(p, ctypes.c_void_p)
  829. p = ctypes.c_void_p(p.value + index)
  830. c_tp = get_ctypes_type(T.TO)
  831. storage.contents._normalized_ctype = c_tp
  832. if normalize and hasattr(storage.contents, '_normalized_ctype'):
  833. normalized_ctype = storage.contents._normalized_ctype
  834. p = ctypes.cast(p, ctypes.POINTER(normalized_ctype))
  835. if lltype.typeOf(llobj) == llmemory.GCREF:
  836. p = ctypes.cast(p, ctypes.c_void_p)
  837. return p
  838. if isinstance(llobj, Symbolic):
  839. if isinstance(llobj, llmemory.ItemOffset):
  840. llobj = ctypes.sizeof(get_ctypes_type(llobj.TYPE)) * llobj.repeat
  841. elif isinstance(llobj, ComputedIntSymbolic):
  842. llobj = llobj.compute_fn()
  843. elif isinstance(llobj, llmemory.CompositeOffset):
  844. llobj = sum([lltype2ctypes(c) for c in llobj.offsets])
  845. elif isinstance(llobj, llmemory.FieldOffset):
  846. CSTRUCT = get_ctypes_type(llobj.TYPE)
  847. llobj = getattr(CSTRUCT, llobj.fldname).offset
  848. elif isinstance(llobj, llmemory.ArrayItemsOffset):
  849. CARRAY = get_ctypes_type(llobj.TYPE)
  850. llobj = CARRAY.items.offset
  851. else:
  852. raise NotImplementedError(llobj) # don't know about symbolic value
  853. if T is lltype.Char or T is lltype.UniChar:
  854. return ord(llobj)
  855. if T is lltype.SingleFloat:
  856. return ctypes.c_float(float(llobj))
  857. return llobj
  858. def ctypes2lltype(T, cobj):
  859. """Convert the ctypes object 'cobj' to its lltype equivalent.
  860. 'T' is the expected lltype type.
  861. """
  862. with rlock:
  863. if T is lltype.Void:
  864. return None
  865. if isinstance(T, lltype.Typedef):
  866. T = T.OF
  867. if isinstance(T, lltype.Ptr):
  868. ptrval = ctypes.cast(cobj, ctypes.c_void_p).value
  869. if not cobj or not ptrval: # NULL pointer
  870. # CFunctionType.__nonzero__ is broken before Python 2.6
  871. return lltype.nullptr(T.TO)
  872. if isinstance(T.TO, lltype.Struct):
  873. if T.TO._gckind == 'gc' and ptrval & 1: # a tagged pointer
  874. gcref = _opaque_objs[ptrval // 2].hide()
  875. return lltype.cast_opaque_ptr(T, gcref)
  876. REAL_TYPE = T.TO
  877. if T.TO._arrayfld is not None:
  878. carray = getattr(cobj.contents, T.TO._arrayfld)
  879. length = getattr(carray, 'length', 9999) # XXX
  880. container = lltype._struct(T.TO, length)
  881. else:
  882. # special treatment of 'OBJECT' subclasses
  883. if get_rtyper() and lltype._castdepth(REAL_TYPE, OBJECT) >= 0:
  884. # figure out the real type of the object
  885. containerheader = lltype._struct(OBJECT)
  886. cobjheader = ctypes.cast(cobj,
  887. get_ctypes_type(lltype.Ptr(OBJECT)))
  888. struct_use_ctypes_storage(containerheader,
  889. cobjheader)
  890. REAL_TYPE = get_rtyper().get_type_for_typeptr(
  891. containerheader.typeptr)
  892. REAL_T = lltype.Ptr(REAL_TYPE)
  893. cobj = ctypes.cast(cobj, get_ctypes_type(REAL_T))
  894. container = lltype._struct(REAL_TYPE)
  895. # obscuuuuuuuuure: 'cobj' is a ctypes pointer, which is
  896. # mutable; and so if we save away the 'cobj' object
  897. # itself, it might suddenly later be unexpectedly
  898. # modified! Make a copy.
  899. cobj = ctypes.cast(cobj, type(cobj))
  900. struct_use_ctypes_storage(container, cobj)
  901. if REAL_TYPE != T.TO:
  902. p = container._as_ptr()
  903. container = lltype.cast_pointer(T, p)._as_obj()
  904. # special treatment of 'OBJECT_VTABLE' subclasses
  905. if get_rtyper() and lltype._castdepth(REAL_TYPE,
  906. OBJECT_VTABLE) >= 0:
  907. # figure out the real object that this vtable points to,
  908. # and just return that
  909. p = get_rtyper().get_real_typeptr_for_typeptr(
  910. container._as_ptr())
  911. container = lltype.cast_pointer(T, p)._as_obj()
  912. elif isinstance(T.TO, lltype.Array):
  913. if T.TO._hints.get('nolength', False):
  914. container = _array_of_unknown_length(T.TO)
  915. container._storage = type(cobj)(cobj.contents)
  916. else:
  917. container = _array_of_known_length(T.TO)
  918. container._storage = type(cobj)(cobj.contents)
  919. elif isinstance(T.TO, lltype.FuncType):
  920. # cobj is a CFunctionType object. We naively think
  921. # that it should be a function pointer. No no no. If
  922. # it was read out of an array, say, then it is a *pointer*
  923. # to a function pointer. In other words, the read doesn't
  924. # read anything, it just takes the address of the function
  925. # pointer inside the array. If later the array is modified
  926. # or goes out of scope, then we crash. CTypes is fun.
  927. # It works if we cast it now to an int and back.
  928. cobjkey = intmask(ctypes.cast(cobj, ctypes.c_void_p).value)
  929. if cobjkey in _int2obj:
  930. container = _int2obj[cobjkey]
  931. else:
  932. name = getattr(cobj, '__name__', '?')
  933. cobj = ctypes.cast(cobjkey, type(cobj))
  934. _callable = get_ctypes_trampoline(T.TO, cobj)
  935. return lltype.functionptr(T.TO, name,
  936. _callable=_callable)
  937. elif isinstance(T.TO, lltype.OpaqueType):
  938. if T == llmemory.GCREF:
  939. container = _llgcopaque(cobj)
  940. else:
  941. container = lltype._opaque(T.TO)
  942. cbuf = ctypes.cast(cobj, ctypes.c_void_p)
  943. add_storage(container, _parentable_mixin, cbuf)
  944. else:
  945. raise NotImplementedError(T)
  946. llobj = lltype._ptr(T, container, solid=True)
  947. elif T is llmemory.Address:
  948. if cobj is None:
  949. llobj = llmemory.NULL
  950. else:
  951. llobj = _lladdress(cobj)
  952. elif T is lltype.Char:
  953. llobj = chr(cobj)
  954. elif T is lltype.UniChar:
  955. try:
  956. llobj = unichr(cobj)
  957. except (ValueError, OverflowError):
  958. for tc in 'HIL':
  959. if array(tc).itemsize == array('u').itemsize:
  960. import struct
  961. cobj &= 256 ** struct.calcsize(tc) - 1
  962. llobj = array('u', array(tc, (cobj,)).tostring())[0]
  963. break
  964. else:
  965. raise
  966. elif T is lltype.Signed:
  967. llobj = cobj
  968. elif T is lltype.Bool:
  969. assert cobj == True or cobj == False # 0 and 1 work too
  970. llobj = bool(cobj)
  971. elif T is lltype.SingleFloat:
  972. if isinstance(cobj, ctypes.c_float):
  973. cobj = cobj.value
  974. llobj = r_singlefloat(cobj)
  975. elif T is lltype.LongFloat:
  976. if isinstance(cobj, ctypes.c_longdouble):
  977. cobj = cobj.value
  978. llobj = r_longfloat(cobj)
  979. elif T is lltype.Void:
  980. llobj = cobj
  981. else:
  982. from rpython.rtyper.lltypesystem import rffi
  983. try:
  984. inttype = rffi.platform.numbertype_to_rclass[T]
  985. except KeyError:
  986. llobj = cobj
  987. else:
  988. llobj = inttype(cobj)
  989. assert lltype.typeOf(llobj) == T
  990. return llobj
  991. def uninitialized2ctypes(T):
  992. "For debugging, create a ctypes object filled with 0xDD."
  993. ctype = get_ctypes_type(T)
  994. cobj = ctype()
  995. size = ctypes.sizeof(cobj)
  996. p = ctypes.cast(ctypes.pointer(cobj),
  997. ctypes.POINTER(ctypes.c_ubyte * size))
  998. for i in range(size):
  999. p.contents[i] = 0xDD
  1000. if isinstance(T, lltype.Primitive):
  1001. return cobj.value
  1002. else:
  1003. return cobj
  1004. # __________ the standard C library __________
  1005. if ctypes:
  1006. def get_libc_name():
  1007. if sys.platform == 'win32':
  1008. # Parses sys.version and deduces the version of the compiler
  1009. import distutils.msvccompiler
  1010. version = distutils.msvccompiler.get_build_version()
  1011. if version is None:
  1012. # This logic works with official builds of Python.
  1013. if sys.version_info < (2, 4):
  1014. clibname = 'msvcrt'
  1015. else:
  1016. clibname = 'msvcr71'
  1017. else:
  1018. if version <= 6:
  1019. clibname = 'msvcrt'
  1020. else:
  1021. clibname = 'msvcr%d' % (version * 10)
  1022. # If python was built with in debug mode
  1023. import imp
  1024. if imp.get_suffixes()[0][0] == '_d.pyd':
  1025. clibname += 'd'
  1026. return clibname+'.dll'
  1027. else:
  1028. return ctypes.util.find_library('c')
  1029. libc_name = get_libc_name() # Make sure the name is determined during import, not at runtime
  1030. if _FREEBSD:
  1031. RTLD_DEFAULT = -2 # see <dlfcn.h>
  1032. rtld_default_lib = ctypes.CDLL("RTLD_DEFAULT", handle=RTLD_DEFAULT, **load_library_kwargs)
  1033. # XXX is this always correct???
  1034. standard_c_lib = ctypes.CDLL(libc_name, **load_library_kwargs)
  1035. # ____________________________________________
  1036. # xxx from ctypes.util, this code is a useful fallback on darwin too
  1037. if sys.platform == 'darwin':
  1038. # Andreas Degert's find function using gcc
  1039. import re, tempfile, errno
  1040. def _findLib_gcc_fallback(name):
  1041. expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name)
  1042. fdout, ccout = tempfile.mkstemp()
  1043. os.close(fdout)
  1044. cmd = 'if type gcc >/dev/null 2>&1; then CC=gcc; else CC=cc; fi;' \
  1045. '$CC -Wl,-t -o ' + ccout + ' 2>&1 -l' + name
  1046. try:
  1047. f = os.popen(cmd)
  1048. trace = f.read()
  1049. f.close()
  1050. finally:
  1051. try:
  1052. os.unlink(ccout)
  1053. except OSError as e:
  1054. if e.errno != errno.ENOENT:
  1055. raise
  1056. res = re.search(expr, trace)
  1057. if not res:
  1058. return None
  1059. return res.group(0)
  1060. else:
  1061. _findLib_gcc_fallback = lambda name: None
  1062. def get_ctypes_callable(funcptr, calling_conv):
  1063. if not ctypes:
  1064. raise ImportError("ctypes is needed to use ll2ctypes")
  1065. def get_on_lib(lib, elem):
  1066. """ Wrapper to always use lib[func] instead of lib.func
  1067. """
  1068. try:
  1069. return lib[elem]
  1070. except AttributeError:
  1071. pass
  1072. old_eci = funcptr._obj.compilation_info
  1073. funcname = funcptr._obj._name
  1074. if hasattr(old_eci, '_with_ctypes'):
  1075. old_eci = old_eci._with_ctypes
  1076. try:
  1077. eci = _eci_cache[old_eci]
  1078. except KeyError:
  1079. eci = old_eci.compile_shared_lib(ignore_a_files=True,
  1080. defines=['RPYTHON_LL2CTYPES'])
  1081. _eci_cache[old_eci] = eci
  1082. libraries = eci.testonly_libraries + eci.libraries + eci.frameworks
  1083. FUNCTYPE = lltype.typeOf(funcptr).TO
  1084. cfunc = None
  1085. if libraries:
  1086. not_found = []
  1087. for libname in libraries:
  1088. libpath = None
  1089. ext = platform.so_ext
  1090. prefixes = platform.so_prefixes
  1091. for dir in eci.library_dirs:
  1092. if libpath:
  1093. break
  1094. for prefix in prefixes:
  1095. tryfile = os.path.join(dir, prefix + libname + '.' + ext)
  1096. if os.path.isfile(tryfile):
  1097. libpath = tryfile
  1098. break
  1099. if not libpath:
  1100. libpath = ctypes.util.find_library(libname)
  1101. if not libpath:
  1102. libpath = _findLib_gcc_fallback(libname)
  1103. if not libpath and os.path.isabs(libname):
  1104. libpath = libname
  1105. if libpath:
  1106. dllclass = getattr(ctypes, calling_conv + 'dll')
  1107. # on ie slackware there was need for RTLD_GLOBAL here.
  1108. # this breaks a lot of things, since passing RTLD_GLOBAL
  1109. # creates symbol conflicts on C level.
  1110. clib = dllclass._dlltype(libpath, **load_library_kwargs)
  1111. cfunc = get_on_lib(clib, funcname)
  1112. if cfunc is not None:
  1113. break
  1114. else:
  1115. not_found.append(libname)
  1116. if cfunc is None:
  1117. if _FREEBSD and funcname in ('dlopen', 'fdlopen', 'dlsym', 'dlfunc', 'dlerror', 'dlclose'):
  1118. cfunc = get_on_lib(rtld_default_lib, funcname)
  1119. else:
  1120. cfunc = get_on_lib(standard_c_lib, funcname)
  1121. # XXX magic: on Windows try to load the function from 'kernel32' too
  1122. if cfunc is None and hasattr(ctypes, 'windll'):
  1123. cfunc = get_on_lib(ctypes.windll.kernel32, funcname)
  1124. if cfunc is None and hasattr(ctypes, 'windll'):
  1125. cfunc = get_on_lib(ctypes.cdll.msvcrt, funcname)
  1126. if cfunc is None:
  1127. # function name not found in any of the libraries
  1128. if not libraries:
  1129. place = 'the standard C library (missing libraries=...?)'
  1130. elif len(not_found) == len(libraries):
  1131. if len(not_found) == 1:
  1132. raise NotImplementedError(
  1133. 'cannot find the library %r' % (not_found[0],))
  1134. else:
  1135. raise NotImplementedError(
  1136. 'cannot find any of the libraries %r' % (not_found,))
  1137. elif len(libraries) == 1:
  1138. place = 'library %r' % (libraries[0],)
  1139. else:
  1140. place = 'any of the libraries %r' % (libraries,)
  1141. if not_found:
  1142. place += ' (did not find %r)' % (not_found,)
  1143. raise NotImplementedError("function %r not found in %s" % (
  1144. funcname, place))
  1145. # get_ctypes_type() can raise NotImplementedError too
  1146. from rpython.rtyper.lltypesystem import rffi
  1147. cfunc.argtypes = [get_ctypes_type(T) if T is not rffi.VOIDP
  1148. else ctypes.c_void_p
  1149. for T in FUNCTYPE.ARGS
  1150. if not T is lltype.Void]
  1151. if FUNCTYPE.RESULT is lltype.Void:
  1152. cfunc.restype = None
  1153. else:
  1154. cfunc.restype = get_ctypes_type(FUNCTYPE.RESULT)
  1155. return cfunc
  1156. class LL2CtypesCallable(object):
  1157. # a special '_callable' object that invokes ctypes
  1158. def __init__(self, FUNCTYPE, calling_conv):
  1159. self.FUNCTYPE = FUNCTYPE
  1160. self.calling_conv = calling_conv
  1161. self.trampoline = None
  1162. #self.funcptr = ... set later
  1163. def __call__(self, *argvalues):
  1164. with rlock:
  1165. if self.trampoline is None:
  1166. # lazily build the corresponding ctypes function object
  1167. cfunc = get_ctypes_callable(self.funcptr, self.calling_conv)
  1168. self.trampoline = get_ctypes_trampoline(self.FUNCTYPE, cfunc)
  1169. # perform the call
  1170. return self.trampoline(*argvalues)
  1171. def get_ctypes_trampoline(FUNCTYPE, cfunc):
  1172. RESULT = FUNCTYPE.RESULT
  1173. container_arguments = []
  1174. for i in range(len(FUNCTYPE.ARGS)):
  1175. if isinstance(FUNCTYPE.ARGS[i], lltype.ContainerType):
  1176. container_arguments.append(i)
  1177. void_arguments = []
  1178. for i in range(len(FUNCTYPE.ARGS)):
  1179. if FUNCTYPE.ARGS[i] is lltype.Void:
  1180. void_arguments.append(i)
  1181. def callme(cargs): # an extra indirection: workaround for rlib.rstacklet
  1182. return cfunc(*cargs)
  1183. def invoke_via_ctypes(*argvalues):
  1184. global _callback_exc_info
  1185. cargs = []
  1186. for i in range(len(argvalues)):
  1187. if i not in void_arguments:
  1188. cvalue = lltype2ctypes(argvalues[i])
  1189. if i in container_arguments:
  1190. cvalue = cvalue.contents
  1191. cargs.append(cvalue)
  1192. _callback_exc_info = None
  1193. _restore_c_errno()
  1194. cres = callme(cargs)
  1195. _save_c_errno()
  1196. if _callback_exc_info:
  1197. etype, evalue, etb = _callback_exc_info
  1198. _callback_exc_info = None
  1199. raise etype, evalue, etb
  1200. return ctypes2lltype(RESULT, cres)
  1201. return invoke_via_ctypes
  1202. def force_cast(RESTYPE, value):
  1203. with rlock:
  1204. if not isinstance(RESTYPE, lltype.LowLevelType):
  1205. raise TypeError("rffi.cast() first arg should be a TYPE")
  1206. if isinstance(value, llmemory.AddressAsInt):
  1207. value = value.adr
  1208. if isinstance(value, llmemory.fakeaddress):
  1209. value = value.ptr or 0
  1210. if isinstance(value, r_singlefloat):
  1211. value = float(value)
  1212. TYPE1 = lltype.typeOf(value)
  1213. cvalue = lltype2ctypes(value)
  1214. cresulttype = get_ctypes_type(RESTYPE)
  1215. if RESTYPE == TYPE1:
  1216. return value
  1217. elif isinstance(TYPE1, lltype.Ptr):
  1218. if isinstance(RESTYPE, lltype.Ptr):
  1219. # shortcut: ptr->ptr cast
  1220. cptr = ctypes.cast(cvalue, cresulttype)
  1221. return ctypes2lltype(RESTYPE, cptr)
  1222. # first cast the input pointer to an integer
  1223. cvalue = ctypes.cast(cvalue, ctypes.c_void_p).value
  1224. if cvalue is None:
  1225. cvalue = 0
  1226. elif isinstance(cvalue, (str, unicode)):
  1227. cvalue = ord(cvalue) # character -> integer
  1228. elif hasattr(RESTYPE, "_type") and issubclass(RESTYPE._type, base_int):
  1229. cvalue = int(cvalue)
  1230. elif isinstance(cvalue, r_longfloat):
  1231. cvalue = cvalue.value
  1232. if not isinstance(cvalue, (int, long, float)):
  1233. raise NotImplementedError("casting %r to %r" % (TYPE1, RESTYPE))
  1234. if isinstance(RESTYPE, lltype.Ptr):
  1235. # upgrade to a more recent ctypes (e.g. 1.0.2) if you get
  1236. # an OverflowError on the following line.
  1237. cvalue = ctypes.cast(ctypes.c_void_p(cvalue), cresulttype)
  1238. elif RESTYPE == lltype.Bool:
  1239. cvalue = bool(cvalue)
  1240. else:
  1241. try:
  1242. cvalue = cresulttype(cvalue).value # mask high bits off if needed
  1243. except TypeError:
  1244. cvalue = int(cvalue) # float -> int
  1245. cvalue = cresulttype(cvalue).value # try again
  1246. return ctypes2lltype(RESTYPE, cvalue)
  1247. class ForceCastEntry(ExtRegistryEntry):
  1248. _about_ = force_cast
  1249. def compute_result_annotation(self, s_RESTYPE, s_value):
  1250. assert s_RESTYPE.is_constant()
  1251. RESTYPE = s_RESTYPE.const
  1252. return lltype_to_annotation(RESTYPE)
  1253. def specialize_call(self, hop):
  1254. hop.exception_cannot_occur()
  1255. s_RESTYPE = hop.args_s[0]
  1256. assert s_RESTYPE.is_constant()
  1257. RESTYPE = s_RESTYPE.const
  1258. v_arg = hop.inputarg(hop.args_r[1], arg=1)
  1259. return hop.genop('force_cast', [v_arg], resulttype = RESTYPE)
  1260. def typecheck_ptradd(T):
  1261. # --- ptradd() is only for pointers to non-GC, no-length arrays.
  1262. assert isinstance(T, lltype.Ptr)
  1263. assert isinstance(T.TO, lltype.Array)
  1264. assert T.TO._hints.get('nolength')
  1265. def force_ptradd(ptr, n):
  1266. """'ptr' must be a pointer to an array. Equivalent of 'ptr + n' in
  1267. C, i.e. gives a pointer to the n'th item of the array. The type of
  1268. the result is again a pointer to an array, the same as the type of
  1269. 'ptr'.
  1270. """
  1271. T = lltype.typeOf(ptr)
  1272. typecheck_ptradd(T)
  1273. ctypes_item_type = get_ctypes_type(T.TO.OF)
  1274. ctypes_arrayptr_type = get_ctypes_type(T)
  1275. cptr = lltype2ctypes(ptr)
  1276. baseaddr = ctypes.addressof(cptr.contents.items)
  1277. addr = baseaddr + n * ctypes.sizeof(ctypes_item_type)
  1278. cptr = ctypes.cast(ctypes.c_void_p(addr), ctypes_arrayptr_type)
  1279. return ctypes2lltype(T, cptr)
  1280. class ForcePtrAddEntry(ExtRegistryEntry):
  1281. _about_ = force_ptradd
  1282. def compute_result_annotation(self, s_ptr, s_n):
  1283. assert isinstance(s_n, annmodel.SomeInteger)
  1284. assert isinstance(s_ptr, SomePtr)
  1285. typecheck_ptradd(s_ptr.ll_ptrtype)
  1286. return lltype_to_annotation(s_ptr.ll_ptrtype)
  1287. def specialize_call(self, hop):
  1288. hop.exception_cannot_occur()
  1289. v_ptr, v_n = hop.inputargs(hop.args_r[0], lltype.Signed)
  1290. return hop.genop('direct_ptradd', [v_ptr, v_n],
  1291. resulttype = v_ptr.concretetype)
  1292. class _lladdress(long):
  1293. _TYPE = llmemory.Address
  1294. def __new__(cls, void_p):
  1295. if isinstance(void_p, (int, long)):
  1296. void_p = ctypes.c_void_p(void_p)
  1297. self = long.__new__(cls, void_p.value)
  1298. self.void_p = void_p
  1299. self.intval = intmask(void_p.value)
  1300. return self
  1301. def _cast_to_ptr(self, TP):
  1302. return force_cast(TP, self.intval)
  1303. def __repr__(self):
  1304. return '<_lladdress %s>' % (self.void_p,)
  1305. def __eq__(self, other):
  1306. if not isinstance(other, (int, long)):
  1307. other = cast_adr_to_int(other)
  1308. return intmask(other) == self.intval
  1309. def __ne__(self, other):
  1310. return not self == other
  1311. class _llgcopaque(lltype._container):
  1312. _TYPE = llmemory.GCREF.TO
  1313. _name = "_llgcopaque"
  1314. _read_directly_intval = True # for _ptr._cast_to_int()
  1315. def __init__(self, void_p):
  1316. if isinstance(void_p, (int, long)):
  1317. self.intval = intmask(void_p)
  1318. else:
  1319. self.intval = intmask(void_p.value)
  1320. def __eq__(self, other):
  1321. if not other:
  1322. return self.intval == 0
  1323. if isinstance(other, _llgcopaque):
  1324. return self.intval == other.intval
  1325. storage = object()
  1326. if hasattr(other, 'container'):
  1327. storage = other.container._storage
  1328. else:
  1329. storage = other._storage
  1330. if storage in (None, True):
  1331. return False
  1332. return force_cast(lltype.Signed, other._as_ptr()) == self.intval
  1333. def __hash__(self):
  1334. return self.intval
  1335. def __ne__(self, other):
  1336. return not self == other
  1337. def _cast_to_ptr(self, PTRTYPE):
  1338. if self.intval & 1:
  1339. return _opaque_objs[self.intval // 2]
  1340. return force_cast(PTRTYPE, self.intval)
  1341. def cast_adr_to_int(addr):
  1342. if isinstance(addr, llmemory.fakeaddress):
  1343. # use ll2ctypes to obtain a real ctypes-based representation of
  1344. # the memory, and cast that address as an integer
  1345. if addr.ptr is None:
  1346. res = 0
  1347. else:
  1348. res = force_cast(lltype.Signed, addr.ptr)
  1349. else:
  1350. res = addr._cast_to_int()
  1351. if res > maxint:
  1352. res = res - 2*(maxint + 1)
  1353. assert int(res) == res
  1354. return int(res)
  1355. return res
  1356. class CastAdrToIntEntry(ExtRegistryEntry):
  1357. _about_ = cast_adr_to_int
  1358. def compute_result_annotation(self, s_addr):
  1359. return annmodel.SomeInteger()
  1360. def specialize_call(self, hop):
  1361. assert isinstance(hop.args_r[0], raddress.AddressRepr)
  1362. adr, = hop.inputargs(hop.args_r[0])
  1363. hop.exception_cannot_occur()
  1364. return hop.genop('cast_adr_to_int', [adr],
  1365. resulttype = lltype.Signed)
  1366. # ____________________________________________________________
  1367. # errno
  1368. # this saves in a thread-local way the "current" value that errno
  1369. # should have in C. We have to save it away from one external C function
  1370. # call to the next. Otherwise a non-zero value left behind will confuse
  1371. # CPython itself a bit later, and/or CPython will stamp on it before we
  1372. # try to inspect it via rposix.get_errno().
  1373. TLS = tlsobject()
  1374. # helpers to save/restore the C-level errno -- platform-specific because
  1375. # ctypes doesn't just do the right thing and expose it directly :-(
  1376. # on 2.6 ctypes does it right, use it
  1377. if sys.version_info >= (2, 6):
  1378. def _save_c_errno():
  1379. TLS.errno = ctypes.get_errno()
  1380. def _restore_c_errno():
  1381. pass
  1382. else:
  1383. def _where_is_errno():
  1384. raise NotImplementedError("don't know how to get the C-level errno!")
  1385. def _save_c_errno():
  1386. errno_p = _where_is_errno()
  1387. TLS.errno = errno_p.contents.value
  1388. errno_p.contents.value = 0
  1389. def _restore_c_errno():
  1390. if hasattr(TLS, 'errno'):
  1391. _where_is_errno().contents.value = TLS.errno
  1392. if ctypes:
  1393. if _MS_WINDOWS:
  1394. standard_c_lib._errno.restype = ctypes.POINTER(ctypes.c_int)
  1395. def _where_is_errno():
  1396. return standard_c_lib._errno()
  1397. elif sys.platform.startswith('linux'):
  1398. standard_c_lib.__errno_location.restype = ctypes.POINTER(ctypes.c_int)
  1399. def _where_is_errno():
  1400. return standard_c_lib.__errno_location()
  1401. elif sys.platform == 'darwin' or _FREEBSD:
  1402. standard_c_lib.__error.restype = ctypes.POINTER(ctypes.c_int)
  1403. def _where_is_errno():
  1404. return standard_c_lib.__error()