Hi Henry,

On Wed, Aug 16, 2017 at 9:04 PM, henry <henry@callistohouse.club> wrote:
To let you know what I tried, trying to learn about this system as I dig into it, I added isInteger to the #blockedSelectors of NearERef. This crashed the squeak vm when I ran the test, and as I look into how blockedSelectors is used it smashes the resolver. What seems to be needed is a list of immediateSelectors, though that may grow to be a sizeable list. This causes me to think there must be a different approach between async and sync code.

Please wait until mustBeBooleanMagic: is fixed before you write this off.�� In Squeak what happens if you implement mustBeBoolean to resolve the promise?
��

- HH


-------- Original Message --------
Subject: Re: [Vm-dev] [Pharo-dev] eventual crashes pharo vm
Local Time: August 16, 2017 11:46 PM
UTC Time: August 17, 2017 3:46 AM
From: henry@callistohouse.club
To: Eliot Miranda <eliot.miranda@gmail.com>
Squeak Virtual Machine Development Discussion <vm-dev@lists.squeakfoundation.org>, Pharo Development List <pharo-dev@lists.pharo.org>, Marcus Denker <marcus.denker@inria.fr>

Hi Eliot,

I have disabled that test for the time being. It will require some deeper thought regarding immediate selectors, I think, and I am deep into another area right now. As mustBeBoolean is from inside the VM, a different approach may be the right solution. A part of me thinks autocoercion between msg sending (async) and msg calling (sync) is what is needed, but I want continuation-based VatSemaphores to prevent a liveness lock on the event loop to support. Again, I have not thought deep enough in this area.

Thanks again for your help,

- HH


-------- Original Message --------
Subject: Re: [Pharo-dev] eventual crashes pharo vm
Local Time: August 16, 2017 10:32 PM
UTC Time: August 17, 2017 2:32 AM
To: henry <henry@callistohouse.club>
Marcus Denker <marcus.denker@inria.fr>, Pharo Development List <pharo-dev@lists.pharo.org>, Squeak Virtual Machine Development Discussion <vm-dev@lists.squeakfoundation.org>

Hi Henry,

On Wed, Aug 16, 2017 at 6:33 PM, henry <henry@callistohouse.club> wrote:
That is good news, that it is due to this code doing funniness than a VM issue. This code trying to bring asynchrony within a synchronous environment brings new issues.

What do you think that right solution is to the issue of a call expected��to be immediate, change��out to go eventual until the arguments resolve?

I'm not informed enough to know.�� One could implement mustBeBoolean in the ERef hierarchy and resolve the promise before going on.�� One could rely on the mustBeBooleanMagic: if one wanted a fully lazy system.�� I don't know the trade-offs between the two.�� I do know that while the miustBeBooleanMagic: solution is cool and fun it is extremely slow.�� So if performance is an issue use the first approach.

��
How can it be structured correctly on the stack without generic functions? I think with the double dispatch of an eventual but I have not spend much time in this particular area.

Yes that's an issue ��There is already a problem with #==.�� It needs to be symmetric for correctness.
��
Preventing the vm from crashing would be a good interim step but even here I am not sure how to go about crafting a solution.��

Well, the issue is simply that the wrong pc is chosen for the continuation after the mustBeBoolean.�� I'm sure the right answer is straight-forward to obtain.

��
Thank you for investigating this.

You're welcome.
��


- HH


On Wed, Aug 16, 2017 at 20:46, Eliot Miranda <eliot.miranda@gmail.com> wrote:
Hi Henry, Hi Marcus,

On Sun, Aug 13, 2017 at 5:08 AM, henry <henry@callistohouse.club> wrote:

Hi all. I was testing with this eventual_test package and it blows up the pharo 6.1 vm. I'd welcome pointers


- HH

I took a look at this and I think you've found a bug in the mustBeBooleanMagic: code.�� What's happening is a mustBeBoolean in Integer>>* due to evaluating
�� �� 10 * 42 eventual
in RefsTest>>testFailureArithmeticPrimitivesWithPromiseArgument

Since 42 eventual is a��NearERef the SmallInteger>>* primitive fails and does ^super * anInteger (where anInteger is the NearERef).�� So that evaluates Integer>>*

Integer>>* aNumber
"Refer to the comment in Number * "��
aNumber isInteger ifTrue:
[^ self digitMultiply: aNumber��
neg: self negative ~~ aNumber negative].
^ aNumber adaptToInteger: self andSend: #*

aNumber, being a NearERef, answers a PromiseERef for the isInteger send, and this provokes a mustBeBoolean for the isInteger ifTrue: [...

After the mustBeBooleanMagic: the stack looks wrong. The activation of Integer>>*, which is about to do
�� �� ^ aNumber adaptToInteger: self andSend: #*
does not have enough items on the stack.�� Instead of containing
�� �� a NearERef (for 42)
�� �� 10
�� �� ��#*
it contains
�� �� a PromiseERef (for 42 eventual isInteger)

and the send of #adaptToInteger:andSend: ends up taking more form the stack than the VM can handle and it crashes.�� The bug appears to be with the use of sendNode irInstruction nextBytecodeOffsetAfterJump in Object>>mustBeBooleanMagic:��since execution should resume at bytecode 55 below, but does so at bytecode 57


41 <10> pushTemp: 0
42 <D0> send: isInteger
43 <AC 09> jumpFalse: 54
45 <70> self
46 <10> pushTemp: 0
47 <70> self
48 <D1> send: negative
49 <10> pushTemp: 0
50 <D1> send: negative
51 <E2> send: ~~
52 <F3> send: digitMultiply:neg:
53 <7C> returnTop
54 <10> pushTemp: 0
55 <70> self
56 <24> pushConstant: #*
57 <F5> send: adaptToInteger:andSend:
58 <7C> returnTop

So the positioning of the context's pc must be before any argument marshaling for the next send, not simply the send itself.

Put a breakpoint at the end of Object>>mustBeBooleanMagic: and add initlaPC and resumePC temporaries at the beginning and capture them via
�� �� initialPC := context pc.
at the beginning and then
context pc: (resumePC := sendNode irInstruction nextBytecodeOffsetAfterJump)
to see what I'm seeing.


Phew.�� Glad it's not a VM bug :-)

HTH
_,,,^..^,,,_
best,��Eliot




--
_,,,^..^,,,_
best,��Eliot





--
_,,,^..^,,,_
best,��Eliot