-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multibyte access to (array i8)
#395
Comments
I've been ruminating on this in the background and I've started to think that we should consider a post-MVP feature that allows regular load/store instructions (of which we now have several dozen) to apply to either on-heap GC arrays or vice versa: to allow slices of linear memory to be viewable through (i.e. aliased by) GC arrays. We have bits available in the |
Another post-MVP feature I would be interested in is to be able to access JavaScript typed arrays (or ArrayBuffer objects) directly from WebAssembly. (Sure, one can access the linear memory as an ArrayBuffer, but it is not as convenient as first-class garbage collected objects.) I was concerned that this would involve adding a lot of new instructions. But using regular load/store instructions could be a solution. |
Oh I like this! A couple thoughts:
|
We have a similar use case in dart2wasm. Dart standard library has a few typed array types like Currently for Multi-byte reads and writes to (Sharing GC references with linear memory application is also possible, but the language-level types for these references need to be more restrictive compared to a type representing a linear memory address, which can just be a Currently the best we can do for the common case of using a list directly (not via a view) while implementing the Dart typed data API (e.g. with the ability to get byte buffer of a list and use it as storage for another list with different element type, maybe with an offset into the buffer) is we implement multiple class _I32ByteBuffer implements ByteBuffer {
final WasmIntArray<WasmI32> _data; // array i32
...
}
class _F64ByteBuffer implements ByteBuffer {
final WasmFloatArray<WasmF64> _data; // array f64
...
} We need one such class for: A However (1) there will be a lot of code (2) |
Just to mention it: an alternative that we have thrown around in the past was to have a form of reinterpret cast on (transparent) array types, such that array(i8) can be viewed as array(f64) etc. That may be useful for other purposes. But it might add some extra complexity around unaligned array sizes. |
Would multi-byte read and write instructions for |
I think we want to avoid exposing the byte order of array elements and struct fields, so I'd be fine restricting the scope of this feature to Another possibility that I've ruminated on is to allow "pinning" all or part of an |
We have a similar use case in CheerpJ (JVM running in the browser): C++ JNI code that access Java byte arrays expects to be able to do arbitrarily sized load and stores on them. Currently we compile Java bytecode to JavaScript, but we would like to eventually target WasmGC. This issue and the inability to expose GC arrays as JS typed arrays (or being able to pass them directly to Web APIs) are the main roadblocks. |
Another use case where this would be very helpful: When compiling to WasmGC instead of JavaScript one may uses WasmGC arrays instead of JS typed data - as WasmGC arrays are faster to allocate & operate on inside wasm code. Though in some occasions one has to pass data across the boundary to JavaScript. => Right now there's no efficient way to |
Use case: Your language allows users to define new packed struct types at runtime. Your language toolchain targets wasm/gc. You use an
(array i8)
to represent the backing store for those packed structs.Problem: For multi-byte loads you have to emit multiple
array.get_s
orarray.get_u
calls and then combine the bytes appropriately. This is inefficient, which is enough of a motivation to add multibyte accessors. There should be something to load and store u16 and i16 from arbitrary offsets in an (array i8), as well as i32, i64, f32, f64, and i128.However I just realized another motivation for multibyte accessors: byte-by-byte access is potentially incorrect in the presence of threads and mutation. Unlike naturally-aligned access to memory in the MVP, access to
(array i8)
contents with MVP GC ops will tear. Not sure what to do about that: whether to specify that naturally aligned multibyte access does not tear (perhaps with an exception for i128), or whether to ensure atomic access only via specific atomic operations. In any case there is some design work to do here.The text was updated successfully, but these errors were encountered: