I repost the mail to the mailing-list since I do not see it in the vm-dev

Stef

> 
> Hi 
> 
> I was reading the following method in the VM code and I have a couple of 
> questions:
> 
> - I do not understand why lookupMethodInClass: may return a class. I was 
> thinking that it would return a method.
> 
> - what is the invariant? 
>       that currentclass always point to the currently looked up class and 
>       newMethod is the found method?
> 
> - why lookupMethodFor: selector InDictionary: dictionary is defined in 
> StackInterpreter but never used
> only in CoInterpreter?
> 
> Thanks
> 
> 
> lookupMethodInClass: class
>       | currentClass dictionary found |
>       <inline: false>
>       self assert: class ~= objectMemory nilObject.
>       currentClass := class.
>       [currentClass ~= objectMemory nilObject]
>               whileTrue:
>               [dictionary := objectMemory fetchPointer: MethodDictionaryIndex 
> ofObject: currentClass.
> 
>               *** trick with the cannotInterpret ***
>               dictionary = objectMemory nilObject ifTrue:
>                       ["MethodDict pointer is nil (hopefully due a swapped 
> out stub)
>                               -- raise exception #cannotInterpret:."
>                       self createActualMessageTo: class.
>                       messageSelector := objectMemory splObj: 
> SelectorCannotInterpret.
>                       self sendBreak: messageSelector + BaseHeaderSize
>                               point: (objectMemory lengthOf: messageSelector)
>                               receiver: nil.
>                       ^self lookupMethodInClass: (self superclassOf: 
> currentClass)].
>               *** trick with the cannotInterpret end ***
> 
>               found := self lookupMethodInDictionary: dictionary.
>               found ifTrue: [^currentClass].
>                       ^^^^^^^^^^^^^^^^^^^^^^^^^
> 
>               currentClass := self superclassOf: currentClass].
> 
>       "Could not find #doesNotUnderstand: -- unrecoverable error."
>       messageSelector = (objectMemory splObj: SelectorDoesNotUnderstand) 
> ifTrue:
>               [self error: 'Recursive not understood error encountered'].
> 
>       "Cound not find a normal message -- raise exception #doesNotUnderstand:"
>       self createActualMessageTo: class.
>       messageSelector := objectMemory splObj: SelectorDoesNotUnderstand.
>       self sendBreak: messageSelector + BaseHeaderSize
>               point: (objectMemory lengthOf: messageSelector)
>               receiver: nil.
>       ^self lookupMethodInClass: class
> 
> 
> if (found) {
>       return currentClass;
>       }
> 
> 
> static sqInt
> lookupMethodInClass(sqInt class)
> {
>       // StackInterpreter>>#lookupMethodInClass:   DECL_MAYBE_SQ_GLOBAL_STRUCT
>     sqInt currentClass;
>     sqInt dictionary;
>     sqInt found;
>     sqInt header;
>     sqInt index;
>     sqInt length;
>     sqInt mask;
>     sqInt methodArray;
>     sqInt nextSelector;
>     sqInt sz;
>     sqInt wrapAround;
> 
>       assert(class != (nilObject()));
>       currentClass = class;
>       while (currentClass != GIV(nilObj)) {
> dictionary = longAt((currentClass + BaseHeaderSize) + (MethodDictionaryIndex 
> << ShiftForWord));
>               if (dictionary == GIV(nilObj)) {
> 
>                       /* ifTrue: */
> 
> createActualMessageTo(class);
>                       GIV(messageSelector) = longAt((GIV(specialObjectsOop) + 
> BaseHeaderSize) + (SelectorCannotInterpret << ShiftForWord));
>                       sendBreakpointreceiver(GIV(messageSelector) + 
> BaseHeaderSize, lengthOf(GIV(messageSelector)), null);
>                       return lookupMethodInClass(longAt((currentClass + 
> BaseHeaderSize) + (SuperclassIndex << ShiftForWord)));
>               }
>               /* begin lookupMethodInDictionary: */
> /* begin fetchWordLengthOf: */
> /* begin sizeBitsOf: */
> header = longAt(dictionary);
>               sz = ((header & TypeMask) == HeaderTypeSizeAndClass
>                       ? (longAt(dictionary - (BytesPerWord * 2))) & 
> LongSizeMask
>                       : header & SizeMask);
>               length = ((usqInt) (sz - BaseHeaderSize)) >> ShiftForWord;
>               mask = (length - SelectorStart) - 1;
> 
>               /* messageSelector */
> 
> index = SelectorStart + (mask & (((GIV(messageSelector) & 1)
>       ? (GIV(messageSelector) >> 1)
>       : (((usqInt) (longAt(GIV(messageSelector)))) >> HashBitsOffset) & 
> HashMaskUnshifted)));
>               wrapAround = 0;
>               while (1) {
> nextSelector = longAt((dictionary + BaseHeaderSize) + (index << 
> ShiftForWord));
>                       if (nextSelector == GIV(nilObj)) {
> found = 0;
>                               goto l1;
>                       }
>                       if (nextSelector == GIV(messageSelector)) {
> methodArray = longAt((dictionary + BaseHeaderSize) + (MethodArrayIndex << 
> ShiftForWord));
>                               GIV(newMethod) = longAt((methodArray + 
> BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord));
>                               found = 1;
>                               goto l1;
>                       }
>                       index += 1;
>                       if (index == length) {
> if (wrapAround) {
> found = 0;
>                                       goto l1;
>                               }
>                               wrapAround = 1;
>                               index = SelectorStart;
>                       }
>               }
> found = 0;
>       l1:     /* end lookupMethodInDictionary: */;
>               if (found) {
> return currentClass;
>               }
>               currentClass = longAt((currentClass + BaseHeaderSize) + 
> (SuperclassIndex << ShiftForWord));
>       }
> if (GIV(messageSelector) == (longAt((GIV(specialObjectsOop) + BaseHeaderSize) 
> + (SelectorDoesNotUnderstand << ShiftForWord)))) {
>               error("Recursive not understood error encountered");
>       }
>       createActualMessageTo(class);
>       GIV(messageSelector) = longAt((GIV(specialObjectsOop) + BaseHeaderSize) 
> + (SelectorDoesNotUnderstand << ShiftForWord));
>       sendBreakpointreceiver(GIV(messageSelector) + BaseHeaderSize, 
> lengthOf(GIV(messageSelector)), null);
>       return lookupMethodInClass(class);
> }
> 
> 
> 
> 

Reply via email to