<br><br><div class="gmail_quote">On Sun, Oct 26, 2008 at 6:21 AM, Klaus D. Witzel <span dir="ltr">&lt;<a href="mailto:klaus.witzel@cobss.com">klaus.witzel@cobss.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="Ih2E3d">On Sun, 26 Oct 2008 13:39:04 +0100, Andreas Raab wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi Frederic -<br>
<br>
Congrats! You found the first real VM bug in five years or so ;-) I&#39;m not completely sure what the problem is but there is obviously something wrong here. It&#39;s easiest to recreate the problem by copying the #/ method and simply do something like:<br>

<br>
SmallInteger&gt;&gt;foo: aNumber<br>
 &nbsp; &nbsp; &nbsp; &nbsp;&quot;(SmallInteger&gt;&gt;#foo:) valueWithReceiver: 11 arguments: {2}&quot;<br>
 &nbsp; &nbsp; &nbsp; &nbsp;&lt;primitive: 10&gt;<br>
self halt.<br>
 &nbsp; &nbsp; &nbsp; &nbsp;aNumber isZero ifTrue: [^(ZeroDivide dividend: self) signal].<br>
 &nbsp; &nbsp; &nbsp; &nbsp;(aNumber isMemberOf: SmallInteger)<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ifTrue: [^(Fraction numerator: self denominator: aNumber) reduced]<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ifFalse: [^super / aNumber]<br>
<br>
When you run this, you&#39;ll see that the debugger shows *two* frames with SmallInteger&gt;&gt;foo: on them. Inspecting the &quot;parent&quot; frame will eventually crash the system since it has a completely bogus stack pointer (-1).<br>

<br>
It seems that in a failing primitive method we end up with a bogus activation record in primitiveExecMethodWithArgs (removing the primitive from the above makes it work fine). I&#39;m somewhat at a loss here as to what the problem might be given that the implementations of primPerformWithArgs and primExecWithArgs are so similar but interestingly, the equivalent:<br>

<br>
 &nbsp; &nbsp; &nbsp; &nbsp;11 perform: #foo: withArguments:{2}.<br>
<br>
works fine with or without the primitive. Somewhere there must be a difference ...<br>
</blockquote>
<br></div>
The difference can be this: #primitiveExecuteMethod is called as part of #primitiveResponse, and in turn calls #executeNewMethod which again does #primitiveResponse. If the latter does #primitiveFail, the now *two* activations of #primitiveResponse want to handle the situation - without knowing from each other.<br>

<br>
Perhaps #primitiveExecuteMethod should end with an explicit [ ... ^ self success: true] in its true-branch (this is just a thought, I have as yet not looked deeper).</blockquote><div><br></div><div>I think you&#39;re exactly right. &nbsp;This fixes it for me.</div>
<div><br></div><div>Thanks!</div><div><br></div><div>&nbsp;</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Besides: if #primitiveExecuteMethod would do its own #primitiveFail, it looks like its arguments are no longer on the stack.<br>

<br>
/Klaus<div><div></div><div class="Wj3C7c"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Cheers,<br>
 &nbsp; - Andreas<br>
<br>
Frederic Pluquet wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hello,<br>
&nbsp;I found a fondamental bug in Squeak and Pharo. The next code<br>
&nbsp;11 / 2 &nbsp;gives the fraction (11/2). It&#39;s correct. But the next code<br>
&nbsp;(SmallInteger&gt;&gt;#/) valueWithReceiver: 11 arguments: {2}<br>
&nbsp;gives 1 !<br>
&nbsp;The problem is the method valueWithReceiver:arguements: is used hugely with method wrappers...<br>
&nbsp;After long time of debugging, I found a point to debug: this method don&#39;t have the good behavior with compiled methods having a primitive that fails and executes some code after (as in SmallInteger&gt;&gt;#/ method when the division don&#39;t give a whole integer). In fact, when I send this message, the vm executes normally the compiled method but, in place of returns simply the good result, seems to rerun the the compiled method with other arguments (completly wrong) and returns so a wrong result.<br>

&nbsp;For example, (SmallInteger&gt;&gt;#/) valueWithReceiver: 11 arguments: {2}<br>
&nbsp;has the following execution trace :<br>
&nbsp;2 isZero<br>
| &nbsp;2 = 0<br>
| &nbsp;returns: false<br>
returns: false<br>
2 isMemberOf: SmallInteger<br>
| &nbsp;2 class<br>
| &nbsp;returns: SmallInteger<br>
| &nbsp;SmallInteger == SmallInteger<br>
| &nbsp;returns: true<br>
returns: true<br>
Fraction numerator: 101 denominator: 2<br>
| &nbsp;Fraction new<br>
| &nbsp;| &nbsp;Fraction basicNew<br>
| &nbsp;| &nbsp;returns: a Fraction instance<br>
| &nbsp;| &nbsp;(a Fraction instance) initialize<br>
| &nbsp;| &nbsp;returns: a Fraction instance<br>
| &nbsp;returns: a Fraction instance<br>
| &nbsp;a Fraction instance setNumerator: 101 denominator: 2<br>
| &nbsp;| &nbsp;2 = 0<br>
| &nbsp;| &nbsp;returns: false<br>
| &nbsp;| &nbsp;101 asInteger<br>
| &nbsp;| &nbsp;returns: 101<br>
| &nbsp;| &nbsp;2 asInteger<br>
| &nbsp;| &nbsp;returns: 2<br>
| &nbsp;| &nbsp;2 abs<br>
| &nbsp;| &nbsp;| &nbsp;2 &lt; 0<br>
| &nbsp;| &nbsp;| &nbsp;returns: false<br>
| &nbsp;| &nbsp;returns: 2<br>
| &nbsp;| &nbsp;2 &lt; 0<br>
| &nbsp;| &nbsp;returns: false<br>
| &nbsp;returns: (101/2)<br>
returns: (101/2)<br>
(101/2) reduced<br>
| &nbsp;101 = 0<br>
| &nbsp;returns: false<br>
| &nbsp;101 gcd: 2<br>
| &nbsp;| &nbsp;101 = 0<br>
| &nbsp;| &nbsp;returns: false<br>
| &nbsp;| &nbsp;2 \\ 101<br>
| &nbsp;| &nbsp;returns: 2<br>
| &nbsp;| &nbsp;2 = 0<br>
| &nbsp;| &nbsp;returns: false<br>
| &nbsp;| &nbsp;101 \\ 2<br>
| &nbsp;| &nbsp;returns: 1<br>
| &nbsp;| &nbsp;1 = 0<br>
| &nbsp;| &nbsp;returns: false<br>
| &nbsp;| &nbsp;2 \\ 1<br>
| &nbsp;| &nbsp;returns: 0<br>
| &nbsp;| &nbsp;0 = 0<br>
| &nbsp;| &nbsp;returns: true<br>
| &nbsp;| &nbsp;1 abs<br>
| &nbsp;| &nbsp;| &nbsp;1 &lt; 0<br>
| &nbsp;| &nbsp;| &nbsp;returns: false<br>
| &nbsp;| &nbsp;returns: 1<br>
| &nbsp;returns: 1<br>
| &nbsp;101 // 1<br>
| &nbsp;returns: 101<br>
| &nbsp;2 // 1<br>
| &nbsp;returns: 2<br>
| &nbsp;2 = 1<br>
| &nbsp;returns: false<br>
| &nbsp;Fraction numerator: 101 denominator: 2<br>
| &nbsp;| &nbsp;Fraction new<br>
| &nbsp;| &nbsp;| &nbsp;Fraction basicNew<br>
| &nbsp;| &nbsp;| &nbsp;returns: a Fraction instance<br>
| &nbsp;| &nbsp;| &nbsp;(a Fraction instance) initialize<br>
| &nbsp;| &nbsp;| &nbsp;returns: a Fraction instance<br>
| &nbsp;| &nbsp;returns: a Fraction instance<br>
| &nbsp;| &nbsp;(a Fraction instance) setNumerator: 101 denominator: 2<br>
| &nbsp;| &nbsp;| &nbsp;2 = 0<br>
| &nbsp;| &nbsp;| &nbsp;returns: false<br>
| &nbsp;| &nbsp;| &nbsp;101 asInteger<br>
| &nbsp;| &nbsp;| &nbsp;returns: 101<br>
| &nbsp;| &nbsp;| &nbsp;2 asInteger<br>
| &nbsp;| &nbsp;| &nbsp;returns: 2<br>
| &nbsp;| &nbsp;| &nbsp;2 abs<br>
| &nbsp;| &nbsp;| &nbsp;| &nbsp;2 &lt; 0<br>
| &nbsp;| &nbsp;| &nbsp;| &nbsp;returns: false<br>
| &nbsp;| &nbsp;| &nbsp;returns: 2<br>
| &nbsp;| &nbsp;| &nbsp;2 &lt; 0<br>
| &nbsp;| &nbsp;| &nbsp;returns: false<br>
| &nbsp;| &nbsp;returns: (101/2)<br>
| &nbsp;returns: (101/2)<br>
returns: (101/2)<br>
2 isZero<br>
| &nbsp;2 = 0<br>
| &nbsp;returns: false<br>
returns: false<br>
false isMemberOf: SmallInteger<br>
| &nbsp;false class<br>
| &nbsp;returns: False<br>
| &nbsp;False == SmallInteger<br>
| &nbsp;returns: false<br>
returns: false<br>
 &nbsp;Please help me to fix this bug. I really need it works fine !<br>
&nbsp;Fréd<br>
-- Frédéric Pluquet<br>
Université Libre de Bruxelles (ULB)<br>
Assistant<br>
<a href="http://www.ulb.ac.be/di/fpluquet" target="_blank">http://www.ulb.ac.be/di/fpluquet</a><br>
 &nbsp;------------------------------------------------------------------------<br>
<br>
</blockquote>
<br>
<br>
<br>
</blockquote>
<br>
<br>
<br></div></div><font color="#888888">
-- <br>
"If at first, the idea is not absurd, then there is no hope for it". Albert Einstein<br>
<br>
<br>
</font></blockquote></div><br>