PageRenderTime 72ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/rpython/rtyper/lltypesystem/ll2ctypes.py

https://bitbucket.org/kcr/pypy
Python | 1475 lines | 1278 code | 117 blank | 80 comment | 248 complexity | d4f9b36febf4e5d06c20357525ca2e89 MD5 | raw file
Possible License(s): Apache-2.0

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

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