Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.239.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.239 Author: eem Time: 18 December 2012, 10:35:18.772 am UUID: 3087e16d-bf3c-4fdc-b2ec-14791deff66f Ancestors: VMMaker.oscog-eem.238
Third time lucky. Fix bug in changeClass:from: so that if receiver has long header and class is compact, receiver still gets compact class field set, not cleared. No matter what header an instance has, if its class is compact it should have the compact class index set.
=============== Diff against VMMaker.oscog-eem.238 ===============
Item was changed: ----- Method: ObjectMemory>>changeClassOf:to: (in category 'interpreter access') ----- changeClassOf: rcvr to: argClass "Attempt to change the class of the receiver into the class of the the argument given that the format of the receiver matches the format of the argument. If successful answer 0, otherwise answer an error code indicating the reason for failure. Fail if receiver or argument are SmallIntegers, or the receiver is an instance of a compact class and the argument isn't, or when the format of the receiver is different from the format of the argument's class, or when the arguments class is fixed and the receiver's size differs from the size that an instance of the argument's class should have." | classHdr sizeHiBits byteSize argFormat rcvrFormat rcvrHdr ccIndex | "Check what the format of the class says" classHdr := self formatOfClass: argClass. "Low 2 bits are 0"
"Compute the size of instances of the class (used for fixed field classes only)" sizeHiBits := (classHdr bitAnd: 16r60000) >> 9. classHdr := classHdr bitAnd: 16r1FFFF. byteSize := (classHdr bitAnd: SizeMask) + sizeHiBits. "size in bytes -- low 2 bits are 0"
"Check the receiver's format against that of the class" argFormat := self formatOfHeader: classHdr. rcvrHdr := self baseHeader: rcvr. rcvrFormat := self formatOfHeader: rcvrHdr. "If the receiver is a byte object we need to clear the number of odd bytes from the format." rcvrFormat > 8 ifTrue: [rcvrFormat := rcvrFormat bitAnd: 16rC]. argFormat = rcvrFormat ifFalse: [^PrimErrInappropriate]. "no way"
"For fixed field classes, the sizes must match. Note: byteSize-4 because base header is included in class size." argFormat < 2 ifTrue: [(byteSize - BaseHeaderSize) ~= (self byteSizeOf: rcvr) ifTrue: [^PrimErrBadReceiver]] ifFalse: [argFormat = 3 ifTrue: "For indexable plus fixed fields the receiver must be at least big enough." [(byteSize - BaseHeaderSize) > (self byteSizeOf: rcvr) ifTrue: [^PrimErrBadReceiver]]].
ccIndex := classHdr bitAnd: CompactClassMask. (self headerTypeOfHeader: rcvrHdr) = HeaderTypeShort ifTrue: "Compact classes. Check if the arg's class is compact and exchange ccIndex" [ccIndex = 0 ifTrue: [^PrimErrInappropriate]. "class is not compact" self cppIf: IMMUTABILITY ifTrue: [(rcvrHdr bitAnd: ImmutabilityBit) ~= 0 ifTrue: [^PrimErrNoModification]]. self baseHeader: rcvr put: (((self longAt: rcvr) bitClear: CompactClassMask) bitOr: ccIndex)] ifFalse: "Exchange the class pointer, which could make rcvr a root for argClass. Don't forget to set ccIndex." [self cppIf: IMMUTABILITY ifTrue: [(rcvrHdr bitAnd: ImmutabilityBit) ~= 0 ifTrue: [^PrimErrNoModification]]. + self baseHeader: rcvr + put: (((self baseHeader: rcvr) bitClear: CompactClassMask) bitOr: ccIndex). - (self compactClassIndexOf: rcvr) ~= 0 ifTrue: - [self baseHeader: rcvr - put: (((self baseHeader: rcvr) bitClear: CompactClassMask) bitOr: ccIndex)]. self longAt: rcvr-BaseHeaderSize put: (argClass bitOr: (self headerType: rcvr)). (self oop: rcvr isLessThan: youngStart) ifTrue: [self possibleRootStoreInto: rcvr value: argClass]]. "ok" ^0!
vm-dev@lists.squeakfoundation.org