<div dir="ltr"><div><div>Hi David,<br>Sorry, I've no linux/mac vm available currently to exhibit the problem.<br>But if you look at github head revision<br><br><a href="https://raw.githubusercontent.com/OpenSmalltalk/opensmalltalk-vm/Cog/spur64src/vm/gcc3x-cointerp.c">https://raw.githubusercontent.com/OpenSmalltalk/opensmalltalk-vm/Cog/spur64src/vm/gcc3x-cointerp.c</a><br><br>then you'll find this code:<br><pre>primitiveIntegerAt(void)
{   DECL_MAYBE_SQ_GLOBAL_STRUCT
    sqInt addr;
... snip declarations of no interest ...
    sqInt value;
<br>... snip long preamble to check parameter types ...

        /* for zero indexing */
        addr = (rcvr + BaseHeaderSize) + ((index - 1) * 4);
        value = intAt(addr);
        /* begin pop: */
        GIV(stackPointer) += 2 * BytesPerWord;
        if ((((((usqInt) value) >> 60) + 1) & 15) <= 1) {
                /* begin pushInteger: */
                longAtput((sp = GIV(stackPointer) - BytesPerWord), ((value << 3) | 1));
                GIV(stackPointer) = sp;
        }
        else {
... snip this branch is never reached ...
        }
}</pre>Above code clearly can't work if the 32bit contents of addr is not sign-extended into the 64bits value...<br>So I don't know which version you used exactly,<br></div>...UNLESS... <br>there might be another reason for the mismatch in:<br><br><a href="https://github.com/OpenSmalltalk/opensmalltalk-vm/blob/Cog/platforms/Cross/vm/sqMemoryAccess.h">https://github.com/OpenSmalltalk/opensmalltalk-vm/blob/Cog/platforms/Cross/vm/sqMemoryAccess.h</a><br><br></div>You can see that the two possible compiler branches don't agree and won't behave the same sign-wise:<br><pre>#ifdef USE_INLINE_MEMORY_ACCESSORS
  /* Use static inline functions when the compiler produces efficient code for small accessors.
     These are preferred because static type checking will prevent inadvertent confusion of pointers and oops. */
... snip ...
  static inline sqInt intAtPointer(char *ptr)                   { return (sqInt)(*((unsigned int *)ptr)); }
  static inline sqInt intAtPointerput(char *ptr, int val)       { return (sqInt)(*((unsigned int *)ptr)= val); }<br>... snip ...
</pre><pre>#else /* USE_INLINE_MEMORY_ACCESSORS */
  /* Use macros when static inline functions aren't efficient. */
... snip ...<br># define intAtPointer(ptr)                        ((sqInt)(*((int *)(ptr))))
# define intAtPointerput(ptr,val)       ((sqInt)(*((int *)(ptr))= (int)(val)))<br>... snip ...<br>#endif /* USE_INLINE_MEMORY_ACCESSORS */
</pre><div><div><div><div>I presume you (or someone else) arranged to not  USE_INLINE_MEMORY_ACCESSORS</div><div>Though it seems to be the default to use them on macosx (I'm just invoking ./mvm).<br><br></div><div>The two branches should better adopt the same (sane) behavior, shouldn't they?<br></div></div></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">2016-11-08 14:23 GMT+01:00 David T. Lewis <span dir="ltr"><<a href="mailto:lewis@mail.msen.com" target="_blank">lewis@mail.msen.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
On Tue, Nov 08, 2016 at 03:29:05AM +0100, Nicolas Cellier wrote:<br>
><br>
> In this code:<br>
><br>
>   static inline sqInt intAtPointer(char *ptr)   { return<br>
> (sqInt)(*((unsigned int *)ptr)); }<br>
>   static inline sqInt intAtPointerput(char *ptr, int val)  { return<br>
> (sqInt)(*((unsigned int *)ptr)= val); }<br>
><br>
> the usage of unsigned int is questionable...<br>
> It means that intAt and long32At won't perform sign extension in 64bits<br>
> Spur VM.<br>
> Since it returns a signed result (sqInt), that's troubling.<br>
><br>
> The sole real sender of intAt seems to be primitiveIntegerAt: which fails<br>
> for this reason on 64bits spur when fed with negative integers.<br>
<br>
<br>
</span>Can you give an example of the failure? I tried on 64-bit Spur and also<br>
on image format 68002 (64-bit V3) on Linux, and the accesses to elements<br>
of an IntegerArray work correctly in both cases.<br>
<br>
<br>
For example:<br>
<br>
{ -1 . -2 . -3 . -4 . 7 . -9 } asIntegerArray ==> an IntegerArray(-1 -2 -3 -4 7 -9)<br>
<br>
Accessing the elements of this IntegerArray works as expected, and I can see<br>
in an inspector that the first element is stored internally as 16rFFFFFFFF.<br>
<br>
Is there something else that is failing?<br>
<br>
Dave<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
><br>
> For long32At, it's difficult to analyze: many senders!<br>
><br>
> IMO, if we don't want a signed quantity, we should better write<br>
> unsignedLong32At (or use lowcode uint32AtPointer which answers a 32 bits<br>
> result)<br>
<br>
</div></div></blockquote></div><br></div>