rustwasm / wasm-bindgen

Facilitating high-level interactions between Wasm modules and JavaScript
https://rustwasm.github.io/docs/wasm-bindgen/
Apache License 2.0
7.64k stars 1.05k forks source link

Vec created from static slice becomes garbage data when passed to javscript #1355

Closed dmbfm closed 5 years ago

dmbfm commented 5 years ago

Summary

Hi,

So, I'm creating a Vec<f32> from a literal/static slice and trying to pass that to webgl's buffer data, pretty much like in the webgl example from the documentation.

I have something like this:

pub struct FloatBuffer {
    buffer: Option<WebGlBuffer>,
    content: Vec<f32>,
}

impl FloatBuffer {
    pub fn new(data: &[f32]) -> FloatBuffer {
        FloatBuffer {
            buffer: None,
            content: Vec::from(data).clone(),
        }

   pub fn init(&mut self, context: &Context) {
        let buffer = context.create_buffer().expect("Error creating buffer.");

        let data_slice = self.content.as_slice();

        let memory_buffer = wasm_bindgen::memory()
            .dyn_into::<WebAssembly::Memory>()
            .unwrap()
            .buffer();

        let vertices_location = data_slice.as_ptr() as u32 / 4;
        let vert_array = js_sys::Float32Array::new(&memory_buffer).subarray(
            vertices_location,
            vertices_location + data_slice.len() as u32,
        );

        context
            .gl()
            .bind_buffer(Context::ARRAY_BUFFER, Some(&buffer));
        context.gl().buffer_data_with_array_buffer_view(
            Context::ARRAY_BUFFER,
            &vert_array,
            Context::STATIC_DRAW,
        );

        self.buffer = Some(buffer);
    }
}

The thing is, If I do something like this:

let mut b = buffer::FloatBuffer::new(&[1.0, 0.0, 0.0]); 
b.init(&context)

I get garbage data on the javascript side. While if I do

let data: [f32; 9] = [1.0,  0.0, 0.0];
let mut b = buffer::FloatBuffer::new(&data);
b.init(&context)

The correct data gets to the javascript call.

This is not much of an issue for me, but I would like to understand why this happens. Is it because of the wasm's linear memory changing during the program's execution?

Thanks!

alexcrichton commented 5 years ago

Thanks for the report, and it definitely looks like something fishy is happening here. Do you have a standalone example which reproduces this that we could poke around with?

dmbfm commented 5 years ago

Hi, thanks for the help, but I think it was just a problem with the javascript-side debugging scheme I was using. It seems it was printing the data after it was no longer valid in rust anyway.

I think we can close this, thanks man!