PageRenderTime 65ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/rpython/rtyper/lltypesystem/ll2ctypes.py

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

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