WebAssembly.ReflectConstruct and Uint8Array

Elements 11.0.0.2657

Hi,

I need to create an ArrayBufferView (exactly Uint8Array) on an existing ArrayBuffer. I couldn’t find the type in RemObjects.Elements.WebAssembly.DOM (there is ArrayBufferView but it’s just an empty interface) so I attempted to create it “manually” using RemObjects.Elements.System.WebAssembly.ReflectConstruct. I pass ‘Uint8Array’ string and an array with the ArrayBuffer object as the constructor arguments. The object is created but the length is different from ArrayBuffer.byteLength (it’s just a big number e.g. 5604996) and all the elements are zeros.

namespace TestModule;

type
  
  [Export]
  Program = public class
  public
    method Main;
    begin

      var len := 32;

      var buf := WebAssembly.ReflectConstruct('ArrayBuffer', [len]);
      assert(buf.byteLength = len); // OK

      var arr := WebAssembly.ReflectConstruct('Uint8Array', [buf]);
      assert(arr.length = len); // WRONG

    end;
  end;
end.

So the question is - how to “manually” create an object that takes another object as an argument in the constructor?

What am I missing? Or is there another approach that I failed to discover?

The ArrayBufferView is an abstract type - that is why there are no elements on it.

But I think your code should just be:

  var arr := WebAssembly.ReflectConstruct('Uint8Array', [len]);
  assert(arr.length = len);

But as this is WASM, why don’t you just use a native Oxygene array?

1 Like

As I’ve mentioned before I don’t need to simply create a Uint8Array of a given size (your code), I need to create a view on an existing ArrayBuffer to read its contents. There’s no way to directly read an ArrayBuffer, you need an ArrayBufferView one of which is Uint8Array (if you need to deal with individual bytes).

Why do I need this? To read a local file. I have an <input type="file"> in my document which provides a FileList which provides a File which provides an ArrayBuffer.

From Uint8Array - JavaScript | MDN

So your code looks valid.

To test, I checked the following:

  var arr1 := WebAssembly.eval('new Uint8Array(new ArrayBuffer(32))');
  var x := arr1.length;

And then, x is indeed 32.

Then I tested (should be exactly the same as the code above):

  var arr1 := WebAssembly.ReflectConstruct('Uint8Array', [WebAssembly.ReflectConstruct('ArrayBuffer', [32])]);
  var x := arr1.length;

And then x = 854500 instead of 32

@ck / @mh
It looks like something goes wrong in the ReflectConstruct with an object as parameter.

Yes, this is exactly my point from the original post. I wasn’t sure if I was doing something wrong or if there is a general problem when you’re trying to call a constructor with an object as an argument. It seems to me that our tests are equivalent so it confirms the latter.

Logged as bugs://E25315.

bugs://E25315 was closed as fixed.