[dmd-internals] BUG? pointer slice failed in arch x86_64, but it works in win32

Lyra Chord via dmd-internals dmd-internals at puremagic.com
Sat Sep 16 00:03:36 PDT 2017


Hi, There is a pointer slice code.
It works in win32 mode. but failed in x86_64 arch.

I guess it's a bug?

Here is my code. It's a simple buffer which operate data on rows.
There last test case expect copy from this:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]

To get this reverted rows:
[24, 25, 26, 27, 28, 29, 30, 31, 16, 17, 18, 19, 20, 21, 22, 23, 
8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7]

`
module vg.buffer;

import std.math : abs;
import std.algorithm.comparison : min;

class Buffer(T)
{
     T[] buffer;
     uint width;
     uint height;
     T* start; //Pointer to the first pixel, depending on stride
     int stride; //number of bytes per row, can be <0

     void attach(T[] buffer, uint width, uint height, int stride)
     {
         assert(buffer.length == width * height * T.sizeof);
         this.buffer = buffer;
         this.width = width;
         this.height = height;
         this.stride = stride;
         if (stride < 0)
             start = buffer.ptr - (height - 1) * stride;
         else
             start = buffer.ptr;
     }

     @property uint strideAbs() const
     {
         return abs(stride);
     }

     T* rowPointer(int y)
     {
         return cast(T*)(start + y * stride);
     }

     T[] row(int y)
     {
         uint begin = stride < 0 ? cast(uint)(buffer.length + (1 + 
y) * stride) : y * stride;
         import std.stdio : writefln;

         writefln("begin =%s y=%s length=%s", begin, y, 
buffer.length);
         return buffer[begin .. begin + width];
     }

     void copyFrom(Buffer!T src)
     {
         uint h = min(height, src.height);
         uint length = min(strideAbs(), src.strideAbs());
         length *= T.sizeof;

         import std.stdio : writefln;

         writefln("byte length %s  buffer: this %s, src %s", 
length, buffer.ptr, src.buffer.ptr);
         writefln("this start %s end =%s", start, start + length);
         writefln("src start %s, end=%s", src.start, src.start + 
length);
         uint w = width;
         for (uint y = 0; y < h; y++)
         {
             T* pp1 = this.rowPointer(y);
             T* pp2 = src.rowPointer(y);
//                        still buggy
//                        ubyte* bp1 = pp1;
//                        ubyte* bp2 = pp2;
//                        bp1[0 .. length] = bp2[0 .. length];

             import std.stdio : writeln;

             T[] p1 = this.row(y);
             T[] p2 = src.row(y);

             writefln("this %s == %s??, src: %s", p1.ptr, 
rowPointer(y), p2.ptr);
             writeln(p1.ptr, " p1=", p1[0 .. w]);
             //here pp1 will produce BUG in arch x86_64
             writeln(pp1); //, " ", pp1[0 .. length]);
             //writeln(pp1, " ", pp1[0 .. length]);
             writeln(p2.ptr, " p2=", p2[0 .. w]);
             pp1[0 .. length] = pp2[0 .. length];
             //rowPointer(y)[0 .. length] = src.rowPointer(y)[0 .. 
length];
             writeln(p1.ptr, " p1=", p1[0 .. w]);
         }
     }

     void clear(T value)
     {
         buffer[] = value;
     }
}

alias Buffer!ubyte RenderingBuffer;

unittest
{
     RenderingBuffer buffer = new RenderingBuffer;
     ubyte[] array = new ubyte[32];
     array[] = 8;
     buffer.attach(array, 8, 4, -8);

     import std.stdio : writeln;

     writeln(array);
     buffer.clear(3);
     writeln(array);

     ubyte[] a2 = new ubyte[16];
     a2[] = 4;
     buffer.copyFrom(a2);
     writeln(array);

     RenderingBuffer b2 = new RenderingBuffer;
     ubyte[] array2 = array.dup;
     foreach (int i, ref ubyte b; array2)
         b = cast(ubyte) i;

     writeln(array2);
     b2.attach(array2, 8, 4, 8);

     buffer.copyFrom(b2);
     writeln(array);
}
`

BUG point:
  pp1[0 .. length] = pp2[0 .. length];

//or this origin line
rowPointer(y)[0 .. length] = src.rowPointer(y)[0 .. length];

//even later lines
bp1[0 .. length] = bp2[0 .. length];

Cheers
Lyra


More information about the dmd-internals mailing list