def gettype_from_unboxed(self, llops, vinst, can_be_none=False): unboxedclass_repr = getclassrepr(self.rtyper, self.unboxedclassdef) cunboxedcls = inputconst(CLASSTYPE, unboxedclass_repr.getvtable()) if self.is_parent: # If the lltype of vinst shows that it cannot be a tagged value, # we can directly read the typeptr. Otherwise, call a helper that # checks if the tag bit is set in the pointer. unboxedinstance_repr = getinstancerepr(self.rtyper, self.unboxedclassdef) try: lltype.castable(unboxedinstance_repr.lowleveltype, vinst.concretetype) except lltype.InvalidCast: can_be_tagged = False else: can_be_tagged = True vinst = llops.genop('cast_pointer', [vinst], resulttype=self.common_repr()) if can_be_tagged: if can_be_none: func = ll_unboxed_getclass_canbenone else: func = ll_unboxed_getclass return llops.gendirectcall(func, vinst, cunboxedcls) elif can_be_none: return llops.gendirectcall(ll_inst_type, vinst) else: ctypeptr = inputconst(lltype.Void, 'typeptr') return llops.genop('getfield', [vinst, ctypeptr], resulttype=CLASSTYPE) else: return cunboxedcls
def gettype_from_unboxed(self, llops, vinst, can_be_none=False): unboxedclass_repr = getclassrepr(self.rtyper, self.unboxedclassdef) cunboxedcls = inputconst(CLASSTYPE, unboxedclass_repr.getvtable()) if self.is_parent: # If the lltype of vinst shows that it cannot be a tagged value, # we can directly read the typeptr. Otherwise, call a helper that # checks if the tag bit is set in the pointer. unboxedinstance_repr = getinstancerepr(self.rtyper, self.unboxedclassdef) try: lltype.castable(unboxedinstance_repr.lowleveltype, vinst.concretetype) except lltype.InvalidCast: can_be_tagged = False else: can_be_tagged = True vinst = llops.genop('cast_pointer', [vinst], resulttype=self.common_repr()) if can_be_tagged: if can_be_none: func = ll_unboxed_getclass_canbenone else: func = ll_unboxed_getclass return llops.gendirectcall(func, vinst, cunboxedcls) elif can_be_none: return llops.gendirectcall(ll_inst_type, vinst) else: ctypeptr = inputconst(lltype.Void, 'typeptr') return llops.genop('getfield', [vinst, ctypeptr], resulttype = CLASSTYPE) else: return cunboxedcls
def handle_op_cast_pointer(self, op): node = self.getnode(op.args[0]) if isinstance(node, VirtualSpecNode): node = self.getnode(op.args[0]) SOURCEPTR = lltype.Ptr(node.typedesc.MALLOCTYPE) TARGETPTR = op.result.concretetype try: if lltype.castable(TARGETPTR, SOURCEPTR) < 0: raise lltype.InvalidCast except lltype.InvalidCast: return self.handle_unreachable(op) self.setnode(op.result, node) return [] else: return self.handle_default(op)
def fromtypeptr(self, vcls, llops): """Return the type pointer cast to self's vtable type.""" self.setup() castable(self.lowleveltype, vcls.concretetype) # sanity check return llops.genop('cast_pointer', [vcls], resulttype=self.lowleveltype)
def castable(self, TO, var): return lltype.castable(TO, lltype.typeOf(var)) > 0