PageRenderTime 51ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/rpython/rtyper/rclass.py

https://bitbucket.org/pypy/pypy/
Python | 1195 lines | 1045 code | 71 blank | 79 comment | 76 complexity | 71c650154ad42039cb015d694e62ed76 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import sys
  2. import types
  3. from rpython.flowspace.model import Constant
  4. from rpython.annotator import description, model as annmodel
  5. from rpython.rlib.objectmodel import UnboxedValue
  6. from rpython.tool.pairtype import pairtype, pair
  7. from rpython.tool.identity_dict import identity_dict
  8. from rpython.tool.flattenrec import FlattenRecursion
  9. from rpython.rtyper.extregistry import ExtRegistryEntry
  10. from rpython.rtyper.error import TyperError
  11. from rpython.rtyper.lltypesystem import lltype
  12. from rpython.rtyper.lltypesystem.lltype import (
  13. Ptr, Struct, GcStruct, malloc, cast_pointer, castable, nullptr,
  14. RuntimeTypeInfo, getRuntimeTypeInfo, typeOf, Void, FuncType, Bool, Signed,
  15. functionptr, attachRuntimeTypeInfo)
  16. from rpython.rtyper.lltypesystem.lloperation import llop
  17. from rpython.rtyper.llannotation import SomePtr
  18. from rpython.rtyper.lltypesystem import rstr
  19. from rpython.rtyper.rmodel import (
  20. Repr, getgcflavor, inputconst, warning, mangle)
  21. class FieldListAccessor(object):
  22. def initialize(self, TYPE, fields):
  23. assert type(fields) is dict
  24. self.TYPE = TYPE
  25. self.fields = fields
  26. for x in fields.itervalues():
  27. assert isinstance(x, ImmutableRanking)
  28. def all_immutable_fields(self):
  29. result = set()
  30. for key, value in self.fields.iteritems():
  31. if value in (IR_IMMUTABLE, IR_IMMUTABLE_ARRAY):
  32. result.add(key)
  33. return result
  34. def __repr__(self):
  35. return '<FieldListAccessor for %s>' % getattr(self, 'TYPE', '?')
  36. class ImmutableRanking(object):
  37. def __init__(self, name, is_immutable):
  38. self.name = name
  39. self.is_immutable = is_immutable
  40. def __nonzero__(self):
  41. return self.is_immutable
  42. def __repr__(self):
  43. return '<%s>' % self.name
  44. IR_MUTABLE = ImmutableRanking('mutable', False)
  45. IR_IMMUTABLE = ImmutableRanking('immutable', True)
  46. IR_IMMUTABLE_ARRAY = ImmutableRanking('immutable_array', True)
  47. IR_QUASIIMMUTABLE = ImmutableRanking('quasiimmutable', False)
  48. IR_QUASIIMMUTABLE_ARRAY = ImmutableRanking('quasiimmutable_array', False)
  49. class ImmutableConflictError(Exception):
  50. """Raised when the _immutable_ or _immutable_fields_ hints are
  51. not consistent across a class hierarchy."""
  52. def getclassrepr(rtyper, classdef):
  53. if classdef is None:
  54. return rtyper.rootclass_repr
  55. result = classdef.repr
  56. if result is None:
  57. result = classdef.repr = ClassRepr(rtyper, classdef)
  58. rtyper.add_pendingsetup(result)
  59. return result
  60. def getinstancerepr(rtyper, classdef, default_flavor='gc'):
  61. if classdef is None:
  62. flavor = default_flavor
  63. else:
  64. flavor = getgcflavor(classdef)
  65. try:
  66. result = rtyper.instance_reprs[classdef, flavor]
  67. except KeyError:
  68. result = buildinstancerepr(rtyper, classdef, gcflavor=flavor)
  69. rtyper.instance_reprs[classdef, flavor] = result
  70. rtyper.add_pendingsetup(result)
  71. return result
  72. def buildinstancerepr(rtyper, classdef, gcflavor='gc'):
  73. from rpython.rtyper.rvirtualizable import VirtualizableInstanceRepr
  74. if classdef is None:
  75. unboxed = []
  76. virtualizable = False
  77. else:
  78. unboxed = [subdef for subdef in classdef.getallsubdefs() if
  79. subdef.classdesc.pyobj is not None and
  80. issubclass(subdef.classdesc.pyobj, UnboxedValue)]
  81. virtualizable = classdef.classdesc.get_param('_virtualizable_', False)
  82. config = rtyper.annotator.translator.config
  83. usetagging = len(unboxed) != 0 and config.translation.taggedpointers
  84. if virtualizable:
  85. assert len(unboxed) == 0
  86. assert gcflavor == 'gc'
  87. return VirtualizableInstanceRepr(rtyper, classdef)
  88. elif usetagging:
  89. # the UnboxedValue class and its parent classes need a
  90. # special repr for their instances
  91. if len(unboxed) != 1:
  92. raise TyperError("%r has several UnboxedValue subclasses" % (
  93. classdef,))
  94. assert gcflavor == 'gc'
  95. from rpython.rtyper.lltypesystem import rtagged
  96. return rtagged.TaggedInstanceRepr(rtyper, classdef, unboxed[0])
  97. else:
  98. return InstanceRepr(rtyper, classdef, gcflavor)
  99. class MissingRTypeAttribute(TyperError):
  100. pass
  101. # ____________________________________________________________
  102. #
  103. # There is one "vtable" per user class, with the following structure:
  104. # A root class "object" has:
  105. #
  106. # struct object_vtable {
  107. # // struct object_vtable* parenttypeptr; not used any more
  108. # RuntimeTypeInfo * rtti;
  109. # Signed subclassrange_min; //this is also the id of the class itself
  110. # Signed subclassrange_max;
  111. # RPyString * name;
  112. # struct object * instantiate();
  113. # }
  114. #
  115. # Every other class X, with parent Y, has the structure:
  116. #
  117. # struct vtable_X {
  118. # struct vtable_Y super; // inlined
  119. # ... // extra class attributes
  120. # }
  121. # The type of the instances is:
  122. #
  123. # struct object { // for the root class
  124. # struct object_vtable* typeptr;
  125. # }
  126. #
  127. # struct X {
  128. # struct Y super; // inlined
  129. # ... // extra instance attributes
  130. # }
  131. #
  132. # there's also a nongcobject
  133. OBJECT_VTABLE = lltype.ForwardReference()
  134. CLASSTYPE = Ptr(OBJECT_VTABLE)
  135. OBJECT = GcStruct('object', ('typeptr', CLASSTYPE),
  136. hints={'immutable': True, 'shouldntbenull': True,
  137. 'typeptr': True},
  138. rtti=True)
  139. OBJECTPTR = Ptr(OBJECT)
  140. OBJECT_VTABLE.become(Struct('object_vtable',
  141. #('parenttypeptr', CLASSTYPE),
  142. ('subclassrange_min', Signed),
  143. ('subclassrange_max', Signed),
  144. ('rtti', Ptr(RuntimeTypeInfo)),
  145. ('name', Ptr(rstr.STR)),
  146. ('hash', Signed),
  147. ('instantiate', Ptr(FuncType([], OBJECTPTR))),
  148. hints={'immutable': True}))
  149. # non-gc case
  150. NONGCOBJECT = Struct('nongcobject', ('typeptr', CLASSTYPE))
  151. NONGCOBJECTPTR = Ptr(NONGCOBJECT)
  152. OBJECT_BY_FLAVOR = {'gc': OBJECT, 'raw': NONGCOBJECT}
  153. LLFLAVOR = {'gc': 'gc', 'raw': 'raw', 'stack': 'raw'}
  154. def cast_vtable_to_typeptr(vtable):
  155. while typeOf(vtable).TO != OBJECT_VTABLE:
  156. vtable = vtable.super
  157. return vtable
  158. def alloc_array_name(name):
  159. return rstr.string_repr.convert_const(name)
  160. class ClassRepr(Repr):
  161. def __init__(self, rtyper, classdef):
  162. self.rtyper = rtyper
  163. self.classdef = classdef
  164. self.vtable_type = lltype.ForwardReference()
  165. self.lowleveltype = Ptr(self.vtable_type)
  166. def __repr__(self):
  167. if self.classdef is None:
  168. clsname = 'object'
  169. else:
  170. clsname = self.classdef.name
  171. return '<ClassRepr for %s>' % (clsname,)
  172. def compact_repr(self):
  173. if self.classdef is None:
  174. clsname = 'object'
  175. else:
  176. clsname = self.classdef.name
  177. return 'ClassR %s' % (clsname,)
  178. def convert_desc(self, desc):
  179. subclassdef = desc.getuniqueclassdef()
  180. if self.classdef is not None:
  181. if self.classdef.commonbase(subclassdef) != self.classdef:
  182. raise TyperError("not a subclass of %r: %r" % (
  183. self.classdef.name, desc))
  184. r_subclass = getclassrepr(self.rtyper, subclassdef)
  185. return r_subclass.getruntime(self.lowleveltype)
  186. def convert_const(self, value):
  187. if not isinstance(value, (type, types.ClassType)):
  188. raise TyperError("not a class: %r" % (value,))
  189. bk = self.rtyper.annotator.bookkeeper
  190. return self.convert_desc(bk.getdesc(value))
  191. def prepare_method(self, s_value):
  192. # special-casing for methods:
  193. # if s_value is SomePBC([MethodDescs...])
  194. # return a PBC representing the underlying functions
  195. if (isinstance(s_value, annmodel.SomePBC) and
  196. s_value.getKind() == description.MethodDesc):
  197. s_value = self.classdef.lookup_filter(s_value)
  198. funcdescs = [mdesc.funcdesc for mdesc in s_value.descriptions]
  199. return annmodel.SomePBC(funcdescs)
  200. return None # not a method
  201. def get_ll_eq_function(self):
  202. return None
  203. def _setup_repr(self):
  204. # NOTE: don't store mutable objects like the dicts below on 'self'
  205. # before they are fully built, to avoid strange bugs in case
  206. # of recursion where other code would uses these
  207. # partially-initialized dicts.
  208. clsfields = {}
  209. pbcfields = {}
  210. allmethods = {}
  211. # class attributes
  212. llfields = []
  213. for name, attrdef in self.classdef.attrs.items():
  214. if attrdef.readonly:
  215. s_value = attrdef.s_value
  216. s_unboundmethod = self.prepare_method(s_value)
  217. if s_unboundmethod is not None:
  218. allmethods[name] = True
  219. s_value = s_unboundmethod
  220. r = self.rtyper.getrepr(s_value)
  221. mangled_name = 'cls_' + name
  222. clsfields[name] = mangled_name, r
  223. llfields.append((mangled_name, r.lowleveltype))
  224. # attributes showing up in getattrs done on the class as a PBC
  225. extra_access_sets = self.classdef.extra_access_sets
  226. for access_set, (attr, counter) in extra_access_sets.items():
  227. r = self.rtyper.getrepr(access_set.s_value)
  228. mangled_name = mangle('pbc%d' % counter, attr)
  229. pbcfields[access_set, attr] = mangled_name, r
  230. llfields.append((mangled_name, r.lowleveltype))
  231. llfields.sort()
  232. llfields.sort(key=attr_reverse_size)
  233. #
  234. self.rbase = getclassrepr(self.rtyper, self.classdef.basedef)
  235. self.rbase.setup()
  236. kwds = {'hints': {'immutable': True}}
  237. vtable_type = Struct('%s_vtable' % self.classdef.name,
  238. ('super', self.rbase.vtable_type),
  239. *llfields, **kwds)
  240. self.vtable_type.become(vtable_type)
  241. allmethods.update(self.rbase.allmethods)
  242. self.clsfields = clsfields
  243. self.pbcfields = pbcfields
  244. self.allmethods = allmethods
  245. self.vtable = None
  246. def getvtable(self):
  247. """Return a ptr to the vtable of this type."""
  248. if self.vtable is None:
  249. self.init_vtable()
  250. return cast_vtable_to_typeptr(self.vtable)
  251. def getruntime(self, expected_type):
  252. assert expected_type == CLASSTYPE
  253. return self.getvtable()
  254. def init_vtable(self):
  255. """Create the actual vtable"""
  256. self.vtable = malloc(self.vtable_type, immortal=True)
  257. vtable_part = self.vtable
  258. r_parentcls = self
  259. while r_parentcls.classdef is not None:
  260. self.setup_vtable(vtable_part, r_parentcls)
  261. vtable_part = vtable_part.super
  262. r_parentcls = r_parentcls.rbase
  263. self.fill_vtable_root(vtable_part)
  264. def setup_vtable(self, vtable, r_parentcls):
  265. """Initialize the vtable portion corresponding to 'r_parentcls'."""
  266. # setup class attributes: for each attribute name at the level
  267. # of 'r_parentcls', look up its value in the class
  268. def assign(mangled_name, value):
  269. if value is None:
  270. llvalue = r.special_uninitialized_value()
  271. if llvalue is None:
  272. return
  273. else:
  274. if (isinstance(value, Constant) and
  275. isinstance(value.value, staticmethod)):
  276. value = Constant(value.value.__get__(42)) # staticmethod => bare function
  277. llvalue = r.convert_desc_or_const(value)
  278. setattr(vtable, mangled_name, llvalue)
  279. for fldname in r_parentcls.clsfields:
  280. mangled_name, r = r_parentcls.clsfields[fldname]
  281. if r.lowleveltype is Void:
  282. continue
  283. value = self.classdef.classdesc.read_attribute(fldname, None)
  284. assign(mangled_name, value)
  285. # extra PBC attributes
  286. for (access_set, attr), (mangled_name, r) in r_parentcls.pbcfields.items():
  287. if self.classdef.classdesc not in access_set.descs:
  288. continue # only for the classes in the same pbc access set
  289. if r.lowleveltype is Void:
  290. continue
  291. attrvalue = self.classdef.classdesc.read_attribute(attr, None)
  292. assign(mangled_name, attrvalue)
  293. def fill_vtable_root(self, vtable):
  294. """Initialize the head of the vtable."""
  295. vtable.hash = hash(self)
  296. # initialize the 'subclassrange_*' and 'name' fields
  297. if self.classdef is not None:
  298. #vtable.parenttypeptr = self.rbase.getvtable()
  299. vtable.subclassrange_min = self.classdef.minid
  300. vtable.subclassrange_max = self.classdef.maxid
  301. else: # for the root class
  302. vtable.subclassrange_min = 0
  303. vtable.subclassrange_max = sys.maxint
  304. rinstance = getinstancerepr(self.rtyper, self.classdef)
  305. rinstance.setup()
  306. if rinstance.gcflavor == 'gc':
  307. vtable.rtti = getRuntimeTypeInfo(rinstance.object_type)
  308. if self.classdef is None:
  309. name = 'object'
  310. else:
  311. name = self.classdef.shortname
  312. vtable.name = alloc_array_name(name)
  313. if hasattr(self.classdef, 'my_instantiate_graph'):
  314. graph = self.classdef.my_instantiate_graph
  315. vtable.instantiate = self.rtyper.getcallable(graph)
  316. #else: the classdef was created recently, so no instantiate()
  317. # could reach it
  318. def fromtypeptr(self, vcls, llops):
  319. """Return the type pointer cast to self's vtable type."""
  320. self.setup()
  321. castable(self.lowleveltype, vcls.concretetype) # sanity check
  322. return llops.genop('cast_pointer', [vcls],
  323. resulttype=self.lowleveltype)
  324. fromclasstype = fromtypeptr
  325. def getclsfield(self, vcls, attr, llops):
  326. """Read the given attribute of 'vcls'."""
  327. if attr in self.clsfields:
  328. mangled_name, r = self.clsfields[attr]
  329. v_vtable = self.fromtypeptr(vcls, llops)
  330. cname = inputconst(Void, mangled_name)
  331. return llops.genop('getfield', [v_vtable, cname], resulttype=r)
  332. else:
  333. if self.classdef is None:
  334. raise MissingRTypeAttribute(attr)
  335. return self.rbase.getclsfield(vcls, attr, llops)
  336. def setclsfield(self, vcls, attr, vvalue, llops):
  337. """Write the given attribute of 'vcls'."""
  338. if attr in self.clsfields:
  339. mangled_name, r = self.clsfields[attr]
  340. v_vtable = self.fromtypeptr(vcls, llops)
  341. cname = inputconst(Void, mangled_name)
  342. llops.genop('setfield', [v_vtable, cname, vvalue])
  343. else:
  344. if self.classdef is None:
  345. raise MissingRTypeAttribute(attr)
  346. self.rbase.setclsfield(vcls, attr, vvalue, llops)
  347. def getpbcfield(self, vcls, access_set, attr, llops):
  348. if (access_set, attr) not in self.pbcfields:
  349. raise TyperError("internal error: missing PBC field")
  350. mangled_name, r = self.pbcfields[access_set, attr]
  351. v_vtable = self.fromtypeptr(vcls, llops)
  352. cname = inputconst(Void, mangled_name)
  353. return llops.genop('getfield', [v_vtable, cname], resulttype=r)
  354. def rtype_issubtype(self, hop):
  355. class_repr = get_type_repr(self.rtyper)
  356. v_cls1, v_cls2 = hop.inputargs(class_repr, class_repr)
  357. if isinstance(v_cls2, Constant):
  358. cls2 = v_cls2.value
  359. minid = hop.inputconst(Signed, cls2.subclassrange_min)
  360. maxid = hop.inputconst(Signed, cls2.subclassrange_max)
  361. return hop.gendirectcall(ll_issubclass_const, v_cls1, minid,
  362. maxid)
  363. else:
  364. v_cls1, v_cls2 = hop.inputargs(class_repr, class_repr)
  365. return hop.gendirectcall(ll_issubclass, v_cls1, v_cls2)
  366. class RootClassRepr(ClassRepr):
  367. """ClassRepr for the root of the class hierarchy"""
  368. classdef = None
  369. def __init__(self, rtyper):
  370. self.rtyper = rtyper
  371. self.vtable_type = OBJECT_VTABLE
  372. self.lowleveltype = Ptr(self.vtable_type)
  373. def _setup_repr(self):
  374. self.clsfields = {}
  375. self.pbcfields = {}
  376. self.allmethods = {}
  377. self.vtable = None
  378. def init_vtable(self):
  379. self.vtable = malloc(self.vtable_type, immortal=True)
  380. self.fill_vtable_root(self.vtable)
  381. def get_type_repr(rtyper):
  382. return rtyper.rootclass_repr
  383. # ____________________________________________________________
  384. class __extend__(annmodel.SomeInstance):
  385. def rtyper_makerepr(self, rtyper):
  386. return getinstancerepr(rtyper, self.classdef)
  387. def rtyper_makekey(self):
  388. return self.__class__, self.classdef
  389. class __extend__(annmodel.SomeException):
  390. def rtyper_makerepr(self, rtyper):
  391. return self.as_SomeInstance().rtyper_makerepr(rtyper)
  392. def rtyper_makekey(self):
  393. return self.__class__, frozenset(self.classdefs)
  394. class __extend__(annmodel.SomeType):
  395. def rtyper_makerepr(self, rtyper):
  396. return get_type_repr(rtyper)
  397. def rtyper_makekey(self):
  398. return self.__class__,
  399. class InstanceRepr(Repr):
  400. def __init__(self, rtyper, classdef, gcflavor='gc'):
  401. self.rtyper = rtyper
  402. self.classdef = classdef
  403. if classdef is None:
  404. self.object_type = OBJECT_BY_FLAVOR[LLFLAVOR[gcflavor]]
  405. else:
  406. ForwardRef = lltype.FORWARDREF_BY_FLAVOR[LLFLAVOR[gcflavor]]
  407. self.object_type = ForwardRef()
  408. self.iprebuiltinstances = identity_dict()
  409. self.lowleveltype = Ptr(self.object_type)
  410. self.gcflavor = gcflavor
  411. def _setup_repr(self, llfields=None, hints=None, adtmeths=None):
  412. # NOTE: don't store mutable objects like the dicts below on 'self'
  413. # before they are fully built, to avoid strange bugs in case
  414. # of recursion where other code would uses these
  415. # partially-initialized dicts.
  416. if self.classdef is None:
  417. self.immutable_field_set = set()
  418. self.rclass = getclassrepr(self.rtyper, self.classdef)
  419. fields = {}
  420. allinstancefields = {}
  421. if self.classdef is None:
  422. fields['__class__'] = 'typeptr', get_type_repr(self.rtyper)
  423. else:
  424. # instance attributes
  425. attrs = self.classdef.attrs.items()
  426. attrs.sort()
  427. myllfields = []
  428. for name, attrdef in attrs:
  429. if not attrdef.readonly:
  430. r = self.rtyper.getrepr(attrdef.s_value)
  431. mangled_name = 'inst_' + name
  432. fields[name] = mangled_name, r
  433. myllfields.append((mangled_name, r.lowleveltype))
  434. myllfields.sort(key=attr_reverse_size)
  435. if llfields is None:
  436. llfields = myllfields
  437. else:
  438. llfields = llfields + myllfields
  439. self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef,
  440. self.gcflavor)
  441. self.rbase.setup()
  442. MkStruct = lltype.STRUCT_BY_FLAVOR[LLFLAVOR[self.gcflavor]]
  443. if adtmeths is None:
  444. adtmeths = {}
  445. if hints is None:
  446. hints = {}
  447. hints = self._check_for_immutable_hints(hints)
  448. kwds = {}
  449. if self.gcflavor == 'gc':
  450. kwds['rtti'] = True
  451. for name, attrdef in attrs:
  452. if not attrdef.readonly and self.is_quasi_immutable(name):
  453. llfields.append(('mutate_' + name, OBJECTPTR))
  454. object_type = MkStruct(self.classdef.name,
  455. ('super', self.rbase.object_type),
  456. hints=hints,
  457. adtmeths=adtmeths,
  458. *llfields,
  459. **kwds)
  460. self.object_type.become(object_type)
  461. allinstancefields.update(self.rbase.allinstancefields)
  462. allinstancefields.update(fields)
  463. self.fields = fields
  464. self.allinstancefields = allinstancefields
  465. def _check_for_immutable_hints(self, hints):
  466. hints = hints.copy()
  467. classdesc = self.classdef.classdesc
  468. immut = classdesc.get_param('_immutable_', inherit=False)
  469. if immut is None:
  470. if classdesc.get_param('_immutable_', inherit=True):
  471. raise ImmutableConflictError(
  472. "class %r inherits from its parent _immutable_=True, "
  473. "so it should also declare _immutable_=True" % (
  474. self.classdef,))
  475. elif immut is not True:
  476. raise TyperError(
  477. "class %r: _immutable_ = something else than True" % (
  478. self.classdef,))
  479. else:
  480. hints['immutable'] = True
  481. self.immutable_field_set = classdesc.immutable_fields
  482. if (classdesc.immutable_fields or
  483. 'immutable_fields' in self.rbase.object_type._hints):
  484. accessor = FieldListAccessor()
  485. hints['immutable_fields'] = accessor
  486. return hints
  487. def __repr__(self):
  488. if self.classdef is None:
  489. clsname = 'object'
  490. else:
  491. clsname = self.classdef.name
  492. return '<InstanceRepr for %s>' % (clsname,)
  493. def compact_repr(self):
  494. if self.classdef is None:
  495. clsname = 'object'
  496. else:
  497. clsname = self.classdef.name
  498. return 'InstanceR %s' % (clsname,)
  499. def _setup_repr_final(self):
  500. self._setup_immutable_field_list()
  501. self._check_for_immutable_conflicts()
  502. if self.gcflavor == 'gc':
  503. if (self.classdef is not None and
  504. self.classdef.classdesc.lookup('__del__') is not None):
  505. s_func = self.classdef.classdesc.s_read_attribute('__del__')
  506. source_desc = self.classdef.classdesc.lookup('__del__')
  507. source_classdef = source_desc.getclassdef(None)
  508. source_repr = getinstancerepr(self.rtyper, source_classdef)
  509. assert len(s_func.descriptions) == 1
  510. funcdesc, = s_func.descriptions
  511. graph = funcdesc.getuniquegraph()
  512. self.check_graph_of_del_does_not_call_too_much(self.rtyper,
  513. graph)
  514. FUNCTYPE = FuncType([Ptr(source_repr.object_type)], Void)
  515. destrptr = functionptr(FUNCTYPE, graph.name,
  516. graph=graph,
  517. _callable=graph.func)
  518. else:
  519. destrptr = None
  520. self.rtyper.call_all_setups() # compute ForwardReferences now
  521. args_s = [SomePtr(Ptr(OBJECT))]
  522. graph = self.rtyper.annotate_helper(ll_runtime_type_info, args_s)
  523. s = self.rtyper.annotation(graph.getreturnvar())
  524. if (not isinstance(s, SomePtr) or
  525. s.ll_ptrtype != Ptr(RuntimeTypeInfo)):
  526. raise TyperError("runtime type info function returns %r, "
  527. "expected Ptr(RuntimeTypeInfo)" % (s))
  528. funcptr = self.rtyper.getcallable(graph)
  529. attachRuntimeTypeInfo(self.object_type, funcptr, destrptr)
  530. vtable = self.rclass.getvtable()
  531. self.rtyper.set_type_for_typeptr(vtable, self.lowleveltype.TO)
  532. def _setup_immutable_field_list(self):
  533. hints = self.object_type._hints
  534. if "immutable_fields" in hints:
  535. accessor = hints["immutable_fields"]
  536. if not hasattr(accessor, 'fields'):
  537. immutable_fields = set()
  538. rbase = self
  539. while rbase.classdef is not None:
  540. immutable_fields.update(rbase.immutable_field_set)
  541. rbase = rbase.rbase
  542. self._parse_field_list(immutable_fields, accessor, hints)
  543. def _parse_field_list(self, fields, accessor, hints):
  544. ranking = {}
  545. for name in fields:
  546. quasi = False
  547. if name.endswith('?[*]'): # a quasi-immutable field pointing to
  548. name = name[:-4] # an immutable array
  549. rank = IR_QUASIIMMUTABLE_ARRAY
  550. quasi = True
  551. elif name.endswith('[*]'): # for virtualizables' lists
  552. name = name[:-3]
  553. rank = IR_IMMUTABLE_ARRAY
  554. elif name.endswith('?'): # a quasi-immutable field
  555. name = name[:-1]
  556. rank = IR_QUASIIMMUTABLE
  557. quasi = True
  558. else: # a regular immutable/green field
  559. rank = IR_IMMUTABLE
  560. try:
  561. mangled_name, r = self._get_field(name)
  562. except KeyError:
  563. continue
  564. if quasi and hints.get("immutable"):
  565. raise TyperError(
  566. "can't have _immutable_ = True and a quasi-immutable field "
  567. "%s in class %s" % (name, self.classdef))
  568. ranking[mangled_name] = rank
  569. accessor.initialize(self.object_type, ranking)
  570. return ranking
  571. def _check_for_immutable_conflicts(self):
  572. # check for conflicts, i.e. a field that is defined normally as
  573. # mutable in some parent class but that is now declared immutable
  574. is_self_immutable = "immutable" in self.object_type._hints
  575. base = self
  576. while base.classdef is not None:
  577. base = base.rbase
  578. for fieldname in base.fields:
  579. try:
  580. mangled, r = base._get_field(fieldname)
  581. except KeyError:
  582. continue
  583. if r.lowleveltype == Void:
  584. continue
  585. base._setup_immutable_field_list()
  586. if base.object_type._immutable_field(mangled):
  587. continue
  588. # 'fieldname' is a mutable, non-Void field in the parent
  589. if is_self_immutable:
  590. raise ImmutableConflictError(
  591. "class %r has _immutable_=True, but parent class %r "
  592. "defines (at least) the mutable field %r" %
  593. (self, base, fieldname))
  594. if (fieldname in self.immutable_field_set or
  595. (fieldname + '?') in self.immutable_field_set):
  596. raise ImmutableConflictError(
  597. "field %r is defined mutable in class %r, but "
  598. "listed in _immutable_fields_ in subclass %r" %
  599. (fieldname, base, self))
  600. def hook_access_field(self, vinst, cname, llops, flags):
  601. pass # for virtualizables; see rvirtualizable.py
  602. def hook_setfield(self, vinst, fieldname, llops):
  603. if self.is_quasi_immutable(fieldname):
  604. c_fieldname = inputconst(Void, 'mutate_' + fieldname)
  605. llops.genop('jit_force_quasi_immutable', [vinst, c_fieldname])
  606. def is_quasi_immutable(self, fieldname):
  607. search1 = fieldname + '?'
  608. search2 = fieldname + '?[*]'
  609. rbase = self
  610. while rbase.classdef is not None:
  611. if (search1 in rbase.immutable_field_set or
  612. search2 in rbase.immutable_field_set):
  613. return True
  614. rbase = rbase.rbase
  615. return False
  616. def new_instance(self, llops, classcallhop=None, nonmovable=False):
  617. """Build a new instance, without calling __init__."""
  618. flavor = self.gcflavor
  619. flags = {'flavor': flavor}
  620. if nonmovable:
  621. flags['nonmovable'] = True
  622. ctype = inputconst(Void, self.object_type)
  623. cflags = inputconst(Void, flags)
  624. vlist = [ctype, cflags]
  625. vptr = llops.genop('malloc', vlist,
  626. resulttype=Ptr(self.object_type))
  627. ctypeptr = inputconst(CLASSTYPE, self.rclass.getvtable())
  628. self.setfield(vptr, '__class__', ctypeptr, llops)
  629. # initialize instance attributes from their defaults from the class
  630. if self.classdef is not None:
  631. flds = self.allinstancefields.keys()
  632. flds.sort()
  633. for fldname in flds:
  634. if fldname == '__class__':
  635. continue
  636. mangled_name, r = self.allinstancefields[fldname]
  637. if r.lowleveltype is Void:
  638. continue
  639. value = self.classdef.classdesc.read_attribute(fldname, None)
  640. if value is not None:
  641. ll_value = r.convert_desc_or_const(value)
  642. # don't write NULL GC pointers: we know that the malloc
  643. # done above initialized at least the GC Ptr fields to
  644. # NULL already, and that's true for all our GCs
  645. if (isinstance(r.lowleveltype, Ptr) and
  646. r.lowleveltype.TO._gckind == 'gc' and
  647. not ll_value):
  648. continue
  649. cvalue = inputconst(r.lowleveltype, ll_value)
  650. self.setfield(vptr, fldname, cvalue, llops,
  651. flags={'access_directly': True})
  652. return vptr
  653. def convert_const(self, value):
  654. if value is None:
  655. return self.null_instance()
  656. if isinstance(value, types.MethodType):
  657. value = value.im_self # bound method -> instance
  658. bk = self.rtyper.annotator.bookkeeper
  659. try:
  660. classdef = bk.getuniqueclassdef(value.__class__)
  661. except KeyError:
  662. raise TyperError("no classdef: %r" % (value.__class__,))
  663. if classdef != self.classdef:
  664. # if the class does not match exactly, check that 'value' is an
  665. # instance of a subclass and delegate to that InstanceRepr
  666. if classdef.commonbase(self.classdef) != self.classdef:
  667. raise TyperError("not an instance of %r: %r" % (
  668. self.classdef.name, value))
  669. rinstance = getinstancerepr(self.rtyper, classdef)
  670. result = rinstance.convert_const(value)
  671. return self.upcast(result)
  672. # common case
  673. return self.convert_const_exact(value)
  674. def convert_const_exact(self, value):
  675. try:
  676. return self.iprebuiltinstances[value]
  677. except KeyError:
  678. self.setup()
  679. result = self.create_instance()
  680. self.iprebuiltinstances[value] = result
  681. self.initialize_prebuilt_instance(value, self.classdef, result)
  682. return result
  683. def get_reusable_prebuilt_instance(self):
  684. "Get a dummy prebuilt instance. Multiple calls reuse the same one."
  685. try:
  686. return self._reusable_prebuilt_instance
  687. except AttributeError:
  688. self.setup()
  689. result = self.create_instance()
  690. self._reusable_prebuilt_instance = result
  691. self.initialize_prebuilt_data(Ellipsis, self.classdef, result)
  692. return result
  693. _initialize_data_flattenrec = FlattenRecursion()
  694. def initialize_prebuilt_instance(self, value, classdef, result):
  695. # must fill in the hash cache before the other ones
  696. # (see test_circular_hash_initialization)
  697. self.initialize_prebuilt_hash(value, result)
  698. self._initialize_data_flattenrec(self.initialize_prebuilt_data,
  699. value, classdef, result)
  700. def get_ll_hash_function(self):
  701. return ll_inst_hash
  702. get_ll_fasthash_function = get_ll_hash_function
  703. def rtype_type(self, hop):
  704. if hop.s_result.is_constant():
  705. return hop.inputconst(hop.r_result, hop.s_result.const)
  706. instance_repr = self.common_repr()
  707. vinst, = hop.inputargs(instance_repr)
  708. if hop.args_s[0].can_be_none():
  709. return hop.gendirectcall(ll_inst_type, vinst)
  710. else:
  711. return instance_repr.getfield(vinst, '__class__', hop.llops)
  712. def rtype_getattr(self, hop):
  713. if hop.s_result.is_constant():
  714. return hop.inputconst(hop.r_result, hop.s_result.const)
  715. attr = hop.args_s[1].const
  716. vinst, vattr = hop.inputargs(self, Void)
  717. if attr == '__class__' and hop.r_result.lowleveltype is Void:
  718. # special case for when the result of '.__class__' is a constant
  719. [desc] = hop.s_result.descriptions
  720. return hop.inputconst(Void, desc.pyobj)
  721. if attr in self.allinstancefields:
  722. return self.getfield(vinst, attr, hop.llops,
  723. flags=hop.args_s[0].flags)
  724. elif attr in self.rclass.allmethods:
  725. # special case for methods: represented as their 'self' only
  726. # (see MethodsPBCRepr)
  727. return hop.r_result.get_method_from_instance(self, vinst,
  728. hop.llops)
  729. else:
  730. vcls = self.getfield(vinst, '__class__', hop.llops)
  731. return self.rclass.getclsfield(vcls, attr, hop.llops)
  732. def rtype_setattr(self, hop):
  733. attr = hop.args_s[1].const
  734. r_value = self.getfieldrepr(attr)
  735. vinst, vattr, vvalue = hop.inputargs(self, Void, r_value)
  736. self.setfield(vinst, attr, vvalue, hop.llops,
  737. flags=hop.args_s[0].flags)
  738. def rtype_bool(self, hop):
  739. vinst, = hop.inputargs(self)
  740. return hop.genop('ptr_nonzero', [vinst], resulttype=Bool)
  741. def ll_str(self, i): # doesn't work for non-gc classes!
  742. from rpython.rtyper.lltypesystem.ll_str import ll_int2hex
  743. from rpython.rlib.rarithmetic import r_uint
  744. if not i:
  745. return rstr.null_str
  746. instance = cast_pointer(OBJECTPTR, i)
  747. # Two choices: the first gives a fast answer but it can change
  748. # (typically only once) during the life of the object.
  749. #uid = r_uint(cast_ptr_to_int(i))
  750. uid = r_uint(llop.gc_id(lltype.Signed, i))
  751. #
  752. res = rstr.instance_str_prefix
  753. res = rstr.ll_strconcat(res, instance.typeptr.name)
  754. res = rstr.ll_strconcat(res, rstr.instance_str_infix)
  755. res = rstr.ll_strconcat(res, ll_int2hex(uid, False))
  756. res = rstr.ll_strconcat(res, rstr.instance_str_suffix)
  757. return res
  758. def get_ll_eq_function(self):
  759. return None # defaults to compare by identity ('==' on pointers)
  760. def can_ll_be_null(self, s_value):
  761. return s_value.can_be_none()
  762. @staticmethod
  763. def check_graph_of_del_does_not_call_too_much(rtyper, graph):
  764. # RPython-level __del__() methods should not do "too much".
  765. # In the PyPy Python interpreter, they usually do simple things
  766. # like file.__del__() closing the file descriptor; or if they
  767. # want to do more like call an app-level __del__() method, they
  768. # enqueue the object instead, and the actual call is done later.
  769. #
  770. # Here, as a quick way to check "not doing too much", we check
  771. # that from no RPython-level __del__() method we can reach a
  772. # JitDriver.
  773. #
  774. # XXX wrong complexity, but good enough because the set of
  775. # reachable graphs should be small
  776. callgraph = rtyper.annotator.translator.callgraph.values()
  777. seen = {graph: None}
  778. while True:
  779. oldlength = len(seen)
  780. for caller, callee in callgraph:
  781. if caller in seen and callee not in seen:
  782. func = getattr(callee, 'func', None)
  783. if getattr(func, '_dont_reach_me_in_del_', False):
  784. lst = [str(callee)]
  785. g = caller
  786. while g:
  787. lst.append(str(g))
  788. g = seen.get(g)
  789. lst.append('')
  790. raise TyperError("the RPython-level __del__() method "
  791. "in %r calls:%s" %
  792. (graph, '\n\t'.join(lst[::-1])))
  793. if getattr(func, '_cannot_really_call_random_things_',
  794. False):
  795. continue
  796. seen[callee] = caller
  797. if len(seen) == oldlength:
  798. break
  799. def common_repr(self): # -> object or nongcobject reprs
  800. return getinstancerepr(self.rtyper, None, self.gcflavor)
  801. def _get_field(self, attr):
  802. return self.fields[attr]
  803. def null_instance(self):
  804. return nullptr(self.object_type)
  805. def upcast(self, result):
  806. return cast_pointer(self.lowleveltype, result)
  807. def create_instance(self):
  808. return malloc(self.object_type, flavor=self.gcflavor, immortal=True)
  809. def initialize_prebuilt_data(self, value, classdef, result):
  810. if self.classdef is not None:
  811. # recursively build the parent part of the instance
  812. self.rbase.initialize_prebuilt_data(value, classdef, result.super)
  813. # then add instance attributes from this level
  814. for name, (mangled_name, r) in self.fields.items():
  815. if r.lowleveltype is Void:
  816. llattrvalue = None
  817. else:
  818. try:
  819. attrvalue = getattr(value, name)
  820. except AttributeError:
  821. attrvalue = self.classdef.classdesc.read_attribute(
  822. name, None)
  823. if attrvalue is None:
  824. # Ellipsis from get_reusable_prebuilt_instance()
  825. #if value is not Ellipsis:
  826. #warning("prebuilt instance %r has no "
  827. # "attribute %r" % (value, name))
  828. llattrvalue = r.lowleveltype._defl()
  829. else:
  830. llattrvalue = r.convert_desc_or_const(attrvalue)
  831. else:
  832. llattrvalue = r.convert_const(attrvalue)
  833. setattr(result, mangled_name, llattrvalue)
  834. else:
  835. # OBJECT part
  836. rclass = getclassrepr(self.rtyper, classdef)
  837. result.typeptr = rclass.getvtable()
  838. def initialize_prebuilt_hash(self, value, result):
  839. llattrvalue = getattr(value, '__precomputed_identity_hash', None)
  840. if llattrvalue is not None:
  841. lltype.init_identity_hash(result, llattrvalue)
  842. def getfieldrepr(self, attr):
  843. """Return the repr used for the given attribute."""
  844. if attr in self.fields:
  845. mangled_name, r = self.fields[attr]
  846. return r
  847. else:
  848. if self.classdef is None:
  849. raise MissingRTypeAttribute(attr)
  850. return self.rbase.getfieldrepr(attr)
  851. def getfield(self, vinst, attr, llops, force_cast=False, flags={}):
  852. """Read the given attribute (or __class__ for the type) of 'vinst'."""
  853. if attr in self.fields:
  854. mangled_name, r = self.fields[attr]
  855. cname = inputconst(Void, mangled_name)
  856. if force_cast:
  857. vinst = llops.genop('cast_pointer', [vinst], resulttype=self)
  858. self.hook_access_field(vinst, cname, llops, flags)
  859. return llops.genop('getfield', [vinst, cname], resulttype=r)
  860. else:
  861. if self.classdef is None:
  862. raise MissingRTypeAttribute(attr)
  863. return self.rbase.getfield(vinst, attr, llops, force_cast=True,
  864. flags=flags)
  865. def setfield(self, vinst, attr, vvalue, llops, force_cast=False,
  866. flags={}):
  867. """Write the given attribute (or __class__ for the type) of 'vinst'."""
  868. if attr in self.fields:
  869. mangled_name, r = self.fields[attr]
  870. cname = inputconst(Void, mangled_name)
  871. if force_cast:
  872. vinst = llops.genop('cast_pointer', [vinst], resulttype=self)
  873. self.hook_access_field(vinst, cname, llops, flags)
  874. self.hook_setfield(vinst, attr, llops)
  875. llops.genop('setfield', [vinst, cname, vvalue])
  876. else:
  877. if self.classdef is None:
  878. raise MissingRTypeAttribute(attr)
  879. self.rbase.setfield(vinst, attr, vvalue, llops, force_cast=True,
  880. flags=flags)
  881. def rtype_isinstance(self, hop):
  882. class_repr = get_type_repr(hop.rtyper)
  883. instance_repr = self.common_repr()
  884. v_obj, v_cls = hop.inputargs(instance_repr, class_repr)
  885. if isinstance(v_cls, Constant):
  886. cls = v_cls.value
  887. llf, llf_nonnull = make_ll_isinstance(self.rtyper, cls)
  888. if hop.args_s[0].can_be_None:
  889. return hop.gendirectcall(llf, v_obj)
  890. else:
  891. return hop.gendirectcall(llf_nonnull, v_obj)
  892. else:
  893. return hop.gendirectcall(ll_isinstance, v_obj, v_cls)
  894. class __extend__(pairtype(InstanceRepr, InstanceRepr)):
  895. def convert_from_to((r_ins1, r_ins2), v, llops):
  896. # which is a subclass of which?
  897. if r_ins1.classdef is None or r_ins2.classdef is None:
  898. basedef = None
  899. else:
  900. basedef = r_ins1.classdef.commonbase(r_ins2.classdef)
  901. if basedef == r_ins2.classdef:
  902. # r_ins1 is an instance of the subclass: converting to parent
  903. v = llops.genop('cast_pointer', [v],
  904. resulttype=r_ins2.lowleveltype)
  905. return v
  906. elif basedef == r_ins1.classdef:
  907. # r_ins2 is an instance of the subclass: potentially unsafe
  908. # casting, but we do it anyway (e.g. the annotator produces
  909. # such casts after a successful isinstance() check)
  910. v = llops.genop('cast_pointer', [v],
  911. resulttype=r_ins2.lowleveltype)
  912. return v
  913. else:
  914. return NotImplemented
  915. def rtype_is_((r_ins1, r_ins2), hop):
  916. if r_ins1.gcflavor != r_ins2.gcflavor:
  917. # obscure logic, the is can be true only if both are None
  918. v_ins1, v_ins2 = hop.inputargs(
  919. r_ins1.common_repr(), r_ins2.common_repr())
  920. return hop.gendirectcall(ll_both_none, v_ins1, v_ins2)
  921. if r_ins1.classdef is None or r_ins2.classdef is None:
  922. basedef = None
  923. else:
  924. basedef = r_ins1.classdef.commonbase(r_ins2.classdef)
  925. r_ins = getinstancerepr(r_ins1.rtyper, basedef, r_ins1.gcflavor)
  926. return pairtype(Repr, Repr).rtype_is_(pair(r_ins, r_ins), hop)
  927. rtype_eq = rtype_is_
  928. def rtype_ne(rpair, hop):
  929. v = rpair.rtype_eq(hop)
  930. return hop.genop("bool_not", [v], resulttype=Bool)
  931. # ____________________________________________________________
  932. def rtype_new_instance(rtyper, classdef, llops, classcallhop=None,
  933. nonmovable=False):
  934. rinstance = getinstancerepr(rtyper, classdef)
  935. return rinstance.new_instance(llops, classcallhop, nonmovable=nonmovable)
  936. def ll_inst_hash(ins):
  937. if not ins:
  938. return 0 # for None
  939. else:
  940. return lltype.identityhash(ins)
  941. _missing = object()
  942. def fishllattr(inst, name, default=_missing):
  943. p = widest = lltype.normalizeptr(inst)
  944. while True:
  945. try:
  946. return getattr(p, 'inst_' + name)
  947. except AttributeError:
  948. pass
  949. try:
  950. p = p.super
  951. except AttributeError:
  952. break
  953. if default is _missing:
  954. raise AttributeError("%s has no field %s" %
  955. (lltype.typeOf(widest), name))
  956. return default
  957. def attr_reverse_size((_, T)):
  958. # This is used to sort the instance or class attributes by decreasing
  959. # "likely size", as reported by rffi.sizeof(), to minimize padding
  960. # holes in C. Fields should first be sorted by name, just to minimize
  961. # randomness, and then (stably) sorted by 'attr_reverse_size'.
  962. if T is lltype.Void:
  963. return None
  964. from rpython.rtyper.lltypesystem.rffi import sizeof
  965. try:
  966. return -sizeof(T)
  967. except StandardError:
  968. return None
  969. # ____________________________________________________________
  970. #
  971. # Low-level implementation of operations on classes and instances
  972. # doesn't work for non-gc stuff!
  973. def ll_cast_to_object(obj):
  974. return cast_pointer(OBJECTPTR, obj)
  975. # doesn't work for non-gc stuff!
  976. def ll_type(obj):
  977. return cast_pointer(OBJECTPTR, obj).typeptr
  978. def ll_issubclass(subcls, cls):
  979. return llop.int_between(Bool,
  980. cls.subclassrange_min,
  981. subcls.subclassrange_min,
  982. cls.subclassrange_max)
  983. def ll_issubclass_const(subcls, minid, maxid):
  984. return llop.int_between(Bool, minid, subcls.subclassrange_min, maxid)
  985. def ll_isinstance(obj, cls): # obj should be cast to OBJECT or NONGCOBJECT
  986. if not obj:
  987. return False
  988. obj_cls = obj.typeptr
  989. return ll_issubclass(obj_cls, cls)
  990. def make_ll_isinstance(rtyper, cls):
  991. try:
  992. return rtyper.isinstance_helpers[cls._obj]
  993. except KeyError:
  994. minid = cls.subclassrange_min
  995. maxid = cls.subclassrange_max
  996. if minid.number_with_subclasses():
  997. def ll_isinstance_const_nonnull(obj):
  998. objid = obj.typeptr.subclassrange_min
  999. return llop.int_between(Bool, minid, objid, maxid)
  1000. else:
  1001. def ll_isinstance_const_nonnull(obj):
  1002. return obj.typeptr == cls
  1003. def ll_isinstance_const(obj):
  1004. if not obj:
  1005. return False
  1006. return ll_isinstance_const_nonnull(obj)
  1007. result = (ll_isinstance_const, ll_isinstance_const_nonnull)
  1008. rtyper.isinstance_helpers[cls._obj] = result
  1009. return result
  1010. def ll_runtime_type_info(obj):
  1011. return obj.typeptr.rtti
  1012. def ll_inst_type(obj):
  1013. if obj:
  1014. return obj.typeptr
  1015. else:
  1016. # type(None) -> NULL (for now)
  1017. return nullptr(typeOf(obj).TO.typeptr.TO)
  1018. def ll_both_none(ins1, ins2):
  1019. return not ins1 and not ins2
  1020. # ____________________________________________________________
  1021. def feedllattr(inst, name, llvalue):
  1022. p = widest = lltype.normalizeptr(inst)
  1023. while True:
  1024. try:
  1025. return setattr(p, 'inst_' + name, llvalue)
  1026. except AttributeError:
  1027. pass
  1028. try:
  1029. p = p.super
  1030. except AttributeError:
  1031. break
  1032. raise AttributeError("%s has no field %s" % (lltype.typeOf(widest),
  1033. name))
  1034. def declare_type_for_typeptr(vtable, TYPE):
  1035. """Hack for custom low-level-only 'subclasses' of OBJECT:
  1036. call this somewhere annotated, in order to declare that it is
  1037. of the given TYPE and has got the corresponding vtable."""
  1038. class Entry(ExtRegistryEntry):
  1039. _about_ = declare_type_for_typeptr
  1040. def compute_result_annotation(self, s_vtable, s_TYPE):
  1041. assert s_vtable.is_constant()
  1042. assert s_TYPE.is_constant()
  1043. return annmodel.s_None
  1044. def specialize_call(self, hop):
  1045. vtable = hop.args_v[0].value
  1046. TYPE = hop.args_v[1].value
  1047. assert lltype.typeOf(vtable) == CLASSTYPE
  1048. assert isinstance(TYPE, GcStruct)
  1049. assert lltype._castdepth(TYPE, OBJECT) > 0
  1050. hop.rtyper.set_type_for_typeptr(vtable, TYPE)
  1051. hop.exception_cannot_occur()
  1052. return hop.inputconst(lltype.Void, None)