#[wasm_bindgen]
pub fn dot(input: Vec, mul: f32) -> Vec{
let mut output: Vec = vec![];
for item in input {
output.push(item * mul);
}
output
}
将rust编写的函数导出为wasm, wasm-bindgen工具自动生成类似的胶水函数
/**
* @param {Float32Array} input
* @param {number} mul
* @returns {Float32Array}
*/
export function dot(input, mul) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passArrayF32ToWasm0(input, wasm.__wbindgen_malloc);
const len0 = WASM_VECTOR_LEN;
wasm.dot(retptr, ptr0, len0, mul);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
var v2 = getArrayF32FromWasm0(r0, r1).slice();
wasm.__wbindgen_free(r0, r1 * 4);
return v2;
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
}
}
其中处理函数输入输出使用类似的代码片段
function passArrayF32ToWasm0(arg, malloc) {
const ptr = malloc(arg.length * 4, 4) >>> 0;
getFloat32Memory0().set(arg, ptr / 4);
WASM_VECTOR_LEN = arg.length;
return ptr;
}
以类似的方法在js中调用dot函数
let input = new Float32Array(10000)
.fill(1);
console.log(input.length);
let output = dot(input, 2);
console.log(output.length);
期望输出为input.length == output.length
实际上输出为input.length == 10000 output.length == 2232
且返回数据是错误的计算结果, 经过测试输入数组长度最高为8177 约等于 64 * 128,超过这个长度,输出的数据就是错误的
在`passArrayF32ToWasm0`函数中也存在错误
let cachedFloat32Memory0 = null;
function getFloat32Memory0() {
if (cachedFloat32Memory0 === null || cachedFloat32Memory0.byteLength === 0) {
cachedFloat32Memory0 = new Float32Array(wasm.memory.buffer);
}
return cachedFloat32Memory0;
}
function passArrayF32ToWasm0(arg, malloc) {
const ptr = malloc(arg.length * 4, 4) >>> 0;
// 在malloc之后,期望 cachedFloat32Memory0.byteLength==0
// 实际上此时的cachedFloat32Memory0.byteLength会保持为一个旧值,但是
// wasm.memory.buffer.byteLength已经grow到了新的值
getFloat32Memory0().set(arg, ptr / 4);
WASM_VECTOR_LEN = arg.length;
return ptr;
}
请问最后解决了吗?
我也遇到类似的问题,使用rust编的wasm。模拟器没问题,ios真机有问题。
memory解析的数据不正确