� � I just got a little burned. �I was searching through an Array of symbols and integers (it is the PrimitiveTable from the VM), wanting to filter-out methods with a with a certain pragma. �The code looks like:
anArray doWithIndex:
[:entry :index|
(self whichClassIncludesSelector: entry) ifNotNil:
[:c| | m |
m := c >> entry.
(m pragmaAt: #option:) ifNotNil:
[:pragma|
(initializationOptions at: (pragma arguments first) ifAbsent: [true]) ifFalse:
[anArray at: index put: 0]]]]
the error was a keyNotFound error for c >> entry. �Turns out entry was the integer 306, a code for a quick primitive that returns some inst var. �The question is why did�(self whichClassIncludesSelector: entry) evaluate to other than nil given that 306 is /not/ a selector in any of the classes from self on up. �Well, it's MethodDictionary's use of pointsTo: that is at fault:
MethodDictionary>>includesKey: aSymbol
"This override assumes that pointsTo is a fast primitive"
aSymbol ifNil: [^ false].
^ self pointsTo: aSymbol
ProtoObject>>pointsTo: anObject
"This method returns true if self contains a pointer to anObject,
and returns false otherwise"
<primitive: 132>
1 to: self class instSize do:
[:i | (self instVarAt: i) == anObject ifTrue: [^ true]].
1 to: self basicSize do:
[:i | (self basicAt: i) == anObject ifTrue: [^ true]].
^ false
Turns out that 306 was the tally of one of the method dictionaries along self's superclass chain. �This seems to be to be completely bogus. �Do we really need crude performance hacks like this any more?
--
best,Eliot