PageRenderTime 36ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/rpython/rtyper/lltypesystem/lltype.py

https://bitbucket.org/pypy/pypy/
Python | 2527 lines | 2396 code | 97 blank | 34 comment | 109 complexity | 3f9008f894992a905e51e46070eaba89 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import weakref
  2. from types import MethodType, NoneType
  3. from rpython.annotator.bookkeeper import analyzer_for, immutablevalue
  4. from rpython.annotator.model import (
  5. AnnotatorError, SomeBool, SomeInteger, SomeObject)
  6. from rpython.rlib.objectmodel import Symbolic
  7. from rpython.rlib.rarithmetic import (
  8. base_int, intmask, is_emulated_long, is_valid_int, longlonglongmask,
  9. longlongmask, maxint, normalizedinttype, r_int, r_longfloat, r_longlong,
  10. r_longlonglong, r_singlefloat, r_uint, r_ulonglong)
  11. from rpython.rtyper.extregistry import ExtRegistryEntry
  12. from rpython.tool import leakfinder
  13. from rpython.tool.identity_dict import identity_dict
  14. class State(object):
  15. pass
  16. TLS = State()
  17. class WeakValueDictionary(weakref.WeakValueDictionary):
  18. """A subclass of weakref.WeakValueDictionary
  19. which resets the 'nested_hash_level' when keys are being deleted.
  20. """
  21. def __init__(self, *args, **kwargs):
  22. weakref.WeakValueDictionary.__init__(self, *args, **kwargs)
  23. remove_base = self._remove
  24. def remove(*args):
  25. if safe_equal is None:
  26. # The interpreter is shutting down, and the comparison
  27. # function is already gone.
  28. return
  29. if TLS is None: # Happens when the interpreter is shutting down
  30. return remove_base(*args)
  31. nested_hash_level = TLS.nested_hash_level
  32. try:
  33. # The 'remove' function is called when an object dies. This
  34. # can happen anywhere when they are reference cycles,
  35. # especially when we are already computing another __hash__
  36. # value. It's not really a recursion in this case, so we
  37. # reset the counter; otherwise the hash value may be be
  38. # incorrect and the key won't be deleted.
  39. TLS.nested_hash_level = 0
  40. remove_base(*args)
  41. finally:
  42. TLS.nested_hash_level = nested_hash_level
  43. self._remove = remove
  44. class _uninitialized(object):
  45. def __init__(self, TYPE):
  46. #self._TYPE = TYPE
  47. self.TYPE = TYPE
  48. def __repr__(self):
  49. return '<Uninitialized %r>'%(self.TYPE,)
  50. def saferecursive(func, defl, TLS=TLS):
  51. def safe(*args):
  52. try:
  53. seeing = TLS.seeing
  54. except AttributeError:
  55. seeing = TLS.seeing = {}
  56. seeingkey = tuple([func] + [id(arg) for arg in args])
  57. if seeingkey in seeing:
  58. return defl
  59. seeing[seeingkey] = True
  60. try:
  61. return func(*args)
  62. finally:
  63. del seeing[seeingkey]
  64. return safe
  65. #safe_equal = saferecursive(operator.eq, True)
  66. def safe_equal(x, y, TLS=TLS):
  67. # a specialized version for performance
  68. try:
  69. seeing = TLS.seeing_eq
  70. except AttributeError:
  71. seeing = TLS.seeing_eq = {}
  72. seeingkey = (id(x), id(y))
  73. if seeingkey in seeing:
  74. return True
  75. seeing[seeingkey] = True
  76. try:
  77. return x == y
  78. finally:
  79. del seeing[seeingkey]
  80. class frozendict(dict):
  81. def __hash__(self):
  82. items = self.items()
  83. items.sort()
  84. return hash(tuple(items))
  85. class LowLevelType(object):
  86. # the following line prevents '__cached_hash' to be in the __dict__ of
  87. # the instance, which is needed for __eq__() and __hash__() to work.
  88. __slots__ = ['__dict__', '__cached_hash']
  89. def __eq__(self, other):
  90. if isinstance(other, Typedef):
  91. return other.__eq__(self)
  92. return self.__class__ is other.__class__ and (
  93. self is other or safe_equal(self.__dict__, other.__dict__))
  94. def __ne__(self, other):
  95. return not (self == other)
  96. _is_compatible = __eq__
  97. def __setattr__(self, attr, nvalue):
  98. try:
  99. LowLevelType.__cached_hash.__get__(self)
  100. except AttributeError:
  101. pass
  102. else:
  103. try:
  104. reprself = repr(self)
  105. except:
  106. try:
  107. reprself = str(self)
  108. except:
  109. reprself = object.__repr__(self)
  110. raise AssertionError("%s: changing the field %r but we already "
  111. "computed the hash" % (reprself, attr))
  112. object.__setattr__(self, attr, nvalue)
  113. def _enforce(self, value):
  114. if typeOf(value) != self:
  115. raise TypeError
  116. return value
  117. def __hash__(self, TLS=TLS):
  118. # cannot use saferecursive() -- see test_lltype.test_hash().
  119. # NB. the __cached_hash should neither be used nor updated
  120. # if we enter with hash_level > 0, because the computed
  121. # __hash__ can be different in this situation.
  122. hash_level = 0
  123. try:
  124. hash_level = TLS.nested_hash_level
  125. if hash_level == 0:
  126. return self.__cached_hash
  127. except AttributeError:
  128. pass
  129. if hash_level >= 3:
  130. return 0
  131. items = self.__dict__.items()
  132. items.sort()
  133. TLS.nested_hash_level = hash_level + 1
  134. try:
  135. result = hash((self.__class__,) + tuple(items))
  136. finally:
  137. TLS.nested_hash_level = hash_level
  138. if hash_level == 0:
  139. self.__cached_hash = result
  140. return result
  141. # due to this dynamic hash value, we should forbid
  142. # pickling, until we have an algorithm for that.
  143. # but we just provide a tag for external help.
  144. __hash_is_not_constant__ = True
  145. def __repr__(self):
  146. return '<%s>' % (self,)
  147. def __str__(self):
  148. return self.__class__.__name__
  149. def _short_name(self):
  150. return str(self)
  151. def _defl(self, parent=None, parentindex=None):
  152. raise NotImplementedError
  153. def _allocate(self, initialization, parent=None, parentindex=None):
  154. assert initialization in ('raw', 'malloc', 'example')
  155. raise NotImplementedError
  156. def _freeze_(self):
  157. return True
  158. def _note_inlined_into(self, parent, first, last):
  159. """Called when this type is being used inline in a container."""
  160. def _is_atomic(self):
  161. return False
  162. def _is_varsize(self):
  163. return False
  164. def _contains_value(self, value):
  165. if self is Void:
  166. return True
  167. return isCompatibleType(typeOf(value), self)
  168. NFOUND = object()
  169. class ContainerType(LowLevelType):
  170. _adtmeths = {}
  171. def _note_inlined_into(self, parent, first, last):
  172. raise TypeError("%r cannot be inlined in %r" % (
  173. self.__class__.__name__, parent.__class__.__name__))
  174. def _install_extras(self, adtmeths={}, hints={}):
  175. self._adtmeths = frozendict(adtmeths)
  176. self._hints = frozendict(hints)
  177. def __getattr__(self, name):
  178. adtmeth = self._adtmeths.get(name, NFOUND)
  179. if adtmeth is not NFOUND:
  180. if getattr(adtmeth, '_type_method', False):
  181. return adtmeth.__get__(self)
  182. else:
  183. return adtmeth
  184. self._nofield(name)
  185. def _nofield(self, name):
  186. raise AttributeError("no field %r" % name)
  187. def _container_example(self):
  188. raise NotImplementedError
  189. class Typedef(LowLevelType):
  190. """A typedef is just another name for an existing type"""
  191. def __init__(self, OF, c_name):
  192. """
  193. @param OF: the equivalent rffi type
  194. @param c_name: the name we want in C code
  195. """
  196. assert isinstance(OF, LowLevelType)
  197. # Look through typedefs, so other places don't have to
  198. if isinstance(OF, Typedef):
  199. OF = OF.OF # haha
  200. self.OF = OF
  201. self.c_name = c_name
  202. def __repr__(self):
  203. return '<Typedef "%s" of %r>' % (self.c_name, self.OF)
  204. def __eq__(self, other):
  205. return other == self.OF
  206. def __getattr__(self, name):
  207. return self.OF.get(name)
  208. def _defl(self, parent=None, parentindex=None):
  209. return self.OF._defl()
  210. def _allocate(self, initialization, parent=None, parentindex=None):
  211. return self.OF._allocate(initialization, parent, parentindex)
  212. class Struct(ContainerType):
  213. _gckind = 'raw'
  214. def __init__(self, name, *fields, **kwds):
  215. self._name = self.__name__ = name
  216. flds = {}
  217. names = []
  218. self._arrayfld = None
  219. for name, typ in fields:
  220. if name.startswith('_'):
  221. raise NameError("%s: field name %r should not start with "
  222. "an underscore" % (self._name, name,))
  223. names.append(name)
  224. if name in flds:
  225. raise TypeError("%s: repeated field name" % self._name)
  226. flds[name] = typ
  227. if isinstance(typ, ContainerType) and typ._gckind != 'raw':
  228. if name == fields[0][0] and typ._gckind == self._gckind:
  229. pass # can inline a XxContainer as 1st field of XxStruct
  230. else:
  231. raise TypeError("%s: cannot inline %s container %r" % (
  232. self._name, typ._gckind, typ))
  233. # look if we have an inlined variable-sized array as the last field
  234. if fields:
  235. first = True
  236. for name, typ in fields[:-1]:
  237. typ._note_inlined_into(self, first=first, last=False)
  238. first = False
  239. name, typ = fields[-1]
  240. typ._note_inlined_into(self, first=first, last=True)
  241. if typ._is_varsize():
  242. self._arrayfld = name
  243. self._flds = frozendict(flds)
  244. self._names = tuple(names)
  245. self._install_extras(**kwds)
  246. def _first_struct(self):
  247. if self._names:
  248. first = self._names[0]
  249. FIRSTTYPE = self._flds[first]
  250. if (isinstance(FIRSTTYPE, Struct) and
  251. self._gckind == FIRSTTYPE._gckind):
  252. return first, FIRSTTYPE
  253. return None, None
  254. def _note_inlined_into(self, parent, first, last):
  255. if self._arrayfld is not None:
  256. raise TypeError("cannot inline a var-sized struct "
  257. "inside another container")
  258. if self._gckind == 'gc':
  259. if not first or not isinstance(parent, GcStruct):
  260. raise TypeError("a GcStruct can only be inlined as the first "
  261. "field of another GcStruct")
  262. def _is_atomic(self):
  263. for typ in self._flds.values():
  264. if not typ._is_atomic():
  265. return False
  266. return True
  267. def _is_varsize(self):
  268. return self._arrayfld is not None
  269. def __getattr__(self, name):
  270. try:
  271. return self._flds[name]
  272. except KeyError:
  273. return ContainerType.__getattr__(self, name)
  274. def _nofield(self, name):
  275. raise AttributeError('struct %s has no field %r' % (self._name,
  276. name))
  277. def _names_without_voids(self):
  278. return [name for name in self._names if self._flds[name] is not Void]
  279. def _str_fields_without_voids(self):
  280. return ', '.join(['%s: %s' % (name, self._flds[name])
  281. for name in self._names_without_voids(False)])
  282. _str_fields_without_voids = saferecursive(_str_fields_without_voids, '...')
  283. def _str_without_voids(self):
  284. return "%s %s { %s }" % (self.__class__.__name__,
  285. self._name, self._str_fields_without_voids())
  286. def _str_fields(self):
  287. return ', '.join(['%s: %s' % (name, self._flds[name])
  288. for name in self._names])
  289. _str_fields = saferecursive(_str_fields, '...')
  290. def __str__(self):
  291. # -- long version --
  292. #return "%s %s { %s }" % (self.__class__.__name__,
  293. # self._name, self._str_fields())
  294. # -- short version --
  295. return "%s %s { %s }" % (self.__class__.__name__, self._name,
  296. ', '.join(self._names))
  297. def _short_name(self):
  298. return "%s %s" % (self.__class__.__name__, self._name)
  299. def _allocate(self, initialization, parent=None, parentindex=None):
  300. return _struct(self, initialization=initialization,
  301. parent=parent, parentindex=parentindex)
  302. def _container_example(self):
  303. if self._arrayfld is None:
  304. n = None
  305. else:
  306. n = 1
  307. return _struct(self, n, initialization='example')
  308. def _immutable_field(self, field):
  309. if self._hints.get('immutable'):
  310. return True
  311. if 'immutable_fields' in self._hints:
  312. try:
  313. return self._hints['immutable_fields'].fields[field]
  314. except KeyError:
  315. pass
  316. return False
  317. class RttiStruct(Struct):
  318. _runtime_type_info = None
  319. def _install_extras(self, rtti=False, **kwds):
  320. if rtti:
  321. self._runtime_type_info = opaqueptr(RuntimeTypeInfo,
  322. name=self._name,
  323. about=self)._obj
  324. Struct._install_extras(self, **kwds)
  325. def _attach_runtime_type_info_funcptr(self, funcptr, destrptr):
  326. if self._runtime_type_info is None:
  327. raise TypeError("attachRuntimeTypeInfo: %r must have been built "
  328. "with the rtti=True argument" % (self,))
  329. if funcptr is not None:
  330. T = typeOf(funcptr)
  331. if (not isinstance(T, Ptr) or
  332. not isinstance(T.TO, FuncType) or
  333. len(T.TO.ARGS) != 1 or
  334. T.TO.RESULT != Ptr(RuntimeTypeInfo) or
  335. castable(T.TO.ARGS[0], Ptr(self)) < 0):
  336. raise TypeError("expected a runtime type info function "
  337. "implementation, got: %s" % funcptr)
  338. self._runtime_type_info.query_funcptr = funcptr
  339. if destrptr is not None:
  340. T = typeOf(destrptr)
  341. if (not isinstance(T, Ptr) or
  342. not isinstance(T.TO, FuncType) or
  343. len(T.TO.ARGS) != 1 or
  344. T.TO.RESULT != Void or
  345. castable(T.TO.ARGS[0], Ptr(self)) < 0):
  346. raise TypeError("expected a destructor function "
  347. "implementation, got: %s" % destrptr)
  348. self._runtime_type_info.destructor_funcptr = destrptr
  349. class GcStruct(RttiStruct):
  350. _gckind = 'gc'
  351. STRUCT_BY_FLAVOR = {'raw': Struct,
  352. 'gc': GcStruct}
  353. class Array(ContainerType):
  354. _gckind = 'raw'
  355. __name__ = 'array'
  356. _anonym_struct = False
  357. def __init__(self, *fields, **kwds):
  358. if len(fields) == 1 and isinstance(fields[0], LowLevelType):
  359. self.OF = fields[0]
  360. else:
  361. self.OF = Struct("<arrayitem>", *fields)
  362. self._anonym_struct = True
  363. if isinstance(self.OF, ContainerType) and self.OF._gckind != 'raw':
  364. raise TypeError("cannot have a %s container as array item type"
  365. % (self.OF._gckind,))
  366. self.OF._note_inlined_into(self, first=False, last=False)
  367. self._install_extras(**kwds)
  368. def _note_inlined_into(self, parent, first, last):
  369. if not last or not isinstance(parent, Struct):
  370. raise TypeError("cannot inline an array in another container"
  371. " unless as the last field of a structure")
  372. if self._gckind == 'gc':
  373. raise TypeError("cannot inline a GC array inside a structure")
  374. if parent._gckind == 'gc' and self._hints.get('nolength', False):
  375. raise TypeError("cannot inline a no-length array inside a GcStruct")
  376. def _is_atomic(self):
  377. return self.OF._is_atomic()
  378. def _is_varsize(self):
  379. return True
  380. def _str_fields(self):
  381. if isinstance(self.OF, Struct):
  382. of = self.OF
  383. if self._anonym_struct:
  384. return "{ %s }" % of._str_fields()
  385. else:
  386. return "%s { %s }" % (of._name, of._str_fields())
  387. elif self._hints.get('render_as_void'):
  388. return 'void'
  389. else:
  390. return str(self.OF)
  391. _str_fields = saferecursive(_str_fields, '...')
  392. def __str__(self):
  393. return "%s of %s " % (self.__class__.__name__,
  394. self._str_fields(),)
  395. def _short_name(self):
  396. return "%s %s" % (self.__class__.__name__,
  397. self.OF._short_name(),)
  398. _short_name = saferecursive(_short_name, '...')
  399. def _container_example(self):
  400. return _array(self, 1, initialization='example')
  401. def _immutable_field(self, index=None):
  402. return self._hints.get('immutable', False)
  403. class GcArray(Array):
  404. _gckind = 'gc'
  405. class FixedSizeArray(Struct):
  406. # behaves more or less like a Struct with fields item0, item1, ...
  407. # but also supports __getitem__(), __setitem__(), __len__().
  408. _cache = WeakValueDictionary() # cache the length-1 FixedSizeArrays
  409. def __new__(cls, OF, length, **kwds):
  410. if length == 1 and not kwds:
  411. try:
  412. obj = FixedSizeArray._cache[OF]
  413. except KeyError:
  414. obj = FixedSizeArray._cache[OF] = Struct.__new__(cls)
  415. except TypeError:
  416. obj = Struct.__new__(cls)
  417. else:
  418. obj = Struct.__new__(cls)
  419. return obj
  420. def __init__(self, OF, length, **kwds):
  421. if '_name' in self.__dict__:
  422. assert self.OF == OF
  423. assert self.length == length
  424. return
  425. fields = [('item%d' % i, OF) for i in range(length)]
  426. super(FixedSizeArray, self).__init__('array%d' % length, *fields,
  427. **kwds)
  428. self.OF = OF
  429. self.length = length
  430. if isinstance(self.OF, ContainerType) and self.OF._gckind != 'raw':
  431. raise TypeError("cannot have a %s container as array item type"
  432. % (self.OF._gckind,))
  433. self.OF._note_inlined_into(self, first=False, last=False)
  434. def _str_fields(self):
  435. return str(self.OF)
  436. _str_fields = saferecursive(_str_fields, '...')
  437. def __str__(self):
  438. return "%s of %d %s " % (self.__class__.__name__,
  439. self.length,
  440. self._str_fields(),)
  441. def _short_name(self):
  442. return "%s %d %s" % (self.__class__.__name__,
  443. self.length,
  444. self.OF._short_name(),)
  445. _short_name = saferecursive(_short_name, '...')
  446. def _first_struct(self):
  447. # don't consider item0 as an inlined first substructure
  448. return None, None
  449. class FuncType(ContainerType):
  450. _gckind = 'raw'
  451. __name__ = 'func'
  452. def __init__(self, args, result, abi='FFI_DEFAULT_ABI'):
  453. for arg in args:
  454. assert isinstance(arg, LowLevelType)
  455. # There are external C functions eating raw structures, not
  456. # pointers, don't check args not being container types
  457. self.ARGS = tuple(args)
  458. assert isinstance(result, LowLevelType)
  459. if isinstance(result, ContainerType):
  460. raise TypeError("function result can only be primitive or pointer")
  461. self.RESULT = result
  462. self.ABI = abi
  463. def __str__(self):
  464. args = ', '.join(map(str, self.ARGS))
  465. return "Func ( %s ) -> %s" % (args, self.RESULT)
  466. __str__ = saferecursive(__str__, '...')
  467. def _short_name(self):
  468. args = ', '.join([ARG._short_name() for ARG in self.ARGS])
  469. return "Func(%s)->%s" % (args, self.RESULT._short_name())
  470. _short_name = saferecursive(_short_name, '...')
  471. def _container_example(self):
  472. def ex(*args):
  473. return self.RESULT._defl()
  474. return _func(self, _callable=ex)
  475. def _trueargs(self):
  476. return [arg for arg in self.ARGS if arg is not Void]
  477. class OpaqueType(ContainerType):
  478. _gckind = 'raw'
  479. def __init__(self, tag, hints={}):
  480. """If hints['render_structure'] is set, the type is internal and
  481. not considered to come from somewhere else (it should be
  482. rendered as a structure)
  483. """
  484. self.tag = tag
  485. self.__name__ = tag
  486. self.hints = frozendict(hints)
  487. def __str__(self):
  488. return "%s (opaque)" % self.tag
  489. def _note_inlined_into(self, parent, first, last):
  490. # OpaqueType can be inlined, but not GcOpaqueType
  491. if self._gckind == 'gc':
  492. raise TypeError("%r cannot be inlined in %r" % (
  493. self.__class__.__name__, parent.__class__.__name__))
  494. def _container_example(self):
  495. return _opaque(self)
  496. def _defl(self, parent=None, parentindex=None):
  497. return _opaque(self, parent=parent, parentindex=parentindex)
  498. def _allocate(self, initialization, parent=None, parentindex=None):
  499. return self._defl(parent=parent, parentindex=parentindex)
  500. RuntimeTypeInfo = OpaqueType("RuntimeTypeInfo")
  501. class GcOpaqueType(OpaqueType):
  502. _gckind = 'gc'
  503. def __str__(self):
  504. return "%s (gcopaque)" % self.tag
  505. class ForwardReference(ContainerType):
  506. _gckind = 'raw'
  507. def become(self, realcontainertype):
  508. if not isinstance(realcontainertype, ContainerType):
  509. raise TypeError("ForwardReference can only be to a container, "
  510. "not %r" % (realcontainertype,))
  511. if realcontainertype._gckind != self._gckind:
  512. raise TypeError("become() gives conflicting gckind, use the "
  513. "correct XxForwardReference")
  514. self.__class__ = realcontainertype.__class__
  515. self.__dict__ = realcontainertype.__dict__
  516. def __hash__(self):
  517. raise TypeError("%r object is not hashable" % self.__class__.__name__)
  518. class GcForwardReference(ForwardReference):
  519. _gckind = 'gc'
  520. class FuncForwardReference(ForwardReference):
  521. _gckind = 'prebuilt'
  522. FORWARDREF_BY_FLAVOR = {'raw': ForwardReference,
  523. 'gc': GcForwardReference,
  524. 'prebuilt': FuncForwardReference}
  525. class Primitive(LowLevelType):
  526. def __init__(self, name, default):
  527. self._name = self.__name__ = name
  528. self._default = default
  529. def __str__(self):
  530. return self._name
  531. def _defl(self, parent=None, parentindex=None):
  532. return self._default
  533. def _allocate(self, initialization, parent=None, parentindex=None):
  534. if self is not Void and initialization != 'example':
  535. return _uninitialized(self)
  536. else:
  537. return self._default
  538. def _is_atomic(self):
  539. return True
  540. def _example(self, parent=None, parentindex=None):
  541. return self._default
  542. class Number(Primitive):
  543. def __init__(self, name, type, cast=None):
  544. Primitive.__init__(self, name, type())
  545. self._type = type
  546. if cast is None:
  547. self._cast = type
  548. else:
  549. self._cast = cast
  550. def normalized(self):
  551. return build_number(None, normalizedinttype(self._type))
  552. _numbertypes = {int: Number("Signed", int, intmask)}
  553. _numbertypes[r_int] = _numbertypes[int]
  554. _numbertypes[r_longlonglong] = Number("SignedLongLongLong", r_longlonglong,
  555. longlonglongmask)
  556. if r_longlong is not r_int:
  557. _numbertypes[r_longlong] = Number("SignedLongLong", r_longlong,
  558. longlongmask)
  559. def build_number(name, type):
  560. try:
  561. return _numbertypes[type]
  562. except KeyError:
  563. pass
  564. if name is None:
  565. raise ValueError('No matching lowlevel type for %r'%type)
  566. number = _numbertypes[type] = Number(name, type)
  567. return number
  568. if is_emulated_long:
  569. SignedFmt = 'q'
  570. else:
  571. SignedFmt = 'l'
  572. Signed = build_number("Signed", int)
  573. Unsigned = build_number("Unsigned", r_uint)
  574. SignedLongLong = build_number("SignedLongLong", r_longlong)
  575. SignedLongLongLong = build_number("SignedLongLongLong", r_longlonglong)
  576. UnsignedLongLong = build_number("UnsignedLongLong", r_ulonglong)
  577. Float = Primitive("Float", 0.0) # C type 'double'
  578. SingleFloat = Primitive("SingleFloat", r_singlefloat(0.0)) # 'float'
  579. LongFloat = Primitive("LongFloat", r_longfloat(0.0)) # 'long double'
  580. r_singlefloat._TYPE = SingleFloat
  581. Char = Primitive("Char", '\x00')
  582. Bool = Primitive("Bool", False)
  583. Void = Primitive("Void", None)
  584. UniChar = Primitive("UniChar", u'\x00')
  585. class Ptr(LowLevelType):
  586. __name__ = property(lambda self: '%sPtr' % self.TO.__name__)
  587. _cache = WeakValueDictionary() # cache the Ptrs
  588. def __new__(cls, TO, use_cache=True):
  589. if not isinstance(TO, ContainerType):
  590. raise TypeError("can only point to a Container type, "
  591. "not to %s" % (TO,))
  592. if not use_cache:
  593. obj = LowLevelType.__new__(cls)
  594. else:
  595. try:
  596. return Ptr._cache[TO]
  597. except KeyError:
  598. obj = Ptr._cache[TO] = LowLevelType.__new__(cls)
  599. except TypeError:
  600. obj = LowLevelType.__new__(cls)
  601. obj.TO = TO
  602. return obj
  603. def _needsgc(self):
  604. # XXX deprecated interface
  605. return self.TO._gckind not in ('raw', 'prebuilt')
  606. def __str__(self):
  607. return '* %s' % (self.TO, )
  608. def _short_name(self):
  609. return 'Ptr %s' % (self.TO._short_name(), )
  610. def _is_atomic(self):
  611. return self.TO._gckind == 'raw'
  612. def _defl(self, parent=None, parentindex=None):
  613. return _ptr(self, None)
  614. def _allocate(self, initialization, parent=None, parentindex=None):
  615. if initialization == 'example':
  616. return _ptr(self, None)
  617. elif initialization == 'malloc' and self._needsgc():
  618. return _ptr(self, None)
  619. else:
  620. return _uninitialized(self)
  621. def _example(self):
  622. o = self.TO._container_example()
  623. return _ptr(self, o, solid=True)
  624. def _interior_ptr_type_with_index(self, TO):
  625. assert self.TO._gckind == 'gc'
  626. if isinstance(TO, Struct):
  627. R = GcStruct("Interior", ('ptr', self), ('index', Signed),
  628. hints={'interior_ptr_type':True},
  629. adtmeths=TO._adtmeths)
  630. else:
  631. R = GcStruct("Interior", ('ptr', self), ('index', Signed),
  632. hints={'interior_ptr_type':True})
  633. return R
  634. @analyzer_for(Ptr)
  635. def constPtr(T):
  636. assert T.is_constant()
  637. return immutablevalue(Ptr(T.const))
  638. class InteriorPtr(LowLevelType):
  639. def __init__(self, PARENTTYPE, TO, offsets):
  640. self.PARENTTYPE = PARENTTYPE
  641. self.TO = TO
  642. self.offsets = tuple(offsets)
  643. def __str__(self):
  644. return '%s (%s).%s'%(self.__class__.__name__,
  645. self.PARENTTYPE._short_name(),
  646. '.'.join(map(str, self.offsets)))
  647. def _example(self):
  648. ob = Ptr(self.PARENTTYPE)._example()
  649. for o in self.offsets:
  650. if isinstance(o, str):
  651. ob = getattr(ob, o)
  652. else:
  653. ob = ob[0]
  654. return ob
  655. # ____________________________________________________________
  656. def typeOf(val):
  657. try:
  658. return val._TYPE
  659. except AttributeError:
  660. tp = type(val)
  661. if tp is _uninitialized:
  662. raise UninitializedMemoryAccess("typeOf uninitialized value")
  663. if tp is NoneType:
  664. return Void # maybe
  665. if tp is int:
  666. return Signed
  667. if tp is long:
  668. if -maxint-1 <= val <= maxint:
  669. return Signed
  670. elif longlongmask(val) == val:
  671. return SignedLongLong
  672. else:
  673. raise OverflowError("integer %r is out of bounds" % (val,))
  674. if tp is bool:
  675. return Bool
  676. if issubclass(tp, base_int):
  677. return build_number(None, tp)
  678. if tp is float:
  679. return Float
  680. if tp is r_longfloat:
  681. return LongFloat
  682. if tp is str:
  683. assert len(val) == 1
  684. return Char
  685. if tp is unicode:
  686. assert len(val) == 1
  687. return UniChar
  688. if issubclass(tp, Symbolic):
  689. return val.lltype()
  690. # if you get a TypeError: typeOf('_interior_ptr' object)
  691. # here, it is very likely that you are accessing an interior pointer
  692. # in an illegal way!
  693. raise TypeError("typeOf(%r object)" % (tp.__name__,))
  694. @analyzer_for(typeOf)
  695. def ann_typeOf(s_val):
  696. from rpython.rtyper.llannotation import annotation_to_lltype
  697. lltype = annotation_to_lltype(s_val, info="in typeOf(): ")
  698. return immutablevalue(lltype)
  699. _to_primitive = {
  700. Char: chr,
  701. UniChar: unichr,
  702. Float: float,
  703. Bool: bool,
  704. }
  705. def cast_primitive(TGT, value):
  706. ORIG = typeOf(value)
  707. if not isinstance(TGT, Primitive) or not isinstance(ORIG, Primitive):
  708. raise TypeError("can only primitive to primitive")
  709. if ORIG == TGT:
  710. return value
  711. if ORIG == Char or ORIG == UniChar:
  712. value = ord(value)
  713. elif ORIG == Float:
  714. if TGT == SingleFloat:
  715. return r_singlefloat(value)
  716. elif TGT == LongFloat:
  717. return r_longfloat(value)
  718. value = long(value)
  719. cast = _to_primitive.get(TGT)
  720. if cast is not None:
  721. return cast(value)
  722. if isinstance(TGT, Number):
  723. return TGT._cast(value)
  724. if ORIG == SingleFloat and TGT == Float:
  725. return float(value)
  726. if ORIG == LongFloat and TGT == Float:
  727. return float(value)
  728. raise TypeError("unsupported cast")
  729. @analyzer_for(cast_primitive)
  730. def ann_cast_primitive(T, s_v):
  731. from rpython.rtyper.llannotation import (
  732. annotation_to_lltype, ll_to_annotation)
  733. assert T.is_constant()
  734. return ll_to_annotation(cast_primitive(T.const,
  735. annotation_to_lltype(s_v)._defl()))
  736. def _cast_whatever(TGT, value):
  737. from rpython.rtyper.lltypesystem import llmemory, rffi
  738. ORIG = typeOf(value)
  739. if ORIG == TGT:
  740. return value
  741. if (isinstance(TGT, Primitive) and
  742. isinstance(ORIG, Primitive)):
  743. return cast_primitive(TGT, value)
  744. elif isinstance(TGT, Ptr):
  745. if isinstance(ORIG, Ptr):
  746. if (isinstance(TGT.TO, OpaqueType) or
  747. isinstance(ORIG.TO, OpaqueType)):
  748. return cast_opaque_ptr(TGT, value)
  749. else:
  750. return cast_pointer(TGT, value)
  751. elif ORIG == llmemory.Address:
  752. return llmemory.cast_adr_to_ptr(value, TGT)
  753. elif TGT == rffi.VOIDP and ORIG == Unsigned:
  754. return rffi.cast(TGT, value)
  755. elif ORIG == Signed:
  756. return cast_int_to_ptr(TGT, value)
  757. elif TGT == llmemory.Address and isinstance(ORIG, Ptr):
  758. return llmemory.cast_ptr_to_adr(value)
  759. elif TGT == Signed and isinstance(ORIG, Ptr) and ORIG.TO._gckind == 'raw':
  760. return llmemory.cast_adr_to_int(llmemory.cast_ptr_to_adr(value),
  761. 'symbolic')
  762. raise TypeError("don't know how to cast from %r to %r" % (ORIG, TGT))
  763. def erasedType(T):
  764. while isinstance(T, Ptr) and isinstance(T.TO, Struct):
  765. first, FIRSTTYPE = T.TO._first_struct()
  766. if first is None:
  767. break
  768. T = Ptr(FIRSTTYPE)
  769. return T
  770. class InvalidCast(TypeError):
  771. pass
  772. def _castdepth(OUTSIDE, INSIDE):
  773. if OUTSIDE == INSIDE:
  774. return 0
  775. dwn = 0
  776. while isinstance(OUTSIDE, Struct):
  777. first, FIRSTTYPE = OUTSIDE._first_struct()
  778. if first is None:
  779. break
  780. dwn += 1
  781. if FIRSTTYPE == INSIDE:
  782. return dwn
  783. OUTSIDE = getattr(OUTSIDE, first)
  784. return -1
  785. def castable(PTRTYPE, CURTYPE):
  786. if CURTYPE.TO._gckind != PTRTYPE.TO._gckind:
  787. raise TypeError("cast_pointer() cannot change the gc status: %s to %s"
  788. % (CURTYPE, PTRTYPE))
  789. if CURTYPE == PTRTYPE:
  790. return 0
  791. if (not isinstance(CURTYPE.TO, Struct) or
  792. not isinstance(PTRTYPE.TO, Struct)):
  793. raise InvalidCast(CURTYPE, PTRTYPE)
  794. CURSTRUC = CURTYPE.TO
  795. PTRSTRUC = PTRTYPE.TO
  796. d = _castdepth(CURSTRUC, PTRSTRUC)
  797. if d >= 0:
  798. return d
  799. u = _castdepth(PTRSTRUC, CURSTRUC)
  800. if u == -1:
  801. raise InvalidCast(CURTYPE, PTRTYPE)
  802. return -u
  803. def cast_pointer(PTRTYPE, ptr):
  804. CURTYPE = typeOf(ptr)
  805. if not isinstance(CURTYPE, Ptr) or not isinstance(PTRTYPE, Ptr):
  806. raise TypeError("can only cast pointers to other pointers")
  807. return ptr._cast_to(PTRTYPE)
  808. @analyzer_for(cast_pointer)
  809. def ann_cast_pointer(PtrT, s_p):
  810. assert isinstance(s_p, SomePtr), "casting of non-pointer: %r" % s_p
  811. assert PtrT.is_constant()
  812. cast_p = cast_pointer(PtrT.const, s_p.ll_ptrtype._defl())
  813. return SomePtr(ll_ptrtype=typeOf(cast_p))
  814. def cast_opaque_ptr(PTRTYPE, ptr):
  815. CURTYPE = typeOf(ptr)
  816. if not isinstance(CURTYPE, Ptr) or not isinstance(PTRTYPE, Ptr):
  817. raise TypeError("can only cast pointers to other pointers")
  818. if CURTYPE == PTRTYPE:
  819. return ptr
  820. if CURTYPE.TO._gckind != PTRTYPE.TO._gckind:
  821. raise TypeError("cast_opaque_ptr() cannot change the gc status: "
  822. "%s to %s" % (CURTYPE, PTRTYPE))
  823. if (isinstance(CURTYPE.TO, OpaqueType)
  824. and not isinstance(PTRTYPE.TO, OpaqueType)):
  825. if hasattr(ptr._obj, '_cast_to_ptr'):
  826. return ptr._obj._cast_to_ptr(PTRTYPE)
  827. if not ptr:
  828. return nullptr(PTRTYPE.TO)
  829. try:
  830. container = ptr._obj.container
  831. except AttributeError:
  832. raise InvalidCast("%r does not come from a container" % (ptr,))
  833. solid = getattr(ptr._obj, 'solid', False)
  834. p = _ptr(Ptr(typeOf(container)), container, solid)
  835. return cast_pointer(PTRTYPE, p)
  836. elif (not isinstance(CURTYPE.TO, OpaqueType)
  837. and isinstance(PTRTYPE.TO, OpaqueType)):
  838. if hasattr(ptr, '_cast_to_opaque'):
  839. return ptr._cast_to_opaque(PTRTYPE)
  840. if not ptr:
  841. return nullptr(PTRTYPE.TO)
  842. return opaqueptr(PTRTYPE.TO, 'hidden', container = ptr._obj,
  843. ORIGTYPE = CURTYPE,
  844. solid = ptr._solid)
  845. elif (isinstance(CURTYPE.TO, OpaqueType)
  846. and isinstance(PTRTYPE.TO, OpaqueType)):
  847. if not ptr:
  848. return nullptr(PTRTYPE.TO)
  849. try:
  850. container = ptr._obj.container
  851. except AttributeError:
  852. raise InvalidCast("%r does not come from a container" % (ptr,))
  853. return opaqueptr(PTRTYPE.TO, 'hidden',
  854. container = container,
  855. solid = ptr._obj.solid)
  856. else:
  857. raise TypeError("invalid cast_opaque_ptr(): %r -> %r" %
  858. (CURTYPE, PTRTYPE))
  859. @analyzer_for(cast_opaque_ptr)
  860. def ann_cast_opaque_ptr(PtrT, s_p):
  861. assert isinstance(s_p, SomePtr), "casting of non-pointer: %r" % s_p
  862. assert PtrT.is_constant()
  863. cast_p = cast_opaque_ptr(PtrT.const, s_p.ll_ptrtype._defl())
  864. return SomePtr(ll_ptrtype=typeOf(cast_p))
  865. def length_of_simple_gcarray_from_opaque(opaque_ptr):
  866. CURTYPE = typeOf(opaque_ptr)
  867. if not isinstance(CURTYPE, Ptr):
  868. raise TypeError("can only cast pointers to other pointers")
  869. if not isinstance(CURTYPE.TO, GcOpaqueType):
  870. raise TypeError("expected a GcOpaqueType")
  871. try:
  872. c = opaque_ptr._obj.container
  873. except AttributeError:
  874. # if 'opaque_ptr' is already some _llgcopaque, hack its length
  875. # by casting it to a random GcArray type and hoping
  876. from rpython.rtyper.lltypesystem import rffi
  877. p = rffi.cast(Ptr(GcArray(Signed)), opaque_ptr)
  878. return len(p)
  879. else:
  880. return c.getlength()
  881. @analyzer_for(length_of_simple_gcarray_from_opaque)
  882. def ann_length_of_simple_gcarray_from_opaque(s_p):
  883. assert isinstance(s_p, SomePtr), "casting of non-pointer: %r" % s_p
  884. assert isinstance(s_p.ll_ptrtype.TO, GcOpaqueType)
  885. return SomeInteger(nonneg=True)
  886. def direct_fieldptr(structptr, fieldname):
  887. """Get a pointer to a field in the struct. The resulting
  888. pointer is actually of type Ptr(FixedSizeArray(FIELD, 1)).
  889. It can be used in a regular getarrayitem(0) or setarrayitem(0)
  890. to read or write to the field.
  891. """
  892. CURTYPE = typeOf(structptr).TO
  893. if not isinstance(CURTYPE, Struct):
  894. raise TypeError("direct_fieldptr: not a struct")
  895. if fieldname not in CURTYPE._flds:
  896. raise TypeError("%s has no field %r" % (CURTYPE, fieldname))
  897. if not structptr:
  898. raise RuntimeError("direct_fieldptr: NULL argument")
  899. return _subarray._makeptr(structptr._obj, fieldname, structptr._solid)
  900. @analyzer_for(direct_fieldptr)
  901. def ann_direct_fieldptr(s_p, s_fieldname):
  902. assert isinstance(s_p, SomePtr), "direct_* of non-pointer: %r" % s_p
  903. assert s_fieldname.is_constant()
  904. cast_p = direct_fieldptr(s_p.ll_ptrtype._example(),
  905. s_fieldname.const)
  906. return SomePtr(ll_ptrtype=typeOf(cast_p))
  907. def direct_arrayitems(arrayptr):
  908. """Get a pointer to the first item of the array. The resulting
  909. pointer is actually of type Ptr(FixedSizeArray(ITEM, 1)) but can
  910. be used in a regular getarrayitem(n) or direct_ptradd(n) to access
  911. further elements.
  912. """
  913. CURTYPE = typeOf(arrayptr).TO
  914. if not isinstance(CURTYPE, (Array, FixedSizeArray)):
  915. raise TypeError("direct_arrayitems: not an array")
  916. if not arrayptr:
  917. raise RuntimeError("direct_arrayitems: NULL argument")
  918. return _subarray._makeptr(arrayptr._obj, 0, arrayptr._solid)
  919. @analyzer_for(direct_arrayitems)
  920. def ann_direct_arrayitems(s_p):
  921. assert isinstance(s_p, SomePtr), "direct_* of non-pointer: %r" % s_p
  922. cast_p = direct_arrayitems(s_p.ll_ptrtype._example())
  923. return SomePtr(ll_ptrtype=typeOf(cast_p))
  924. def direct_ptradd(ptr, n):
  925. """Shift a pointer forward or backward by n items. The pointer must
  926. have been built by direct_arrayitems(), or it must be directly a
  927. pointer to a raw array with no length (handled by emulation with ctypes).
  928. """
  929. if not ptr:
  930. raise RuntimeError("direct_ptradd: NULL argument")
  931. if not isinstance(ptr._obj, _subarray):
  932. # special case: delegate barebone C-like array cases to rffi.ptradd()
  933. from rpython.rtyper.lltypesystem import rffi
  934. return rffi.ptradd(ptr, n)
  935. parent, base = parentlink(ptr._obj)
  936. return _subarray._makeptr(parent, base + n, ptr._solid)
  937. @analyzer_for(direct_ptradd)
  938. def ann_direct_ptradd(s_p, s_n):
  939. assert isinstance(s_p, SomePtr), "direct_* of non-pointer: %r" % s_p
  940. # don't bother with an example here: the resulting pointer is the same
  941. return s_p
  942. def parentlink(container):
  943. parent = container._parentstructure()
  944. if parent is not None:
  945. return parent, container._parent_index
  946. else:
  947. return None, None
  948. def top_container(container):
  949. top_parent = container
  950. while True:
  951. parent = top_parent._parentstructure()
  952. if parent is None:
  953. break
  954. top_parent = parent
  955. return top_parent
  956. def normalizeptr(p, check=True):
  957. # If p is a pointer, returns the same pointer casted to the largest
  958. # containing structure (for the cast where p points to the header part).
  959. # Also un-hides pointers to opaque. Null pointers become None.
  960. assert not isinstance(p, _container) # pointer or primitive
  961. T = typeOf(p)
  962. if not isinstance(T, Ptr):
  963. return p # primitive
  964. obj = p._getobj(check)
  965. if not obj:
  966. return None # null pointer
  967. if type(p._obj0) is int:
  968. return p # a pointer obtained by cast_int_to_ptr
  969. if getattr(p._obj0, '_carry_around_for_tests', False):
  970. return p # a pointer obtained by cast_instance_to_base_ptr
  971. container = obj._normalizedcontainer()
  972. if type(container) is int:
  973. # this must be an opaque ptr originating from an integer
  974. assert isinstance(obj, _opaque)
  975. return cast_int_to_ptr(obj.ORIGTYPE, container)
  976. if container is not obj:
  977. p = _ptr(Ptr(typeOf(container)), container, p._solid)
  978. return p
  979. class DelayedPointer(Exception):
  980. pass
  981. class UninitializedMemoryAccess(Exception):
  982. pass
  983. class _abstract_ptr(object):
  984. __slots__ = ('_T',)
  985. # assumes one can access _TYPE, _expose and _obj
  986. def _set_T(self, T):
  987. _ptr._T.__set__(self, T)
  988. def _togckind(self):
  989. return self._T._gckind
  990. def _needsgc(self):
  991. # XXX deprecated interface
  992. return self._TYPE._needsgc() # xxx other rules?
  993. def __eq__(self, other):
  994. if type(self) is not type(other):
  995. raise TypeError("comparing pointer with %r object" % (
  996. type(other).__name__,))
  997. if self._TYPE != other._TYPE:
  998. raise TypeError("comparing %r and %r" % (self._TYPE, other._TYPE))
  999. try:
  1000. return self._obj == other._obj
  1001. except DelayedPointer:
  1002. # if one of the two pointers is delayed, they cannot
  1003. # possibly be equal unless they are the same _ptr instance
  1004. return self is other
  1005. def __ne__(self, other):
  1006. return not (self == other)
  1007. def _same_obj(self, other):
  1008. return self._obj == other._obj
  1009. def __hash__(self):
  1010. raise TypeError("pointer objects are not hashable")
  1011. def __nonzero__(self):
  1012. try:
  1013. return self._obj is not None
  1014. except DelayedPointer:
  1015. return True # assume it's not a delayed null
  1016. # _setobj, _getobj and _obj0 are really _internal_ implementations
  1017. # details of _ptr, use _obj if necessary instead !
  1018. def _setobj(self, pointing_to, solid=False):
  1019. if pointing_to is None:
  1020. obj0 = None
  1021. elif (solid or self._T._gckind != 'raw' or
  1022. isinstance(self._T, FuncType)):
  1023. obj0 = pointing_to
  1024. else:
  1025. self._set_weak(True)
  1026. obj0 = weakref.ref(pointing_to)
  1027. self._set_solid(solid)
  1028. self._set_obj0(obj0)
  1029. def _getobj(self, check=True):
  1030. obj = self._obj0
  1031. if obj is not None:
  1032. if self._weak:
  1033. obj = obj()
  1034. if obj is None:
  1035. raise RuntimeError("accessing already garbage collected %r"
  1036. % (self._T,))
  1037. if isinstance(obj, _container):
  1038. if check:
  1039. obj._check()
  1040. elif isinstance(obj, str) and obj.startswith("delayed!"):
  1041. raise DelayedPointer
  1042. return obj
  1043. _obj = property(_getobj)
  1044. def _was_freed(self):
  1045. return (type(self._obj0) not in (type(None), int) and
  1046. self._getobj(check=False)._was_freed())
  1047. def _lookup_adtmeth(self, member_name):
  1048. if isinstance(self._T, ContainerType):
  1049. try:
  1050. adtmember = self._T._adtmeths[member_name]
  1051. except KeyError:
  1052. pass
  1053. else:
  1054. try:
  1055. getter = adtmember.__get__
  1056. except AttributeError:
  1057. return adtmember
  1058. else:
  1059. return getter(self)
  1060. raise AttributeError
  1061. def __getattr__(self, field_name): # ! can only return basic or ptr !
  1062. if isinstance(self._T, Struct):
  1063. if field_name in self._T._flds:
  1064. o = self._obj._getattr(field_name)
  1065. return self._expose(field_name, o)
  1066. try:
  1067. return self._lookup_adtmeth(field_name)
  1068. except AttributeError:
  1069. raise AttributeError("%r instance has no field %r" % (self._T,
  1070. field_name))
  1071. def __setattr__(self, field_name, val):
  1072. if isinstance(self._T, Struct):
  1073. if field_name in self._T._flds:
  1074. T1 = self._T._flds[field_name]
  1075. T2 = typeOf(val)
  1076. if T1 == T2:
  1077. setattr(self._obj, field_name, val)
  1078. else:
  1079. raise TypeError(
  1080. "%r instance field %r:\nexpects %r\n got %r" %
  1081. (self._T, field_name, T1, T2))
  1082. return
  1083. raise AttributeError("%r instance has no field %r" %
  1084. (self._T, field_name))
  1085. def __getitem__(self, i): # ! can only return basic or ptr !
  1086. if isinstance(self._T, (Array, FixedSizeArray)):
  1087. start, stop = self._obj.getbounds()
  1088. if not (start <= i < stop):
  1089. if isinstance(i, slice):
  1090. raise TypeError("array slicing not supported")
  1091. raise IndexError("array index out of bounds")
  1092. o = self._obj.getitem(i)
  1093. return self._expose(i, o)
  1094. raise TypeError("%r instance is not an array" % (self._T,))
  1095. def __setitem__(self, i, val):
  1096. if isinstance(self._T, (Array, FixedSizeArray)):
  1097. T1 = self._T.OF
  1098. if isinstance(T1, ContainerType):
  1099. raise TypeError("cannot directly assign to container array "
  1100. "items")
  1101. T2 = typeOf(val)
  1102. if T2 != T1:
  1103. from rpython.rtyper.lltypesystem import rffi
  1104. if T1 is rffi.VOIDP and isinstance(T2, Ptr):
  1105. # Any pointer is convertible to void*
  1106. val = rffi.cast(rffi.VOIDP, val)
  1107. else:
  1108. raise TypeError("%r items:\n"
  1109. "expect %r\n"
  1110. " got %r" % (self._T, T1, T2))
  1111. start, stop = self._obj.getbounds()
  1112. if not (start <= i < stop):
  1113. if isinstance(i, slice):
  1114. raise TypeError("array slicing not supported")
  1115. raise IndexError("array index out of bounds")
  1116. self._obj.setitem(i, val)
  1117. return
  1118. raise TypeError("%r instance is not an array" % (self._T,))
  1119. def __len__(self):
  1120. if isinstance(self._T, (Array, FixedSizeArray)):
  1121. if self._T._hints.get('nolength', False):
  1122. raise TypeError("%r instance has no length attribute" %
  1123. (self._T,))
  1124. return self._obj.getlength()
  1125. raise TypeError("%r instance is not an array" % (self._T,))
  1126. def _fixedlength(self):
  1127. length = len(self) # always do this, for the checking
  1128. if isinstance(self._T, FixedSizeArray):
  1129. return length
  1130. else:
  1131. return None
  1132. def __repr__(self):
  1133. return '<%s>' % (self,)
  1134. def __str__(self):
  1135. try:
  1136. return '* %s' % (self._obj, )
  1137. except RuntimeError:
  1138. return '* DEAD %s' % self._T
  1139. except DelayedPointer:
  1140. return '* %s' % (self._obj0,)
  1141. def __call__(self, *args):
  1142. from rpython.rtyper.lltypesystem import rffi
  1143. if isinstance(self._T, FuncType):
  1144. if len(args) != len(self._T.ARGS):
  1145. raise TypeError("calling %r with wrong argument number: %r" %
  1146. (self._T, args))
  1147. for i, a, ARG in zip(range(len(self._T.ARGS)), args, self._T.ARGS):
  1148. if typeOf(a) != ARG:
  1149. # ARG could be Void
  1150. if ARG == Void:
  1151. try:
  1152. value = getattr(self._obj, '_void' + str(i))
  1153. except AttributeError:
  1154. pass
  1155. else:
  1156. assert a == value
  1157. # None is acceptable for any pointer
  1158. elif isinstance(ARG, Ptr) and a is None:
  1159. pass
  1160. # Any pointer is convertible to void*
  1161. elif ARG is rffi.VOIDP and isinstance(typeOf(a), Ptr):
  1162. pass
  1163. # special case: ARG can be a container type, in which
  1164. # case a should be a pointer to it. This must also be
  1165. # special-cased in the backends.
  1166. elif (isinstance(ARG, ContainerType) and
  1167. typeOf(a) == Ptr(ARG)):
  1168. pass
  1169. else:
  1170. args_repr = [typeOf(arg) for arg in args]
  1171. raise TypeError("calling %r with wrong argument "
  1172. "types: %r" % (self._T, args_repr))
  1173. callb = self._obj._callable
  1174. if callb is None:
  1175. raise RuntimeError("calling undefined function")
  1176. return callb(*args)
  1177. raise TypeError("%r instance is not a function" % (self._T,))
  1178. def _identityhash(self, cache=True):
  1179. p = normalizeptr(self)
  1180. try:
  1181. return p._obj._hash_cache_
  1182. except AttributeError:
  1183. assert self._T._gckind == 'gc'
  1184. assert self # not for NULL
  1185. result = hash(p._obj)
  1186. if cache:
  1187. try:
  1188. p._obj._hash_cache_ = result
  1189. except AttributeError:
  1190. pass
  1191. return result
  1192. class _ptr(_abstract_ptr):
  1193. __slots__ = ('_TYPE',
  1194. '_weak', '_solid',
  1195. '_obj0', '__weakref__')
  1196. def _set_TYPE(self, TYPE):
  1197. _ptr._TYPE.__set__(self, TYPE)
  1198. def _set_weak(self, weak):
  1199. _ptr._weak.__set__(self, weak)
  1200. def _set_solid(self, solid):
  1201. _ptr._solid.__set__(self, solid)
  1202. def _set_obj0(self, obj):
  1203. _ptr._obj0.__set__(self, obj)
  1204. def __init__(self, TYPE, pointing_to, solid=False):
  1205. self._set_TYPE(TYPE)
  1206. self._set_T(TYPE.TO)
  1207. self._set_weak(False)
  1208. self._setobj(pointing_to, solid)
  1209. def _become(self, other):
  1210. assert self._TYPE == other._TYPE
  1211. assert not self._weak
  1212. self._setobj(other._obj, other._solid)
  1213. def _cast_to(self, PTRTYPE):
  1214. CURTYPE = self._TYPE
  1215. down_or_up = castable(PTRTYPE, CURTYPE)
  1216. if down_or_up == 0:
  1217. return self
  1218. if not self: # null pointer cast
  1219. return PTRTYPE._defl()
  1220. if isinstance(self._obj, int):
  1221. return _ptr(PTRTYPE, self._obj, solid=True)
  1222. if down_or_up > 0:
  1223. p = self
  1224. while down_or_up:
  1225. p = getattr(p, typeOf(p).TO._names[0])
  1226. down_or_up -= 1
  1227. return _ptr(PTRTYPE, p._obj, solid=self._solid)
  1228. u = -down_or_up
  1229. struc = self._obj
  1230. while u:
  1231. parent = struc._parentstructure()
  1232. if parent is None:
  1233. raise RuntimeError("widening to trash: %r" % self)
  1234. PARENTTYPE = struc._parent_type
  1235. if getattr(parent, PARENTTYPE._names[0]) != struc:
  1236. # xxx different exception perhaps?
  1237. raise InvalidCast(CURTYPE, PTRTYPE)
  1238. struc = parent
  1239. u -= 1
  1240. if PARENTTYPE != PTRTYPE.TO:
  1241. raise RuntimeError("widening %r inside %r instead of %r" %
  1242. (CURTYPE, PARENTTYPE, PTRTYPE.TO))
  1243. return _ptr(PTRTYPE, struc, solid=self._solid)
  1244. def _cast_to_int(self, check=True):
  1245. obj = self._getobj(check)
  1246. if not obj:
  1247. return 0 # NULL pointer
  1248. if isinstance(obj, int):
  1249. return obj # special case for cast_int_to_ptr() results
  1250. obj = normalizeptr(self, check)._getobj(check)
  1251. if isinstance(obj, int):
  1252. # special case for cast_int_to_ptr() results put into
  1253. # opaques
  1254. return obj
  1255. if getattr(obj, '_read_directly_intval', False):
  1256. return obj.intval # special case for _llgcopaque
  1257. result = intmask(obj._getid())
  1258. # assume that id() returns an addressish value which is
  1259. # not zero and aligned to at least a multiple of 4
  1260. # (at least for GC pointers; we can't really assume anything
  1261. # for raw addresses)
  1262. if self._T._gckind == 'gc':
  1263. assert result != 0 and (result & 3) == 0
  1264. return result
  1265. def _cast_to_adr(self):
  1266. from rpython.rtyper.lltypesystem import llmemory
  1267. if isinstance(self._T, FuncType):
  1268. return llmemory.fakeaddress(self)
  1269. elif self._was_freed():
  1270. # hack to support llarena.test_replace_object_with_stub()
  1271. from rpython.rtyper.lltypesystem import llarena
  1272. return llarena._oldobj_to_address(self._getobj(check=False))
  1273. elif isinstance(self._obj, _subarray):
  1274. return llmemory.fakeaddress(self)
  1275. ## # return an address built as an offset in the whole array
  1276. ## parent, parentindex = parentlink(self._obj)
  1277. ## T = typeOf(parent)
  1278. ## addr = llmemory.fakeaddress(normalizeptr(_ptr(Ptr(T), parent)))
  1279. ## addr += llmemory.itemoffsetof(T, parentindex)
  1280. ## return addr
  1281. else:
  1282. # normal case
  1283. return llmemory.fakeaddress(normalizeptr(self))
  1284. def _as_ptr(self):
  1285. return self
  1286. def _as_obj(self, check=True):
  1287. return self._getobj(check=check)
  1288. def _expose(self, offset, val):
  1289. """XXX A nice docstring here"""
  1290. T = typeOf(val)
  1291. if isinstance(T, ContainerType):
  1292. if (self._T._gckind == 'gc' and T._gckind == 'raw' and
  1293. not isinstance(T, OpaqueType)):
  1294. val = _interior_ptr(T, self._obj, [offset])
  1295. else:
  1296. val = _ptr(Ptr(T), val, solid=self._solid)
  1297. return val
  1298. assert not '__dict__' in dir(_ptr)
  1299. class _ptrEntry(ExtRegistryEntry):
  1300. _type_ = _ptr
  1301. def compute_annotation(self):
  1302. from rpython.rtyper.llannotation import SomePtr
  1303. return SomePtr(typeOf(self.instance))
  1304. class SomePtr(SomeObject):
  1305. knowntype = _ptr
  1306. immutable = True
  1307. def __init__(self, ll_ptrtype):
  1308. assert isinstance(ll_ptrtype, Ptr)
  1309. self.ll_ptrtype = ll_ptrtype
  1310. def can_be_none(self):
  1311. return False
  1312. def getattr(self, s_attr):
  1313. from rpython.rtyper.llannotation import SomeLLADTMeth, ll_to_annotation
  1314. if not s_attr.is_constant():
  1315. raise AnnotatorError("getattr on ptr %r with non-constant "
  1316. "field-name" % self.ll_ptrtype)
  1317. example = self.ll_ptrtype._example()
  1318. try:
  1319. v = example._lookup_adtmeth(s_attr.const)
  1320. except AttributeError:
  1321. v = getattr(example, s_attr.const)
  1322. return ll_to_annotation(v)
  1323. else:
  1324. if isinstance(v, MethodType):
  1325. ll_ptrtype = typeOf(v.im_self)
  1326. assert isinstance(ll_ptrtype, (Ptr, InteriorPtr))
  1327. return SomeLLADTMeth(ll_ptrtype, v.im_func)
  1328. return immutablevalue(v)
  1329. getattr.can_only_throw = []
  1330. def len(self):
  1331. length = self.ll_ptrtype._example()._fixedlength()
  1332. if length is None:
  1333. return SomeObject.len(self)
  1334. else:
  1335. return immutablevalue(length)
  1336. def setattr(self, s_attr, s_value): # just doing checking
  1337. from rpython.rtyper.llannotation import annotation_to_lltype
  1338. if not s_attr.is_constant():
  1339. raise AnnotatorError("setattr on ptr %r with non-constant "
  1340. "field-name" % self.ll_ptrtype)
  1341. example = self.ll_ptrtype._example()
  1342. if getattr(example, s_attr.const) is not None: # ignore Void s_value
  1343. v_lltype = annotation_to_lltype(s_value)
  1344. setattr(example, s_attr.const, v_lltype._defl())
  1345. def call(self, args):
  1346. from rpython.rtyper.llannotation import (
  1347. annotation_to_lltype, ll_to_annotation)
  1348. args_s, kwds_s = args.unpack()
  1349. if kwds_s:
  1350. raise Exception("keyword arguments to call to a low-level fn ptr")
  1351. info = 'argument to ll function pointer call'
  1352. llargs = [annotation_to_lltype(s_arg, info)._defl()
  1353. for s_arg in args_s]
  1354. v = self.ll_ptrtype._example()(*llargs)
  1355. return ll_to_annotation(v)
  1356. def bool(self):
  1357. result = SomeBool()
  1358. if self.is_constant():
  1359. result.const = bool(self.const)
  1360. return result
  1361. class _interior_ptr(_abstract_ptr):
  1362. __slots__ = ('_parent', '_offsets')
  1363. def _set_parent(self, _parent):
  1364. _interior_ptr._parent.__set__(self, _parent)
  1365. def _set_offsets(self, _offsets):
  1366. _interior_ptr._offsets.__set__(self, _offsets)
  1367. def __init__(self, _T, _parent, _offsets):
  1368. self._set_T(_T)
  1369. #self._set_parent(weakref.ref(_parent))
  1370. self._set_parent(_parent)
  1371. self._set_offsets(_offsets)
  1372. def __nonzero__(self):
  1373. raise RuntimeError("do not test an interior pointer for nullity")
  1374. def _get_obj(self):
  1375. ob = self._parent
  1376. if ob is None:
  1377. raise RuntimeError
  1378. if isinstance(ob, _container):
  1379. ob._check()
  1380. for o in self._offsets:
  1381. if isinstance(o, str):
  1382. ob = ob._getattr(o)
  1383. else:
  1384. ob = ob.getitem(o)
  1385. return ob
  1386. _obj = property(_get_obj)
  1387. def _get_TYPE(self):
  1388. ob = self._parent
  1389. if ob is None:
  1390. raise RuntimeError
  1391. return InteriorPtr(typeOf(ob), self._T, self._offsets)
  1392. ## _TYPE = property(_get_TYPE)
  1393. def _expose(self, offset, val):
  1394. """XXX A nice docstring here"""
  1395. T = typeOf(val)
  1396. if isinstance(T, ContainerType):
  1397. assert T._gckind == 'raw'
  1398. val = _interior_ptr(T, self._parent, self._offsets + [offset])
  1399. return val
  1400. assert not '__dict__' in dir(_interior_ptr)
  1401. class _container(object):
  1402. __slots__ = ()
  1403. def _parentstructure(self, check=True):
  1404. return None
  1405. def _check(self):
  1406. pass
  1407. def _as_ptr(self):
  1408. return _ptr(Ptr(self._TYPE), self, True)
  1409. def _as_obj(self, check=True):
  1410. return self
  1411. def _normalizedcontainer(self, check=True):
  1412. return self
  1413. def _getid(self):
  1414. return id(self)
  1415. def _was_freed(self):
  1416. return False
  1417. class _parentable(_container):
  1418. _kind = "?"
  1419. __slots__ = ('_TYPE',
  1420. '_parent_type', '_parent_index', '_keepparent',
  1421. '_wrparent',
  1422. '__weakref__',
  1423. '_storage')
  1424. def __init__(self, TYPE):
  1425. self._wrparent = None
  1426. self._TYPE = TYPE
  1427. self._storage = True # means "use default storage", as opposed to:
  1428. # None - container was freed
  1429. # <ctypes object> - using ctypes
  1430. # (see ll2ctypes.py)
  1431. def _free(self):
  1432. self._check() # no double-frees
  1433. self._storage = None
  1434. def _protect(self):
  1435. result = self._storage
  1436. self._free() # no double-frees or double-protects
  1437. return result
  1438. def _unprotect(self, saved_storage):
  1439. assert self._storage is None
  1440. self._storage = saved_storage
  1441. def _was_freed(self):
  1442. if self._storage is None:
  1443. return True
  1444. if self._wrparent is None:
  1445. return False
  1446. parent = self._wrparent()
  1447. if parent is None:
  1448. raise RuntimeError("accessing sub%s %r,\n"
  1449. "but already garbage collected parent %r"
  1450. % (self._kind, self, self._parent_type))
  1451. return parent._was_freed()
  1452. def _setparentstructure(self, parent, parentindex):
  1453. self._wrparent = weakref.ref(parent)
  1454. self._parent_type = typeOf(parent)
  1455. self._parent_index = parentindex
  1456. if (isinstance(self._parent_type, Struct)
  1457. and self._parent_type._names
  1458. and parentindex in (self._parent_type._names[0], 0)
  1459. and self._TYPE._gckind == typeOf(parent)._gckind):
  1460. # keep strong reference to parent, we share the same allocation
  1461. self._keepparent = parent
  1462. def _parentstructure(self, check=True):
  1463. if self._wrparent is not None:
  1464. parent = self._wrparent()
  1465. if parent is None:
  1466. raise RuntimeError("accessing sub%s %r,\n"
  1467. "but already garbage collected parent %r"
  1468. % (self._kind, self, self._parent_type))
  1469. if check:
  1470. parent._check()
  1471. return parent
  1472. return None
  1473. def _check(self):
  1474. if self._storage is None:
  1475. raise RuntimeError("accessing freed %r" % self._TYPE)
  1476. self._parentstructure()
  1477. def _normalizedcontainer(self, check=True):
  1478. # if we are the first inlined substructure of a structure,
  1479. # return the whole (larger) structure instead
  1480. container = self
  1481. while True:
  1482. parent = container._parentstructure(check=check)
  1483. if parent is None:
  1484. break
  1485. index = container._parent_index
  1486. T = typeOf(parent)
  1487. if (not isinstance(T, Struct) or T._first_struct()[0] != index
  1488. or isinstance(T, FixedSizeArray)):
  1489. break
  1490. container = parent
  1491. return container
  1492. def _struct_variety(flds, cache={}):
  1493. flds = list(flds)
  1494. flds.sort()
  1495. tag = tuple(flds)
  1496. try:
  1497. return cache[tag]
  1498. except KeyError:
  1499. class _struct1(_struct):
  1500. __slots__ = tag + ('__arena_location__',)
  1501. cache[tag] = _struct1
  1502. return _struct1
  1503. #for pickling support:
  1504. def _get_empty_instance_of_struct_variety(flds):
  1505. cls = _struct_variety(flds)
  1506. return object.__new__(cls)
  1507. class _struct(_parentable):
  1508. _kind = "structure"
  1509. __slots__ = ('_hash_cache_', '_compilation_info')
  1510. def __new__(self, TYPE, n=None, initialization=None, parent=None,
  1511. parentindex=None):
  1512. if isinstance(TYPE, FixedSizeArray):
  1513. my_variety = _fixedsizearray
  1514. else:
  1515. my_variety = _struct_variety(TYPE._names)
  1516. return object.__new__(my_variety)
  1517. def __init__(self, TYPE, n=None, initialization=None, parent=None,
  1518. parentindex=None):
  1519. _parentable.__init__(self, TYPE)
  1520. if n is not None and TYPE._arrayfld is None:
  1521. raise TypeError("%r is not variable-sized" % (TYPE,))
  1522. if n is None and TYPE._arrayfld is not None:
  1523. raise TypeError("%r is variable-sized" % (TYPE,))
  1524. for fld, typ in TYPE._flds.items():
  1525. if fld == TYPE._arrayfld:
  1526. value = _array(typ, n, initialization=initialization,
  1527. parent=self, parentindex=fld)
  1528. else:
  1529. value = typ._allocate(initialization=initialization,
  1530. parent=self, parentindex=fld)
  1531. setattr(self, fld, value)
  1532. if parent is not None:
  1533. self._setparentstructure(parent, parentindex)
  1534. def __repr__(self):
  1535. return '<%s>' % (self,)
  1536. def _str_fields(self):
  1537. fields = []
  1538. names = self._TYPE._names
  1539. if len(names) > 10:
  1540. names = names[:5] + names[-1:]
  1541. skipped_after = 5
  1542. else:
  1543. skipped_after = None
  1544. for name in names:
  1545. T = self._TYPE._flds[name]
  1546. if isinstance(T, Primitive):
  1547. reprvalue = repr(getattr(self, name, '<uninitialized>'))
  1548. else:
  1549. reprvalue = '...'
  1550. fields.append('%s=%s' % (name, reprvalue))
  1551. if skipped_after:
  1552. fields.insert(skipped_after, '(...)')
  1553. return ', '.join(fields)
  1554. def __str__(self):
  1555. return 'struct %s { %s }' % (self._TYPE._name, self._str_fields())
  1556. def _getattr(self, field_name, uninitialized_ok=False):
  1557. r = getattr(self, field_name)
  1558. if isinstance(r, _uninitialized) and not uninitialized_ok:
  1559. raise UninitializedMemoryAccess("%r.%s"%(self, field_name))
  1560. return r
  1561. class _fixedsizearray(_struct):
  1562. def __init__(self, TYPE, n=None, initialization=None, parent=None,
  1563. parentindex=None):
  1564. _parentable.__init__(self, TYPE)
  1565. if n is not None:
  1566. raise TypeError("%r is not variable-sized" % (TYPE,))
  1567. typ = TYPE.OF
  1568. storage = []
  1569. for i, fld in enumerate(TYPE._names):
  1570. value = typ._allocate(initialization=initialization,
  1571. parent=self, parentindex=fld)
  1572. storage.append(value)
  1573. self._items = storage
  1574. if parent is not None:
  1575. self._setparentstructure(parent, parentindex)
  1576. def getlength(self):
  1577. return self._TYPE.length
  1578. def getbounds(self):
  1579. return 0, self.getlength()
  1580. def getitem(self, index, uninitialized_ok=False):
  1581. assert 0 <= index < self.getlength()
  1582. return self._items[index]
  1583. def setitem(self, index, value):
  1584. assert 0 <= index < self.getlength()
  1585. self._items[index] = value
  1586. def __getattr__(self, name):
  1587. # obscure
  1588. if name.startswith("item"):
  1589. return self.getitem(int(name[len('item'):]))
  1590. return _struct.__getattr__(self, name)
  1591. def __setattr__(self, name, value):
  1592. if name.startswith("item"):
  1593. self.setitem(int(name[len('item'):]), value)
  1594. return
  1595. _struct.__setattr__(self, name, value)
  1596. class _array(_parentable):
  1597. _kind = "array"
  1598. __slots__ = ('items', '__arena_location__',)
  1599. def __init__(self, TYPE, n, initialization=None, parent=None,
  1600. parentindex=None):
  1601. if not is_valid_int(n):
  1602. raise TypeError("array length must be an int")
  1603. if n < 0:
  1604. raise ValueError("negative array length")
  1605. _parentable.__init__(self, TYPE)
  1606. myrange = self._check_range(n)
  1607. self.items = [TYPE.OF._allocate(initialization=initialization,
  1608. parent=self, parentindex=j)
  1609. for j in myrange]
  1610. if parent is not None:
  1611. self._setparentstructure(parent, parentindex)
  1612. def __repr__(self):
  1613. return '<%s>' % (self,)
  1614. def _check_range(self, n):
  1615. # checks that it's ok to make an array of size 'n', and returns
  1616. # range(n). Explicitly overridden by some tests.
  1617. try:
  1618. return range(n)
  1619. except OverflowError:
  1620. raise MemoryError("definitely too many items")
  1621. def _str_item(self, item):
  1622. if isinstance(item, _uninitialized):
  1623. return '#'
  1624. if isinstance(self._TYPE.OF, Struct):
  1625. of = self._TYPE.OF
  1626. if self._TYPE._anonym_struct:
  1627. return "{%s}" % item._str_fields()
  1628. else:
  1629. return "%s {%s}" % (of._name, item._str_fields())
  1630. else:
  1631. return repr(item)
  1632. def __str__(self):
  1633. items = self.items
  1634. if len(items) > 20:
  1635. items = items[:12] + items[-5:]
  1636. skipped_at = 12
  1637. else:
  1638. skipped_at = None
  1639. items = [self._str_item(item) for item in items]
  1640. if skipped_at:
  1641. items.insert(skipped_at, '(...)')
  1642. return 'array [ %s ]' % (', '.join(items),)
  1643. def getlength(self):
  1644. return len(self.items)
  1645. def shrinklength(self, newlength):
  1646. del self.items[newlength:]
  1647. def getbounds(self):
  1648. stop = len(self.items)
  1649. return 0, stop
  1650. def getitem(self, index, uninitialized_ok=False):
  1651. try:
  1652. v = self.items[index]
  1653. except IndexError:
  1654. if (index == len(self.items) and uninitialized_ok == 2 and
  1655. self._TYPE._hints.get('extra_item_after_alloc')):
  1656. # special case: reading the extra final char returns
  1657. # an uninitialized, if 'uninitialized_ok==2'
  1658. return _uninitialized(self._TYPE.OF)
  1659. raise
  1660. if isinstance(v, _uninitialized) and not uninitialized_ok:
  1661. raise UninitializedMemoryAccess("%r[%s]"%(self, index))
  1662. return v
  1663. def setitem(self, index, value):
  1664. assert typeOf(value) == self._TYPE.OF
  1665. try:
  1666. self.items[index] = value
  1667. except IndexError:
  1668. if (index == len(self.items) and value == '\x00' and
  1669. self._TYPE._hints.get('extra_item_after_alloc')):
  1670. # special case: writing NULL to the extra final char
  1671. return
  1672. raise
  1673. assert not '__dict__' in dir(_array)
  1674. assert not '__dict__' in dir(_struct)
  1675. class _subarray(_parentable): # only for direct_fieldptr()
  1676. # and direct_arrayitems()
  1677. _kind = "subarray"
  1678. _cache = {} # TYPE -> weak{ parentarray -> {subarrays} }
  1679. def __init__(self, TYPE, parent, baseoffset_or_fieldname):
  1680. _parentable.__init__(self, TYPE)
  1681. self._setparentstructure(parent, baseoffset_or_fieldname)
  1682. # Keep the parent array alive, we share the same allocation.
  1683. # Don't do it if we are inside a GC object, though -- it's someone
  1684. # else's job to keep the GC object alive
  1685. if (typeOf(top_container(parent))._gckind == 'raw' or
  1686. hasattr(top_container(parent)._storage, 'contents')): # ll2ctypes
  1687. self._keepparent = parent
  1688. def __str__(self):
  1689. parent = self._wrparent()
  1690. if parent is None:
  1691. return '_subarray at %s in already freed' % (self._parent_index,)
  1692. return '_subarray at %r in %s' % (self._parent_index,
  1693. parent._TYPE)
  1694. def __repr__(self):
  1695. parent = self._wrparent()
  1696. if parent is None:
  1697. return '<_subarray at %s in already freed>' % (self._parent_index,)
  1698. return '<_subarray at %r in %r>' % (self._parent_index,
  1699. self._parentstructure(check=False))
  1700. def getlength(self):
  1701. assert isinstance(self._TYPE, FixedSizeArray)
  1702. return self._TYPE.length
  1703. def getbounds(self):
  1704. baseoffset = self._parent_index
  1705. if isinstance(baseoffset, str):
  1706. return 0, 1 # structfield case
  1707. start, stop = self._parentstructure().getbounds()
  1708. return start - baseoffset, stop - baseoffset
  1709. def getitem(self, index, uninitialized_ok=False):
  1710. baseoffset = self._parent_index
  1711. if isinstance(baseoffset, str):
  1712. assert index == 0
  1713. fieldname = baseoffset # structfield case
  1714. return getattr(self._parentstructure(), fieldname)
  1715. else:
  1716. return self._parentstructure().getitem(baseoffset + index,
  1717. uninitialized_ok=uninitialized_ok)
  1718. def setitem(self, index, value):
  1719. baseoffset = self._parent_index
  1720. if isinstance(baseoffset, str):
  1721. assert index == 0
  1722. fieldname = baseoffset # structfield case
  1723. setattr(self._parentstructure(), fieldname, value)
  1724. else:
  1725. self._parentstructure().setitem(baseoffset + index, value)
  1726. def _makeptr(parent, baseoffset_or_fieldname, solid=False):
  1727. try:
  1728. d = _subarray._cache[parent._TYPE]
  1729. except KeyError:
  1730. d = _subarray._cache[parent._TYPE] = weakref.WeakKeyDictionary()
  1731. try:
  1732. cache = d.setdefault(parent, {})
  1733. except RuntimeError: # pointer comparison with a freed structure
  1734. _subarray._cleanup_cache()
  1735. # try again
  1736. return _subarray._makeptr(parent, baseoffset_or_fieldname, solid)
  1737. try:
  1738. subarray = cache[baseoffset_or_fieldname]
  1739. except KeyError:
  1740. PARENTTYPE = typeOf(parent)
  1741. if isinstance(baseoffset_or_fieldname, str):
  1742. # for direct_fieldptr
  1743. ITEMTYPE = getattr(PARENTTYPE, baseoffset_or_fieldname)
  1744. else:
  1745. # for direct_arrayitems
  1746. ITEMTYPE = PARENTTYPE.OF
  1747. ARRAYTYPE = FixedSizeArray(ITEMTYPE, 1)
  1748. subarray = _subarray(ARRAYTYPE, parent, baseoffset_or_fieldname)
  1749. cache[baseoffset_or_fieldname] = subarray
  1750. return _ptr(Ptr(subarray._TYPE), subarray, solid)
  1751. _makeptr = staticmethod(_makeptr)
  1752. def _getid(self):
  1753. raise NotImplementedError('_subarray._getid()')
  1754. def _cleanup_cache():
  1755. for T, d in _subarray._cache.items():
  1756. newcache = weakref.WeakKeyDictionary()
  1757. for key, value in d.items():
  1758. try:
  1759. if not key._was_freed():
  1760. newcache[key] = value
  1761. except RuntimeError:
  1762. # ignore "accessing subxxx, but already gc-ed parent"
  1763. pass
  1764. if newcache:
  1765. _subarray._cache[T] = newcache
  1766. else:
  1767. del _subarray._cache[T]
  1768. _cleanup_cache = staticmethod(_cleanup_cache)
  1769. class _arraylenref(_parentable):
  1770. """Pseudo-reference to the length field of an array.
  1771. Only used internally by llmemory to implement ArrayLengthOffset.
  1772. """
  1773. _kind = "arraylenptr"
  1774. _cache = weakref.WeakKeyDictionary() # array -> _arraylenref
  1775. def __init__(self, array):
  1776. TYPE = FixedSizeArray(Signed, 1)
  1777. _parentable.__init__(self, TYPE)
  1778. self.array = array
  1779. def getlength(self):
  1780. return 1
  1781. def getbounds(self):
  1782. return 0, 1
  1783. def getitem(self, index, uninitialized_ok=False):
  1784. assert index == 0
  1785. return self.array.getlength()
  1786. def setitem(self, index, value):
  1787. assert index == 0
  1788. if value != self.array.getlength():
  1789. if value > self.array.getlength():
  1790. raise Exception("can't grow an array in-place")
  1791. self.array.shrinklength(value)
  1792. def _makeptr(array, solid=False):
  1793. try:
  1794. lenref = _arraylenref._cache[array]
  1795. except KeyError:
  1796. lenref = _arraylenref(array)
  1797. _arraylenref._cache[array] = lenref
  1798. return _ptr(Ptr(lenref._TYPE), lenref, solid)
  1799. _makeptr = staticmethod(_makeptr)
  1800. def _getid(self):
  1801. raise NotImplementedError('_arraylenref._getid()')
  1802. class _func(_container):
  1803. def __init__(self, TYPE, **attrs):
  1804. attrs.setdefault('_TYPE', TYPE)
  1805. attrs.setdefault('_name', '?')
  1806. attrs.setdefault('_callable', None)
  1807. self.__dict__.update(attrs)
  1808. if '_callable' in attrs and hasattr(attrs['_callable'],
  1809. '_compilation_info'):
  1810. self.__dict__['compilation_info'] = \
  1811. attrs['_callable']._compilation_info
  1812. def __repr__(self):
  1813. return '<%s>' % (self,)
  1814. def __str__(self):
  1815. return "fn %s" % self._name
  1816. def __eq__(self, other):
  1817. return (self.__class__ is other.__class__ and
  1818. self.__dict__ == other.__dict__)
  1819. def __ne__(self, other):
  1820. return not (self == other)
  1821. def __hash__(self):
  1822. return hash(frozendict(self.__dict__))
  1823. def _getid(self):
  1824. if hasattr(self, 'graph'):
  1825. return id(self.graph)
  1826. elif self._callable:
  1827. return id(self._callable)
  1828. else:
  1829. return id(self)
  1830. def __setattr__(self, attr, value):
  1831. raise AttributeError("cannot change the attributes of %r" % (self,))
  1832. class _opaque(_parentable):
  1833. def __init__(self, TYPE, parent=None, parentindex=None, **attrs):
  1834. _parentable.__init__(self, TYPE)
  1835. self._name = "?"
  1836. self.__dict__.update(attrs)
  1837. if parent is not None:
  1838. self._setparentstructure(parent, parentindex)
  1839. def __repr__(self):
  1840. return '<%s>' % (self,)
  1841. def __str__(self):
  1842. return "%s %s" % (self._TYPE.__name__, self._name)
  1843. def __eq__(self, other):
  1844. if self.__class__ is not other.__class__:
  1845. return NotImplemented
  1846. if hasattr(self, 'container') and hasattr(other, 'container'):
  1847. obj1 = self._normalizedcontainer()
  1848. obj2 = other._normalizedcontainer()
  1849. return obj1 == obj2
  1850. else:
  1851. return self is other
  1852. def __ne__(self, other):
  1853. if self.__class__ is not other.__class__:
  1854. return NotImplemented
  1855. return not (self == other)
  1856. def __hash__(self):
  1857. if hasattr(self, 'container'):
  1858. obj = self.container._normalizedcontainer()
  1859. return hash(obj)
  1860. else:
  1861. return _parentable.__hash__(self)
  1862. def _normalizedcontainer(self):
  1863. # if we are an opaque containing a normal Struct/GcStruct,
  1864. # unwrap it
  1865. if hasattr(self, 'container'):
  1866. # an integer, cast to a ptr, cast to an opaque
  1867. if type(self.container) is int:
  1868. return self.container
  1869. if getattr(self.container, '_carry_around_for_tests', False):
  1870. return self.container
  1871. return self.container._normalizedcontainer()
  1872. else:
  1873. return _parentable._normalizedcontainer(self)
  1874. def malloc(T, n=None, flavor='gc', immortal=False, zero=False,
  1875. track_allocation=True, add_memory_pressure=False,
  1876. nonmovable=False):
  1877. assert flavor in ('gc', 'raw')
  1878. if zero or immortal:
  1879. initialization = 'example'
  1880. elif flavor == 'raw':
  1881. initialization = 'raw'
  1882. else:
  1883. initialization = 'malloc'
  1884. if isinstance(T, Struct):
  1885. o = _struct(T, n, initialization=initialization)
  1886. elif isinstance(T, Array):
  1887. o = _array(T, n, initialization=initialization)
  1888. elif isinstance(T, OpaqueType):
  1889. assert n is None
  1890. o = _opaque(T, initialization=initialization)
  1891. else:
  1892. raise TypeError("malloc: unmallocable type")
  1893. if flavor == 'gc' and T._gckind != 'gc' and not immortal:
  1894. raise TypeError("gc flavor malloc of a non-GC non-immortal structure")
  1895. if flavor == "raw" and not immortal and track_allocation:
  1896. leakfinder.remember_malloc(o, framedepth=2)
  1897. solid = immortal or flavor == 'raw'
  1898. return _ptr(Ptr(T), o, solid)
  1899. @analyzer_for(malloc)
  1900. def ann_malloc(s_T, s_n=None, s_flavor=None, s_zero=None,
  1901. s_track_allocation=None, s_add_memory_pressure=None,
  1902. s_nonmovable=None):
  1903. assert (s_n is None or s_n.knowntype == int
  1904. or issubclass(s_n.knowntype, base_int))
  1905. assert s_T.is_constant()
  1906. if s_n is not None:
  1907. n = 1
  1908. else:
  1909. n = None
  1910. if s_zero:
  1911. assert s_zero.is_constant()
  1912. if s_flavor is None:
  1913. p = malloc(s_T.const, n)
  1914. r = SomePtr(typeOf(p))
  1915. else:
  1916. assert s_flavor.is_constant()
  1917. assert s_track_allocation is None or s_track_allocation.is_constant()
  1918. assert (s_add_memory_pressure is None or
  1919. s_add_memory_pressure.is_constant())
  1920. assert s_nonmovable is None or s_nonmovable.is_constant()
  1921. # not sure how to call malloc() for the example 'p' in the
  1922. # presence of s_extraargs
  1923. r = SomePtr(Ptr(s_T.const))
  1924. return r
  1925. def free(p, flavor, track_allocation=True):
  1926. if flavor.startswith('gc'):
  1927. raise TypeError("gc flavor free")
  1928. T = typeOf(p)
  1929. if not isinstance(T, Ptr) or p._togckind() != 'raw':
  1930. raise TypeError("free(): only for pointers to non-gc containers")
  1931. if track_allocation:
  1932. leakfinder.remember_free(p._obj0)
  1933. p._obj0._free()
  1934. @analyzer_for(free)
  1935. def ann_free(s_p, s_flavor, s_track_allocation=None):
  1936. assert s_flavor.is_constant()
  1937. assert s_track_allocation is None or s_track_allocation.is_constant()
  1938. # same problem as in malloc(): some flavors are not easy to
  1939. # malloc-by-example
  1940. #T = s_p.ll_ptrtype.TO
  1941. #p = malloc(T, flavor=s_flavor.const)
  1942. #free(p, flavor=s_flavor.const)
  1943. def render_immortal(p, track_allocation=True):
  1944. T = typeOf(p)
  1945. if not isinstance(T, Ptr) or p._togckind() != 'raw':
  1946. raise TypeError("free(): only for pointers to non-gc containers")
  1947. if track_allocation:
  1948. leakfinder.remember_free(p._obj0)
  1949. @analyzer_for(render_immortal)
  1950. def ann_render_immortal(s_p, s_track_allocation=None):
  1951. assert s_track_allocation is None or s_track_allocation.is_constant()
  1952. def _make_scoped_allocator(T, zero):
  1953. class ScopedAlloc:
  1954. def __init__(self, n=None):
  1955. if n is None:
  1956. self.buf = malloc(T, flavor='raw', zero=zero)
  1957. else:
  1958. self.buf = malloc(T, n, flavor='raw', zero=zero)
  1959. def __enter__(self):
  1960. return self.buf
  1961. def __exit__(self, *args):
  1962. free(self.buf, flavor='raw')
  1963. ScopedAlloc.__name__ = 'ScopedAlloc_%s' % (T,)
  1964. return ScopedAlloc
  1965. _make_scoped_allocator._annspecialcase_ = 'specialize:memo'
  1966. def scoped_alloc(T, n=None, zero=False):
  1967. """Returns a context manager which handles allocation and
  1968. deallocation of temporary memory. Use it in a with statement::
  1969. with scoped_alloc(Array(Signed), 1) as array:
  1970. ...use array...
  1971. ...it's freed now.
  1972. """
  1973. return _make_scoped_allocator(T, zero)(n=n)
  1974. scoped_alloc._annspecialcase_ = 'specialize:arg(0, 2)'
  1975. def functionptr(TYPE, name, **attrs):
  1976. if not isinstance(TYPE, FuncType):
  1977. raise TypeError("functionptr() for FuncTypes only")
  1978. try:
  1979. hash(tuple(attrs.items()))
  1980. except TypeError:
  1981. raise TypeError("'%r' must be hashable"%attrs)
  1982. o = _func(TYPE, _name=name, **attrs)
  1983. return _ptr(Ptr(TYPE), o)
  1984. def _getconcretetype(v):
  1985. return v.concretetype
  1986. def getfunctionptr(graph, getconcretetype=_getconcretetype):
  1987. """Return callable given a Python function."""
  1988. llinputs = [getconcretetype(v) for v in graph.getargs()]
  1989. lloutput = getconcretetype(graph.getreturnvar())
  1990. FT = FuncType(llinputs, lloutput)
  1991. name = graph.name
  1992. if hasattr(graph, 'func') and callable(graph.func):
  1993. # the Python function object can have _llfnobjattrs_, specifying
  1994. # attributes that are forced upon the functionptr(). The idea
  1995. # for not passing these extra attributes as arguments to
  1996. # getcallable() itself is that multiple calls to getcallable()
  1997. # for the same graph should return equal functionptr() objects.
  1998. if hasattr(graph.func, '_llfnobjattrs_'):
  1999. fnobjattrs = graph.func._llfnobjattrs_.copy()
  2000. # can specify a '_name', but use graph.name by default
  2001. name = fnobjattrs.pop('_name', name)
  2002. else:
  2003. fnobjattrs = {}
  2004. # _callable is normally graph.func, but can be overridden:
  2005. # see fakeimpl in extfunc.py
  2006. _callable = fnobjattrs.pop('_callable', graph.func)
  2007. return functionptr(FT, name, graph=graph, _callable=_callable,
  2008. **fnobjattrs)
  2009. else:
  2010. return functionptr(FT, name, graph=graph)
  2011. def nullptr(T):
  2012. return Ptr(T)._defl()
  2013. @analyzer_for(nullptr)
  2014. def ann_nullptr(T):
  2015. assert T.is_constant()
  2016. p = nullptr(T.const)
  2017. return immutablevalue(p)
  2018. def opaqueptr(TYPE, name, **attrs):
  2019. if not isinstance(TYPE, OpaqueType):
  2020. raise TypeError("opaqueptr() for OpaqueTypes only")
  2021. o = _opaque(TYPE, _name=name, **attrs)
  2022. return _ptr(Ptr(TYPE), o, solid=True)
  2023. def cast_ptr_to_int(ptr):
  2024. return ptr._cast_to_int()
  2025. @analyzer_for(cast_ptr_to_int)
  2026. def ann_cast_ptr_to_int(s_ptr): # xxx
  2027. return SomeInteger()
  2028. def cast_int_to_ptr(PTRTYPE, oddint):
  2029. if oddint == 0:
  2030. return nullptr(PTRTYPE.TO)
  2031. if not (oddint & 1):
  2032. raise ValueError("only odd integers can be cast back to ptr")
  2033. return _ptr(PTRTYPE, oddint, solid=True)
  2034. @analyzer_for(cast_int_to_ptr)
  2035. def ann_cast_int_to_ptr(PtrT, s_int):
  2036. assert PtrT.is_constant()
  2037. return SomePtr(ll_ptrtype=PtrT.const)
  2038. def attachRuntimeTypeInfo(GCSTRUCT, funcptr=None, destrptr=None):
  2039. if not isinstance(GCSTRUCT, RttiStruct):
  2040. raise TypeError("expected a RttiStruct: %s" % GCSTRUCT)
  2041. GCSTRUCT._attach_runtime_type_info_funcptr(funcptr, destrptr)
  2042. return _ptr(Ptr(RuntimeTypeInfo), GCSTRUCT._runtime_type_info)
  2043. def getRuntimeTypeInfo(GCSTRUCT):
  2044. if not isinstance(GCSTRUCT, RttiStruct):
  2045. raise TypeError("expected a RttiStruct: %s" % GCSTRUCT)
  2046. if GCSTRUCT._runtime_type_info is None:
  2047. raise ValueError("no attached runtime type info for GcStruct %s" %
  2048. GCSTRUCT._name)
  2049. return _ptr(Ptr(RuntimeTypeInfo), GCSTRUCT._runtime_type_info)
  2050. @analyzer_for(getRuntimeTypeInfo)
  2051. def ann_getRuntimeTypeInfo(T):
  2052. assert T.is_constant()
  2053. return immutablevalue(getRuntimeTypeInfo(T.const))
  2054. def runtime_type_info(p):
  2055. T = typeOf(p)
  2056. if not isinstance(T, Ptr) or not isinstance(T.TO, RttiStruct):
  2057. raise TypeError("runtime_type_info on non-RttiStruct pointer: %s" % p)
  2058. struct = p._obj
  2059. top_parent = top_container(struct)
  2060. result = getRuntimeTypeInfo(top_parent._TYPE)
  2061. static_info = getRuntimeTypeInfo(T.TO)
  2062. query_funcptr = getattr(static_info._obj, 'query_funcptr', None)
  2063. if query_funcptr is not None:
  2064. T = typeOf(query_funcptr).TO.ARGS[0]
  2065. result2 = query_funcptr(cast_pointer(T, p))
  2066. if result != result2:
  2067. raise RuntimeError("runtime type-info function for %s:\n"
  2068. " returned: %s,\n"
  2069. "should have been: %s" % (p, result2, result))
  2070. return result
  2071. @analyzer_for(runtime_type_info)
  2072. def ann_runtime_type_info(s_p):
  2073. assert isinstance(s_p, SomePtr), \
  2074. "runtime_type_info of non-pointer: %r" % s_p
  2075. return SomePtr(typeOf(runtime_type_info(s_p.ll_ptrtype._example())))
  2076. def identityhash(p):
  2077. """Returns the lltype-level hash of the given GcStruct.
  2078. Not for NULL. See rlib.objectmodel.compute_identity_hash() for more
  2079. information about the RPython-level meaning of this.
  2080. """
  2081. assert p
  2082. return p._identityhash()
  2083. @analyzer_for(identityhash)
  2084. def ann_identityhash(s_obj):
  2085. assert isinstance(s_obj, SomePtr)
  2086. return SomeInteger()
  2087. def identityhash_nocache(p):
  2088. """Version of identityhash() to use from backends that don't care about
  2089. caching."""
  2090. assert p
  2091. return p._identityhash(cache=False)
  2092. def init_identity_hash(p, value):
  2093. """For a prebuilt object p, initialize its hash value to 'value'."""
  2094. assert isinstance(typeOf(p), Ptr)
  2095. p = normalizeptr(p)
  2096. if not p:
  2097. raise ValueError("cannot change hash(NULL)!")
  2098. if hasattr(p._obj, '_hash_cache_'):
  2099. raise ValueError("the hash of %r was already computed" % (p,))
  2100. if typeOf(p).TO._is_varsize():
  2101. raise ValueError("init_identity_hash(): not for varsized types")
  2102. p._obj._hash_cache_ = intmask(value)
  2103. def isCompatibleType(TYPE1, TYPE2):
  2104. return TYPE1._is_compatible(TYPE2)
  2105. def enforce(TYPE, value):
  2106. return TYPE._enforce(value)
  2107. # mark type ADT methods
  2108. def typeMethod(func):
  2109. func._type_method = True
  2110. return func
  2111. class staticAdtMethod(object):
  2112. # Like staticmethod(), but for ADT methods. The difference is only
  2113. # that this version compares and hashes correctly, unlike CPython's.
  2114. def __init__(self, obj):
  2115. self.obj = obj
  2116. def __get__(self, inst, typ=None):
  2117. return self.obj
  2118. def __hash__(self):
  2119. return hash(self.obj)
  2120. def __eq__(self, other):
  2121. if not isinstance(other, staticAdtMethod):
  2122. return NotImplemented
  2123. else:
  2124. return self.obj == other.obj
  2125. def __ne__(self, other):
  2126. if not isinstance(other, staticAdtMethod):
  2127. return NotImplemented
  2128. else:
  2129. return self.obj != other.obj
  2130. def dissect_ll_instance(v, t=None, memo=None):
  2131. if memo is None:
  2132. memo = identity_dict()
  2133. if v in memo:
  2134. return
  2135. memo[v] = True
  2136. if t is None:
  2137. t = typeOf(v)
  2138. yield t, v
  2139. if isinstance(t, Ptr):
  2140. if v._obj:
  2141. for i in dissect_ll_instance(v._obj, t.TO, memo):
  2142. yield i
  2143. elif isinstance(t, Struct):
  2144. parent = v._parentstructure()
  2145. if parent:
  2146. for i in dissect_ll_instance(parent, typeOf(parent), memo):
  2147. yield i
  2148. for n in t._flds:
  2149. f = getattr(t, n)
  2150. for i in dissect_ll_instance(getattr(v, n), t._flds[n], memo):
  2151. yield i
  2152. elif isinstance(t, Array):
  2153. for item in v.items:
  2154. for i in dissect_ll_instance(item, t.OF, memo):
  2155. yield i