PageRenderTime 68ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 1ms

/pypy/rpython/lltypesystem/ll2ctypes.py

https://bitbucket.org/yrttyr/pypy
Python | 1452 lines | 1256 code | 115 blank | 81 comment | 241 complexity | 7f53b99070845a42ead562d595edc6a4 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

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

Large files files are truncated, but you can click here to view the full file