[squeak-dev] primitiveClass infected after primitiveIdentityHash on wrong receiver

Eliot Miranda eliot.miranda at gmail.com
Tue Dec 28 19:13:50 UTC 2021

On Dec 28, 2021, at 9:02 AM, Christoph.Thiede at student.hpi.uni-potsdam.de wrote:
> Hi Eliot, Hi all,
> the following snippet returns an unexpected result to me cross-platform (tested with 202112201228 on Win 21H1 and WSL/Ubuntu 18.04):
>     ProtoObject tryPrimitive: 75 withArgs: #().
>     thisContext objectClass: ProtoObject basicNew. "nil"
> The example needs to be run in a fresh image. If primitiveBehaviorHash was sent to ProtoObject before, the bug does not occur:
>     ProtoObject tryPrimitive: 175 withArgs: #().
>     ProtoObject tryPrimitive: 75 withArgs: #().
>     thisContext objectClass: ProtoObject basicNew. "ProtoObject"

Thanks, Christoph!  Very very nice!  Ouch.

> I'm not sure whether this should be classified as a bug.

But it is :-)

> On the one hand, the name and the implementors of primitiveIdentityHash make pretty clear that one should not invoke it with a behavior. On the other hand, incidents like this make the usage of primitives extremely hard.
> I was writing a mirror primitive method that used primitiveIdentityHash in the first run and only falled back to primitiveBehaviorHash if the former failed [1]. Imagine how many hours it took me to trace a larger segfaulting test suite back to this unexpected behavior of primitiveClass. :-)
> In my expectation, primitiveIdentityHash should consequently fail for unappropriate receivers. However, I have fixed my mirror implementation now and only wanted to let you know about this observation.

The issue is how efficiently to determine that primitive 75 is being invoked on a behavior.  Luckily this determination doesn’t need to be made if the argument count is zero, so the common case is unaffected.

One style in HPS, the VisualWorks VM, is to look up a message via the method lookup class. So one would lookup #identityHash or #basicNew in the class of the argument, and if it bound to a method with primitive 175 or 70 respectively, then the argument is a behaviour, and the test is much cheaper if executed subsequently.  But to do this the primitive must be able to get at #identityHash or #basicNew.  Neither of these is close to hand.

I’ll have a root around and a think and see what I can come up with.

> Best,
> Christoph
> [1] Pointer if you want to read up to bloody details by yourself: https://github.com/LinqLover/SimulationStudio/pull/34/commits/0a55a8a23b6e842548049c07cbd96120a30cd06e
> ---
> Sent from Squeak Inbox Talk
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211228/640cc334/attachment.html>

More information about the Squeak-dev mailing list