Assemblyscript: for array loop - RuntimeError: memory access out of bounds

Created on 22 Sep 2019  路  6Comments  路  Source: AssemblyScript/assemblyscript

My index.ts:

export function foo(data: Array<i32>): Array<i32> {
  for (let i = 0; i < 1; i++) {
    data[i];
  }
  return data;
}

compiles fine but throws a runtime error:
RuntimeError: memory access out of bounds

This code works fine:

export function foo(data: Array<i32>): Array<i32> {
  for (let i = 0; i < 1; i++) {
  }
  return data;
}

I'm running it with this javascript code:

let exportedInterface = module.instance.exports;
console.log(exportedInterface.foo([5]));

Obviously this code is doing nothing, I just want to understand how can I access an array cell.

BTW (probably related) the return value is 5 while the expected value is [5]. seems like data is the value of the first cell on the array instead of the array itself.

Any idea on how to pass an array as a parameter?

Thanks.

question stale

Most helpful comment

__allocArray expects the runtime id of the kind of array to allocate, like so:

// wasm
export const Uint8ClampedArray_ID = idof<Uint8ClampedArray>();
// js
var arrPtr = myModule.__retain(myModule.__allocArray(myModule.Uint8ClampedArray_ID, [5]));
...

See also: https://github.com/AssemblyScript/assemblyscript/tree/master/lib/loader

All 6 comments

You can't pass JS array to AS array directly. This WebAssembly limitation. You could use loader

export const ARRAY_I32_ID = idof<Array<i32>>();
export function foo(data: Array<i32>): Array<i32> {
  for (let i = 0; i < 1; i++) {
    data[i];
  }
  return data;
}
const loader = require("assemblyscript/lib/loader");
const myModule = await loader.instantiateStreaming(fetch("optimized.wasm"));
var arrPtr = myModule.__retain(myModule.__allocArray(myModule.ARRAY_I32_ID, [5]));
var resPtr = myModule.foo(arrPtr);
var result = myModule.__getArray(resPtr);
console.log(result);
myModule.__release(arrPtr);

@MaxGraey your code doesn't run well:

if ((id >>>= 0) >= count) throw Error("invalid id: " + id);

while id = [5].

I've tried this:

var arrPtr = myModule.__retain(myModule.__allocArray([5, 4, 6, 3]));

but this one is throwing here:

if (!(info & (ARRAYBUFFERVIEW | ARRAY))) throw Error("not an array: " + id + " @ " + info);

Error: not an array: 5,4,6,3 @ 16

My realworld usage will be Uint8ClampedArray from ctx.getImageData().data, will it work?
Do you have any example with images and pixels manipulations or something like that?

Thank you!

__allocArray expects the runtime id of the kind of array to allocate, like so:

// wasm
export const Uint8ClampedArray_ID = idof<Uint8ClampedArray>();
// js
var arrPtr = myModule.__retain(myModule.__allocArray(myModule.Uint8ClampedArray_ID, [5]));
...

See also: https://github.com/AssemblyScript/assemblyscript/tree/master/lib/loader

yes. First argument should be id.

Can you maybe share a link to an example with transferring a param and getting the answer back. The loader documentation assumes I already know a great deal about assemblyscript.

I've tried to find reference to the type WasmImports on this repository but turns out it's not an existing interface but it just stands for any?

I couldn't find an example that uses the loader on this repository examples folder.

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

emil14 picture emil14  路  3Comments

kungfooman picture kungfooman  路  5Comments

lastmjs picture lastmjs  路  4Comments

MaxGraey picture MaxGraey  路  3Comments

dcodeIO picture dcodeIO  路  4Comments