Carl
Carl

Reputation: 383

Does WASM Bindgen copy &mut [u8] zero times or twice?

From JavaScript, I call this Rust function. Does Bindgen copy the memory twice or zero times?

#[wasm_bindgen]
pub fn mod_u8_slice(input_output: &mut [u8]) {
    input_output.iter_mut().for_each(|x| *x += 1);
}

Upvotes: 0

Views: 129

Answers (1)

kmdreko
kmdreko

Reputation: 59912

The data is copied twice: once in, once out.

// mycrate_bg.wasm.d.ts
export function mod_u8_slice(a: number, b: number, c: number): void;
// mycrate.js
export function mod_u8_slice(input_output) {
    var ptr0 = passArray8ToWasm0(input_output, wasm.__wbindgen_malloc);
    var len0 = WASM_VECTOR_LEN;
    wasm.mod_u8_slice(ptr0, len0, addHeapObject(input_output));
}

The passArray8ToWams0 copies the bytes from input_output into a region of the WASM module's memory. The addHeapObject is just a bit of record-keeping for JavaScript objects.

The generated WASM itself will include a call to __wbindgen_copy_to_typed_array when your Rust function completes. Here is that function added to the WASM imports which copies the data back. The getObject function retrieves the object stored by addHeapObject, which will be input_output:

function __wbg_get_imports() {
    const imports = {};
    imports.wbg = {};
    imports.wbg.__wbindgen_copy_to_typed_array = function(arg0, arg1, arg2) {
        new Uint8Array(getObject(arg2).buffer, getObject(arg2).byteOffset, getObject(arg2).byteLength).set(getArrayU8FromWasm0(arg0, arg1));
    };
    imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
        takeObject(arg0);
    };

    return imports;
}

That is the gist; you can inspect the generated .js and .wasm files yourself for more details.

Upvotes: 2

Related Questions