hxcpp
hxcpp copied to clipboard
NativeArray.address, constRaw and empty Bytes being internally changed
Consider this snippet (Haxe 4.1.3 and 4.1.4):
class T {
public static function main() {
var a = haxe.io.Bytes.ofString("");
var b = haxe.io.Bytes.ofString("");
trace( 'Lengths: ${a.length} VS ${b.length}' ); // Lengths 0 VS 0
trace( a.compare(b) ); // 0: identical
// now after this single line
var foo = cpp.NativeArray.address(a.getData(), 0).constRaw;
trace( 'Lengths: ${a.length} VS ${b.length}' ); // Lengths 0 VS 0
trace( a.compare(b) ); // 1: different
}
}
I'm not sure if the above is the correct way to get a constRaw
, if not please tell me.
But I think above behavior can create issues.
It seems to happen because the a
variable when inspected with a debugger, internally gets through those 2 states:
- length=0, mAlloc=0, mBase=0x00
- length=1, mAlloc=56, mBase=0x7ffff024a262
Even though on the surface, the Bytes
object still gives a.length == 0
.
Here what I think happens from tracking this with gdb:
At one point, it gets into (hxcpp/4,1,15/include/cpp/Pointer.h):
inline static AutoCast arrayElem(::Array<T> array, int inIndex) { return AutoCast(&array[inIndex]); }
which eventually calls (in hxcpp/4,1,15/include/Array.h):
inline ELEM_ &Item(int inIndex)
{
if (inIndex>=(int)length) EnsureSize(inIndex+1);
else if (inIndex<0) { return * hx::NewNull<ELEM_>(); }
return * (ELEM_ *)(mBase + inIndex*sizeof(ELEM_));
}
And the EnsureSize()
methods IIUC sets a length
of 1, and
allocates 64-8 = 56 bytes.
Seems it is enforcing a minimal size of 1 for a certain reason, and then memory alignment rules gives this 56 bytes value and the memcmp() used by Bytes.compare() on cpp target then compares a buffer of 0 vs a buffer of 56 bytes, returning 1 (or -1) instead of 0.
From a purely pragmatic point of view, I need a const unsigned char*
, passed from a Bytes that should be allowed to have 0 elements.
I will wait for some feedback on this, as the internals of hxcpp are a bit difficult for me ;). Edit: maybe we can just use the following simple fix?