Skip to content
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

Referencing arrays in JS #804

Closed
CarstenHoyer opened this issue Aug 31, 2019 · 12 comments
Closed

Referencing arrays in JS #804

CarstenHoyer opened this issue Aug 31, 2019 · 12 comments
Labels

Comments

@CarstenHoyer
Copy link

CarstenHoyer commented Aug 31, 2019

I have looked at:
#105
#263
WebAssembly/design#1231

But I cannot make this thing work as I expect it to.

Given the below code, I would expect the console.logs to output [1, 2, 3, 4), [100, 2, 3, 4) then [200, 2, 3, 4). But what I see is [1, 2, 3, 4), [100, 2, 3, 4) then [100, 2, 3, 4). That indicates that my processF32Array is wrong. I tried different ideas, but none of them seems to reflect any changes on the JS side.

I could use a little help.

JS

const module = await loader.instantiateStreaming(fetch("untouched.wasm"), myImports);
const { processF32Array } = module
const myArray = [1,2,3,4];
const myArrayId = module.__retain(module.__allocArray(module.FLOAT32ARRAY_ID, myArray))

const myArrayView = module.__getArrayView(myArrayId);
console.log(myArrayView)

myArrayView[0] = 100;
console.log(myArrayView)

processF32Array(myArrayId);
console.log(myArrayView)

WASM:

export const FLOAT32ARRAY_ID = idof<Float32Array>()

export function processF32Array(ptr: i32): void {
  const val: f32 = 200
  store<f32>((ptr) << 2, val)
}
@MaxGraey
Copy link
Member

Try this one:

export function processF32Array(ptr: i32): void {
  const val: f32 = 200
  store<f32>(ptr + (0 << 2), val)
}

@CarstenHoyer
Copy link
Author

Thanks. Tried it. It stays the same [100, 2, 3, 4].

@CarstenHoyer
Copy link
Author

CarstenHoyer commented Aug 31, 2019

Actually, if i make a slight change, I can see the array values get reset, so that indicates that it is not the same array I am working on in JS/WASM.

JS:

const module = await loader.instantiateStreaming(fetch("untouched.wasm"), myImports);
const { processF32Array } = module
const myArray = [1,2,3,4];
const myArrayId = module.__retain(module.__allocArray(module.FLOAT32ARRAY_ID, myArray))
let myArrayView = module.__getArrayView(myArrayId); // NOT A CONSTANT
console.log(myArrayView)
myArrayView[0] = 100;
console.log(myArrayView)
processF32Array(myArrayId);
myArrayView = module.__getArrayView(myArrayId); // GET THE VIEW AGAIN
console.log(myArrayView)

Logs:
Float32Array(4) [1, 2, 3, 4]
Float32Array(4) [100, 2, 3, 4]
Float32Array(4) [1, 2, 3, 4]

@MaxGraey
Copy link
Member

You should invalidate your myArrayView after processF32Array. It could be done via calling myArrayView = module.__getArrayView(myArrayId) again after processF32Array

@CarstenHoyer
Copy link
Author

Ah, exactly what I just tried above :)

@CarstenHoyer
Copy link
Author

I wonder if this is the part i misunderstood?

WASM

export const FLOAT32ARRAY_ID = idof<Float32Array>()

@CarstenHoyer
Copy link
Author

No that part looks correct.

@CarstenHoyer
Copy link
Author

CarstenHoyer commented Aug 31, 2019

I am not getting any kind of updates. Below I would expect the console.log to be [200]

JS

const myImports = {
      env: {
        abort(_msg, _file, line, column) {
          console.error("abort called at main.ts:" + line + ":" + column);
        },
        memory: new WebAssembly.Memory({ initial: 256 })
      },
      imports: { }
    }

    const module = await loader.instantiateStreaming(fetch("optimized.wasm"), myImports);
    const { processF32Array } = module
    const arr = new Float32Array([1]);
    const id = module.__retain(module.__allocArray(module.FLOAT32ARRAY_ID, arr))
    
    processF32Array(id);
    const arr1 = module.__getArray(id)
    console.log(arr1)

WASM

export function processF32Array(ptr: i32): void {
  const val: f32 = 200
  store<f32>(ptr + (0 << 2), val)
}

SCRIPT

asc assembly/index.ts -b build/optimized.wasm -t build/optimized.wat -d build/optimized.d.ts --use Math=JSMath --runtime full -O3 --importMemory --sourceMap --validate --measure

@CarstenHoyer
Copy link
Author

On the WASM side, it looks like I can do this:

WASM

export function processF32Array(arr: Float32Array): void {
  arr[0] = 200
}

Now to figure out what to do on the JS side.

@MaxGraey
Copy link
Member

Yeah, I forgot, you can't access direct to typed array by pointer, it has backing buffer, so you should use:

export function processF32Array(arr: Float32Array, val: f32): void {
  var index = 0;
  store<f32>(arr.dataStart + (index << alignof<f32>), val);
}

@MaxGraey
Copy link
Member

I guess before doing such low level things better read this part of documentation. Hope this help you

@stale
Copy link

stale bot commented Sep 30, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Sep 30, 2019
@stale stale bot closed this as completed Oct 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants