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);
> }
>
>
>
>