1

I have defined a tuple struct:

pub struct ChangedCell(pub bool, pub u32, pub u32);

My Assumption

ChangedCell weighs 9 bytes (bool: 1 byte, u32: 4 bytes, u32: 4 bytes)

What I Did

I returned a pointer, length for Vec<ChangedCell> to JavaScript:

const arr = new Uint8Array(memory.buffer, pointer, length * 9);
function getElements(n,arr) {

    const isVal = arr[n * 9 + 0];
    const val1 = arr.slice(n * 9 + 1, n * 9 + 5);
    const val2 = arr.slice(n * 9 + 5, n * 9 + 9);
    return {isVal,val1,val2}
}

Expected behaviour

  • isVal to be valid [byte]
  • val1 to be valid [byte] * 4
  • val2 to be valid [byte] * 4

Question

I am getting Garbage values! How do you read something like this into JavaScript?

  • 4
    To help people answer your question, you should include a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example), not just snippets of the code and state what you expect and what result you currently get, not just "it's not working". – justinas Aug 05 '20 at 12:53

1 Answers1

5

First of all, if you are going to assume a particular layout you should mark your type as repr(C):

#[repr(C)]
pub struct ChangedCell(pub bool, pub u32, pub u32);

It is likely that you get the same layout with our without the repr(C), but you only get a guarantee if you write it explicitly.

Now you are guaranteed a C compatible layout, that (beware of the padding!) in wasm32 will be:

  • bool: at offset 0, 1 byte, 0x00 or 0x01.
  • u32: at offset 4, 4 bytes,
  • u32: at offset 8, 4 bytes,

Total size: 12 bytes. Bytes 1, 2 and 3 are padding and thus unused.

rodrigo
  • 94,151
  • 12
  • 143
  • 190