def store(self, w_self, n0, w_val): AbstractCachingShadow.store(self, w_self, n0, w_val) if n0 == constants.CLASS_SUPERCLASS_INDEX: self.store_w_superclass(w_val) elif n0 == constants.CLASS_METHODDICT_INDEX: self.store_w_methoddict(w_val) elif n0 == constants.CLASS_FORMAT_INDEX: # read and painfully decode the format assert isinstance(w_val, model.W_SmallInteger) classformat = self.space.unwrap_int(w_val) # The classformat in Squeak, as an integer value, is: # <2 bits=instSize//64><5 bits=cClass><4 bits=instSpec> # <6 bits=instSize\\64><1 bit=0> # In Slang the value is read directly as a boxed integer, so that # the code gets a "pointer" whose bits are set as above, but # shifted one bit to the left and with the lowest bit set to 1. # Compute the instance size (really the size, not the number of bytes) instsize_lo = (classformat >> 1) & 0x3F instsize_hi = (classformat >> (9 + 1)) & 0xC0 self._instance_size = (instsize_lo | instsize_hi) - 1 # subtract hdr # decode the instSpec format = (classformat >> 7) & 15 self.instance_varsized = format >= 2 # In case of raised exception below. self.changed() if format < 4: self.instance_kind = POINTERS elif format == 4: self.instance_kind = WEAK_POINTERS elif format == 6: if self.space.w_Float.is_same_object(self.w_self()): self.instance_kind = FLOAT else: self.instance_kind = WORDS if self.instsize() != 0: raise ClassShadowError( "can't have both words and a non-zero " "base instance size") elif 8 <= format <= 11: if self.space.w_LargePositiveInteger.is_same_object( self.w_self()): self.instance_kind = LARGE_POSITIVE_INTEGER else: self.instance_kind = BYTES if self.instsize() != 0: raise ClassShadowError( "can't have both bytes and a non-zero " "base instance size") elif 12 <= format <= 15: self.instance_kind = COMPILED_METHOD else: raise ClassShadowError("unknown format %d" % (format, )) else: if w_self.w_class == self.space.classtable["w_Metaclass"]: # In case of Metaclasses, the "instance" class is stored in the last field. if n0 == self.size(w_self) - 1 and isinstance( w_val, model.W_PointersObject): cl_shadow = w_val.as_class_get_shadow(self.space) self.name = "%s class" % cl_shadow.getname() else: return elif n0 == constants.CLASS_NAME_INDEX: # In case of regular classes, the name is stored here. self.store_w_name(w_val) else: return # Some of the special info has changed -> Switch version. self.changed()
def __init__(self, space, w_self, size): self.subclass_s = {} AbstractCachingShadow.__init__(self, space, w_self, size)
def __init__(self, space, w_self, size): AbstractCachingShadow.__init__(self, space, w_self, size) self.invalid = False
def store(self, n0, w_val): AbstractCachingShadow.store(self, n0, w_val) if n0 == constants.CLASS_SUPERCLASS_INDEX: self.store_w_superclass(w_val) elif n0 == constants.CLASS_METHODDICT_INDEX: self.store_w_methoddict(w_val) elif n0 == constants.CLASS_FORMAT_INDEX: # read and painfully decode the format assert isinstance(w_val, model.W_SmallInteger) classformat = self.space.unwrap_int(w_val) # The classformat in Squeak, as an integer value, is: # <2 bits=instSize//64><5 bits=cClass><4 bits=instSpec> # <6 bits=instSize\\64><1 bit=0> # In Slang the value is read directly as a boxed integer, so that # the code gets a "pointer" whose bits are set as above, but # shifted one bit to the left and with the lowest bit set to 1. # Compute the instance size (really the size, not the number of bytes) instsize_lo = (classformat >> 1) & 0x3F instsize_hi = (classformat >> (9 + 1)) & 0xC0 self._instance_size = (instsize_lo | instsize_hi) - 1 # subtract hdr # decode the instSpec format = (classformat >> 7) & 15 self.instance_varsized = format >= 2 # In case of raised exception below. self.changed() if format < 4: self.instance_kind = POINTERS elif format == 4: self.instance_kind = WEAK_POINTERS elif format == 6: if self.space.w_Float.is_same_object(self.w_self()): self.instance_kind = FLOAT else: self.instance_kind = WORDS if self.instsize() != 0: raise ClassShadowError("can't have both words and a non-zero " "base instance size") elif 8 <= format <= 11: if self.space.w_LargePositiveInteger.is_same_object(self.w_self()): self.instance_kind = LARGE_POSITIVE_INTEGER else: self.instance_kind = BYTES if self.instsize() != 0: raise ClassShadowError("can't have both bytes and a non-zero " "base instance size") elif 12 <= format <= 15: self.instance_kind = COMPILED_METHOD else: raise ClassShadowError("unknown format %d" % (format,)) else: if self._w_self.w_class == self.space.classtable["w_Metaclass"]: # In case of Metaclasses, the "instance" class is stored in the last field. if n0 == self.size() - 1 and isinstance(w_val, model.W_PointersObject): cl_shadow = w_val.as_class_get_shadow(self.space) self.name = "%s class" % cl_shadow.getname() else: return elif n0 == constants.CLASS_NAME_INDEX: # In case of regular classes, the name is stored here. self.store_w_name(w_val) else: return # Some of the special info has changed -> Switch version. self.changed()