[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