<p>Comparison of SmallInteger and Float is simple in Spur32, we just have to convert the SmallInteger to a (double), which is an exact operation, and perform the comparison of (double).</p>
<p>But it's more tricky in Spur64 because SmallInteger has more precision (61 bits) than Float (53 bits) and thus conversion to (double) might be inexact...</p>
<p>Example:</p>
<pre><code>si := 1<<(Float precision + 2)+1.
sf := si asFloat.
self deny: sf = si.
self deny: si = sf.
</code></pre>
<p>It's not obvious to find where the trick happens in the VM, because all code at upper level is equivalent to trivial asFloat conversion followed by comparison, and there are many possible path!</p>
<p>Let's concentrate on <=</p>
<p>SmallInteger receiver:</p>
<ul>
<li>#primitiveLessOrEqual</li>
<li>#genPrimitiveLessOrEqual (JIT)<br>
BoxedFloat64 receiver:</li>
<li>#primitiveFloatLessOrEqual</li>
<li>#genPrimitiveFloatLessOrEqual (JIT)<br>
SmallFloat64 receiver:</li>
<li>#primitiveSmallFloatLessOrEqual</li>
<li>#genPrimitiveSmallFloatLessOrEqual (JIT)<br>
All receivers (non jitted sender or stack VM only?):</li>
<li>#bytecodePrimLessOrEqual</li>
</ul>
<p>For generated C code, the protection is programmed in lower level #loadFloatOrIntFrom:</p>
<p>To check that it does not exceed 53 bits, we shift the integer left << and forth >> and verify integrity. If not, we fail the primitive.<br>
With shift length as programmed currently, the primitive will fail for 52 bits and above. It should fail for 54 bits and above, but that's a detail, the primitive will fail more often than necessary...</p>
<p>The problem is that there is no such exactness check for jitted primitives!</p>
<p>I have sketched a solution in Squeak inbox (See <a href="http://source.squeak.org/inbox/Kernel-nice.1260.diff" rel="nofollow">http://source.squeak.org/inbox/Kernel-nice.1260.diff</a>), demonstrated here for SmallInteger <=</p>
<pre><code>^(asFloat := self asFloat) = aNumber
     ifTrue: [self <= aNumber truncated]
     ifFalse: [asFloat <= aNumber]
</code></pre>
<p>In C code that is:</p>
<pre><code>if ( (double) si == sf ) return si <= (int64) sf;
else return (double) si <= sf;
</code></pre>
<p>It works for all the comparisons (though = and ~= could be a bit simpler, no need to perform the comparison twice).</p>
<p>And it's simple enough to be jitted (I have prototyped it this evening).</p>

<p style="font-size:small;-webkit-text-size-adjust:none;color:#666;">—<br />You are receiving this because you are subscribed to this thread.<br />Reply to this email directly, <a href="https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/417?email_source=notifications&email_token=AIJPEW7RSEAEH4M5ODAMYBTQFSC2HA5CNFSM4IN66INKYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HGMEGLA">view it on GitHub</a>, or <a href="https://github.com/notifications/unsubscribe-auth/AIJPEW5EG6XB3XPJANWZYJLQFSC2HANCNFSM4IN66INA">mute the thread</a>.<img src="https://github.com/notifications/beacon/AIJPEW25DA5E6BX5LXVPWLDQFSC2HA5CNFSM4IN66INKYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HGMEGLA.gif" height="1" width="1" alt="" /></p>
<script type="application/ld+json">[
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"potentialAction": {
"@type": "ViewAction",
"target": "https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/417?email_source=notifications\u0026email_token=AIJPEW7RSEAEH4M5ODAMYBTQFSC2HA5CNFSM4IN66INKYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HGMEGLA",
"url": "https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/417?email_source=notifications\u0026email_token=AIJPEW7RSEAEH4M5ODAMYBTQFSC2HA5CNFSM4IN66INKYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HGMEGLA",
"name": "View Issue"
},
"description": "View this Issue on GitHub",
"publisher": {
"@type": "Organization",
"name": "GitHub",
"url": "https://github.com"
}
}
]</script>