PageRenderTime 116ms CodeModel.GetById 7ms RepoModel.GetById 8ms app.codeStats 0ms

/pypy/rpython/lltypesystem/ll2ctypes.py

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