codefrau / SqueakJS

A Squeak Smalltalk VM in Javascript
https://squeak.js.org
MIT License
364 stars 75 forks source link

Improve isAssociation() in vm.primitives.js #125

Open ccrraaiigg opened 3 years ago

ccrraaiigg commented 3 years ago

We have a Global in the special objects array, so we can be rather more specific in isAssociation(). This bit me when marshaling a complex object for use with the JS bridge.

codefrau commented 3 years ago

Alternatively, we could iterate through the array and make sure every entry is a 2-pointer object and the first of these 2 is a bytes object (ByteSymbol / ByteString).

ccrraaiigg commented 3 years ago

Hm, I still would have been bitten. Perhaps we could check both the old and new special objects array cases, and answer true if either of them is a match?

codefrau commented 3 years ago

Okay. We could try to find (and maybe cache) LookupKey class by following the superclass chain from the Processor global to the class that has only 1 instance variable:

(Smalltalk specialObjectsArray at: 4) class withAllSuperclasses collect: [:c | c -> c instSize] 

Global->2 Binding->1 LookupKey->1 Magnitude->0 Object->0 ProtoObject->0

Association->2 LookupKey->1 Magnitude->0 Object->0 

So maybe something like

  1. LookupKey = starting at schedAssoc.sqClass, go up superclass chain until we find a class satisfying cls.pointers[0].classInstSize() === 0
  2. Object in question is an Association if its superclass is LookupKey and it has 2 inst vars.