def get_typeid_from_classptr_if_gcremovetypeptr(self, classptr): """Returns the typeid corresponding from a vtable pointer 'classptr'. This function only works if cpu.vtable_offset is None, i.e. in a translation with --gcremovetypeptr. """ from rpython.memory.gctypelayout import GCData assert self.gcdescr.config.translation.gcremovetypeptr # hard-coded assumption: to go from an object to its class # we would use the following algorithm: # - read the typeid from mem(locs[0]), i.e. at offset 0; # this is a complete word (N=4 bytes on 32-bit, N=8 on # 64-bits) # - keep the lower half of what is read there (i.e. # truncate to an unsigned 'N / 2' bytes value) # - multiply by 4 (on 32-bits only) and use it as an # offset in type_info_group # - add 16/32 bytes, to go past the TYPE_INFO structure # here, we have to go back from 'classptr' back to the typeid, # so we do (part of) these computations in reverse. sizeof_ti = rffi.sizeof(GCData.TYPE_INFO) type_info_group = llop.gc_get_type_info_group(llmemory.Address) type_info_group = rffi.cast(lltype.Signed, type_info_group) expected_typeid = classptr - sizeof_ti - type_info_group if WORD == 4: expected_typeid >>= 2 return expected_typeid
def get_typeid_from_classptr_if_gcremovetypeptr(self, classptr): """Returns the typeid corresponding from a vtable pointer 'classptr'. This function only works if cpu.vtable_offset is None, i.e. in a translation with --gcremovetypeptr. """ from rpython.memory.gctypelayout import GCData assert self.gcdescr.config.translation.gcremovetypeptr # hard-coded assumption: to go from an object to its class # we would use the following algorithm: # - read the typeid from mem(locs[0]), i.e. at offset 0; # this is a complete word (N=4 bytes on 32-bit, N=8 on # 64-bits) # - keep the lower half of what is read there (i.e. # truncate to an unsigned 'N / 2' bytes value) # - multiply by 4 (on 32-bits only) and use it as an # offset in type_info_group # - add 16/32 bytes, to go past the TYPE_INFO structure # here, we have to go back from 'classptr' back to the typeid, # so we do (part of) these computations in reverse. sizeof_ti = rffi.sizeof(GCData.TYPE_INFO) type_info_group = llop.gc_get_type_info_group(llmemory.Address) type_info_group = rffi.cast(lltype.Signed, type_info_group) expected_typeid = classptr - sizeof_ti - type_info_group if WORD == 4: expected_typeid >>= 2 return expected_typeid
def get_translated_info_for_typeinfo(self): from rpython.memory.gctypelayout import GCData type_info_group = llop.gc_get_type_info_group(llmemory.Address) type_info_group = rffi.cast(lltype.Signed, type_info_group) if WORD == 4: shift_by = 2 elif WORD == 8: shift_by = 0 sizeof_ti = rffi.sizeof(GCData.TYPE_INFO) return (type_info_group, shift_by, sizeof_ti)
def get_translated_info_for_typeinfo(self): from rpython.memory.gctypelayout import GCData type_info_group = llop.gc_get_type_info_group(llmemory.Address) type_info_group = rffi.cast(lltype.Signed, type_info_group) if WORD == 4: shift_by = 2 elif WORD == 8: shift_by = 0 sizeof_ti = rffi.sizeof(GCData.TYPE_INFO) return (type_info_group, shift_by, sizeof_ti)
def ClassPtrTypeID(classptr): """ASMJSValue representing the typeid for a class pointer. This is a special value for handling class comparisons when we're not using type pointers. It extracts an "expected type id" from the class pointer, which can be compared agaist the first half-word in the object pointer. Logic shamelessly cargo-culted from x86 backend. """ sizeof_ti = rffi.sizeof(GCData.TYPE_INFO) type_info_group = llop.gc_get_type_info_group(llmemory.Address) type_info_group = rffi.cast(lltype.Signed, type_info_group) typeid = Minus(classptr, ConstInt(sizeof_ti + type_info_group)) typeid = RShift(typeid, ConstInt(2)) typeid = And(typeid, ConstInt(0xFFFF)) return typeid
def ClassPtrTypeID(classptr): """ASMJSValue representing the typeid for a class pointer. This is a special value for handling class comparisons when we're not using type pointers. It extracts an "expected type id" from the class pointer, which can be compared agaist the first half-word in the object pointer. Logic shamelessly cargo-culted from x86 backend. """ sizeof_ti = rffi.sizeof(GCData.TYPE_INFO) type_info_group = llop.gc_get_type_info_group(llmemory.Address) type_info_group = rffi.cast(lltype.Signed, type_info_group) typeid = Minus(classptr, ConstInt(sizeof_ti + type_info_group)) typeid = RShift(typeid, ConstInt(2)) typeid = And(typeid, ConstInt(0xFFFF)) return typeid