def rtyper_makerepr(self, rtyper): kind = getkind(self) if kind == "type": return rclass.get_type_repr(rtyper) elif kind == "const": return constpyobj_repr else: return pyobj_repr
def _setup_repr(self, llfields=None, hints=None, adtmeths=None): # NOTE: don't store mutable objects like the dicts below on 'self' # before they are fully built, to avoid strange bugs in case # of recursion where other code would uses these # partially-initialized dicts. self.rclass = getclassrepr(self.rtyper, self.classdef) fields = {} allinstancefields = {} if self.classdef is None: fields['__class__'] = 'typeptr', get_type_repr(self.rtyper) else: # instance attributes if llfields is None: llfields = [] attrs = self.classdef.attrs.items() attrs.sort() for name, attrdef in attrs: if not attrdef.readonly: r = self.rtyper.getrepr(attrdef.s_value) mangled_name = 'inst_' + name fields[name] = mangled_name, r llfields.append((mangled_name, r.lowleveltype)) # # hash() support if self.rtyper.needs_hash_support(self.classdef): from pypy.rpython import rint fields['_hash_cache_'] = 'hash_cache', rint.signed_repr llfields.append(('hash_cache', Signed)) self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef, self.gcflavor) self.rbase.setup() # # PyObject wrapper support if self.has_wrapper and '_wrapper_' not in self.rbase.allinstancefields: fields['_wrapper_'] = 'wrapper', pyobj_repr llfields.append(('wrapper', Ptr(PyObject))) MkStruct = lltype.STRUCT_BY_FLAVOR[LLFLAVOR[self.gcflavor]] if adtmeths is None: adtmeths = {} if hints is None: hints = {} if '_immutable_' in self.classdef.classdesc.classdict: hints = hints.copy() hints['immutable'] = True object_type = MkStruct(self.classdef.name, ('super', self.rbase.object_type), hints=hints, adtmeths=adtmeths, *llfields) self.object_type.become(object_type) allinstancefields.update(self.rbase.allinstancefields) allinstancefields.update(fields) self.fields = fields self.allinstancefields = allinstancefields if self.gcflavor in RTTIFLAVORS: attachRuntimeTypeInfo(self.object_type)
def _setup_repr(self, llfields=None, hints=None, adtmeths=None): # NOTE: don't store mutable objects like the dicts below on 'self' # before they are fully built, to avoid strange bugs in case # of recursion where other code would uses these # partially-initialized dicts. self.rclass = getclassrepr(self.rtyper, self.classdef) fields = {} allinstancefields = {} if self.classdef is None: fields['__class__'] = 'typeptr', get_type_repr(self.rtyper) else: # instance attributes if llfields is None: llfields = [] attrs = self.classdef.attrs.items() attrs.sort() for name, attrdef in attrs: if not attrdef.readonly: r = self.rtyper.getrepr(attrdef.s_value) mangled_name = 'inst_' + name fields[name] = mangled_name, r llfields.append((mangled_name, r.lowleveltype)) # # hash() support if self.rtyper.needs_hash_support(self.classdef): from pypy.rpython import rint fields['_hash_cache_'] = 'hash_cache', rint.signed_repr llfields.append(('hash_cache', Signed)) self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef, self.gcflavor) self.rbase.setup() MkStruct = lltype.STRUCT_BY_FLAVOR[LLFLAVOR[self.gcflavor]] if adtmeths is None: adtmeths = {} if hints is None: hints = {} if '_immutable_' in self.classdef.classdesc.classdict: hints = hints.copy() hints['immutable'] = True object_type = MkStruct(self.classdef.name, ('super', self.rbase.object_type), hints=hints, adtmeths=adtmeths, *llfields) self.object_type.become(object_type) allinstancefields.update(self.rbase.allinstancefields) allinstancefields.update(fields) self.fields = fields self.allinstancefields = allinstancefields if self.gcflavor == 'gc': attachRuntimeTypeInfo(self.object_type)
def rtype_isinstance(self, hop): if not hop.args_s[1].is_constant(): raise TyperError("isinstance() too complicated") [classdesc] = hop.args_s[1].descriptions classdef = classdesc.getuniqueclassdef() class_repr = get_type_repr(self.rtyper) instance_repr = self.common_repr() v_obj, v_cls = hop.inputargs(instance_repr, class_repr) cls = v_cls.value answer = self.unboxedclassdef.issubclass(classdef) c_answer_if_unboxed = hop.inputconst(lltype.Bool, answer) minid = hop.inputconst(lltype.Signed, cls.subclassrange_min) maxid = hop.inputconst(lltype.Signed, cls.subclassrange_max) return hop.gendirectcall(ll_unboxed_isinstance_const, v_obj, minid, maxid, c_answer_if_unboxed)
def rtype_issubtype(self, hop): class_repr = get_type_repr(self.rtyper) v_cls1, v_cls2 = hop.inputargs(class_repr, class_repr) if isinstance(v_cls2, Constant): cls2 = v_cls2.value # XXX re-implement the following optimization ## if cls2.subclassrange_max == cls2.subclassrange_min: ## # a class with no subclass ## return hop.genop('ptr_eq', [v_cls1, v_cls2], resulttype=Bool) ## else: minid = hop.inputconst(Signed, cls2.subclassrange_min) maxid = hop.inputconst(Signed, cls2.subclassrange_max) return hop.gendirectcall(ll_issubclass_const, v_cls1, minid, maxid) else: v_cls1, v_cls2 = hop.inputargs(class_repr, class_repr) return hop.gendirectcall(ll_issubclass, v_cls1, v_cls2)
def rtype_isinstance(self, hop): class_repr = get_type_repr(hop.rtyper) instance_repr = self.common_repr() v_obj, v_cls = hop.inputargs(instance_repr, class_repr) if isinstance(v_cls, Constant): cls = v_cls.value # XXX re-implement the following optimization #if cls.subclassrange_max == cls.subclassrange_min: # # a class with no subclass # return hop.gendirectcall(rclass.ll_isinstance_exact, v_obj, v_cls) #else: minid = hop.inputconst(Signed, cls.subclassrange_min) maxid = hop.inputconst(Signed, cls.subclassrange_max) return hop.gendirectcall(ll_isinstance_const, v_obj, minid, maxid) else: return hop.gendirectcall(ll_isinstance, v_obj, v_cls)
def _setup_repr(self, llfields=None, hints=None, adtmeths=None): # NOTE: don't store mutable objects like the dicts below on 'self' # before they are fully built, to avoid strange bugs in case # of recursion where other code would uses these # partially-initialized dicts. self.rclass = getclassrepr(self.rtyper, self.classdef) fields = {} allinstancefields = {} if self.classdef is None: fields['__class__'] = 'typeptr', get_type_repr(self.rtyper) else: # instance attributes if llfields is None: llfields = [] attrs = self.classdef.attrs.items() attrs.sort() for name, attrdef in attrs: if not attrdef.readonly: r = self.rtyper.getrepr(attrdef.s_value) mangled_name = 'inst_' + name fields[name] = mangled_name, r llfields.append((mangled_name, r.lowleveltype)) self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef, self.gcflavor) self.rbase.setup() MkStruct = lltype.STRUCT_BY_FLAVOR[LLFLAVOR[self.gcflavor]] if adtmeths is None: adtmeths = {} if hints is None: hints = {} hints = self._check_for_immutable_hints(hints) object_type = MkStruct(self.classdef.name, ('super', self.rbase.object_type), hints=hints, adtmeths=adtmeths, *llfields) self.object_type.become(object_type) allinstancefields.update(self.rbase.allinstancefields) allinstancefields.update(fields) self.fields = fields self.allinstancefields = allinstancefields if self.gcflavor == 'gc': attachRuntimeTypeInfo(self.object_type)
def _generate_save_block(self, varsforcall, v_unwind_exception, saver): conc_types = tuple([v.concretetype for v in varsforcall]) if conc_types in self.curr_graph_save_blocks: return self.curr_graph_save_blocks[conc_types] rtyper = self.translator.rtyper edata = rtyper.getexceptiondata() etype = edata.lltype_of_exception_type evalue = edata.lltype_of_exception_value inputargs = [copyvar(v) for v in varsforcall] v_unwind_exception = copyvar(v_unwind_exception) save_state_block = model.Block(inputargs + [v_unwind_exception]) saveops = LowLevelOpList() v_exc = gen_cast(saveops, self.unwind_exception_type, v_unwind_exception) realvarsforcall = [v_exc] for v in inputargs: realvarsforcall.append(gen_cast(saveops, storage_type(v.concretetype), v)) saveops.genop('direct_call', [model.Constant(saver, lltype.typeOf(saver))] + realvarsforcall, resulttype=lltype.Void) save_state_block.operations = saveops type_repr = rclass.get_type_repr(rtyper) c_unwindexception = model.Constant( type_repr.convert_const(code.UnwindException), etype) if not hasattr(self.curr_graph.exceptblock.inputargs[0], 'concretetype'): self.curr_graph.exceptblock.inputargs[0].concretetype = etype if not hasattr(self.curr_graph.exceptblock.inputargs[1], 'concretetype'): self.curr_graph.exceptblock.inputargs[1].concretetype = evalue save_state_block.closeblock(model.Link( [c_unwindexception, v_unwind_exception], self.curr_graph.exceptblock)) self.translator.rtyper._convert_link( save_state_block, save_state_block.exits[0]) if SAVE_STATISTICS: self.stats.saveops += len(save_state_block.operations) self.curr_graph_save_blocks[conc_types] = save_state_block return save_state_block
def _setup_repr(self, llfields=None, hints=None, adtmeths=None): # NOTE: don't store mutable objects like the dicts below on 'self' # before they are fully built, to avoid strange bugs in case # of recursion where other code would uses these # partially-initialized dicts. AbstractInstanceRepr._setup_repr(self) self.rclass = getclassrepr(self.rtyper, self.classdef) fields = {} allinstancefields = {} if self.classdef is None: fields["__class__"] = "typeptr", get_type_repr(self.rtyper) else: # instance attributes attrs = self.classdef.attrs.items() attrs.sort() myllfields = [] for name, attrdef in attrs: if not attrdef.readonly: r = self.rtyper.getrepr(attrdef.s_value) mangled_name = "inst_" + name fields[name] = mangled_name, r myllfields.append((mangled_name, r.lowleveltype)) # Sort the instance attributes by decreasing "likely size", # as reported by rffi.sizeof(), to minimize padding holes in C. # Fields of the same size are sorted by name (by attrs.sort() # above) just to minimize randomness. def keysize((_, T)): if T is lltype.Void: return None from pypy.rpython.lltypesystem.rffi import sizeof try: return -sizeof(T) except StandardError: return None myllfields.sort(key=keysize) if llfields is None: llfields = myllfields else: llfields = llfields + myllfields self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef, self.gcflavor) self.rbase.setup() MkStruct = lltype.STRUCT_BY_FLAVOR[LLFLAVOR[self.gcflavor]] if adtmeths is None: adtmeths = {} if hints is None: hints = {} hints = self._check_for_immutable_hints(hints) kwds = {} if self.gcflavor == "gc": kwds["rtti"] = True for name, attrdef in attrs: if not attrdef.readonly and self.is_quasi_immutable(name): llfields.append(("mutate_" + name, OBJECTPTR)) object_type = MkStruct( self.classdef.name, ("super", self.rbase.object_type), hints=hints, adtmeths=adtmeths, *llfields, **kwds ) self.object_type.become(object_type) allinstancefields.update(self.rbase.allinstancefields) allinstancefields.update(fields) self.fields = fields self.allinstancefields = allinstancefields
def _setup_repr(self, llfields=None, hints=None, adtmeths=None): # NOTE: don't store mutable objects like the dicts below on 'self' # before they are fully built, to avoid strange bugs in case # of recursion where other code would uses these # partially-initialized dicts. AbstractInstanceRepr._setup_repr(self) self.rclass = getclassrepr(self.rtyper, self.classdef) fields = {} allinstancefields = {} if self.classdef is None: fields['__class__'] = 'typeptr', get_type_repr(self.rtyper) else: # instance attributes attrs = self.classdef.attrs.items() attrs.sort() myllfields = [] for name, attrdef in attrs: if not attrdef.readonly: r = self.rtyper.getrepr(attrdef.s_value) mangled_name = 'inst_' + name fields[name] = mangled_name, r myllfields.append((mangled_name, r.lowleveltype)) # Sort the instance attributes by decreasing "likely size", # as reported by rffi.sizeof(), to minimize padding holes in C. # Fields of the same size are sorted by name (by attrs.sort() # above) just to minimize randomness. def keysize((_, T)): if T is lltype.Void: return None from pypy.rpython.lltypesystem.rffi import sizeof try: return -sizeof(T) except StandardError: return None myllfields.sort(key=keysize) if llfields is None: llfields = myllfields else: llfields = llfields + myllfields self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef, self.gcflavor) self.rbase.setup() MkStruct = lltype.STRUCT_BY_FLAVOR[LLFLAVOR[self.gcflavor]] if adtmeths is None: adtmeths = {} if hints is None: hints = {} hints = self._check_for_immutable_hints(hints) kwds = {} if self.gcflavor == 'gc': kwds['rtti'] = True for name, attrdef in attrs: if not attrdef.readonly and self.is_quasi_immutable(name): llfields.append(('mutate_' + name, OBJECTPTR)) object_type = MkStruct(self.classdef.name, ('super', self.rbase.object_type), hints=hints, adtmeths=adtmeths, *llfields, **kwds) self.object_type.become(object_type) allinstancefields.update(self.rbase.allinstancefields) allinstancefields.update(fields) self.fields = fields self.allinstancefields = allinstancefields
def convert_desc(self, desc): if desc not in self.s_pbc.descriptions: raise TyperError("%r not in %r" % (cls, self)) if self.lowleveltype is Void: return desc.pyobj return rclass.get_type_repr(self.rtyper).convert_desc(desc)
def _instantiate_runtime_class(self, hop, v_class, r_instance): classdef = hop.s_result.classdef resulttype = getinstancerepr(hop.rtyper, classdef).lowleveltype # convert v_class from META to ootype.Class if necessary: v_class = get_type_repr(hop.rtyper).fromclasstype(v_class, hop.llops) return hop.genop('runtimenew', [v_class], resulttype=resulttype)
def rtype_issubtype(self, hop): class_repr = get_type_repr(self.rtyper) vmeta1, vmeta2 = hop.inputargs(class_repr, class_repr) return hop.gendirectcall(ll_issubclass, vmeta1, vmeta2)
def convert_desc(self, desc): if desc not in self.s_pbc.descriptions: raise TyperError("%r not in %r" % (cls, self)) if self.lowleveltype is Void: return None return rclass.get_type_repr(self.rtyper).convert_desc(desc)
def rtype_issubtype(self, hop): class_repr = get_type_repr(self.rtyper) vcls1, vcls2 = hop.inputargs(class_repr, class_repr) return hop.genop('subclassof', [vcls1, vcls2], resulttype=ootype.Bool)