收藏
回答

iOS wasm 内存分配问题

框架类型 问题类型 API/组件名称 终端类型 微信版本 基础库版本
小程序 Bug WXWebAssembly 微信iOS客户端 8.0.39 2.32.3
#[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;
}



最后一次编辑于  2023-07-12
回答关注问题邀请回答
收藏

1 个回答

  • 哈特斯星
    哈特斯星
    03-14

    请问最后解决了吗?

    我也遇到类似的问题,使用rust编的wasm。模拟器没问题,ios真机有问题。

    memory解析的数据不正确

    03-14
    有用
    回复 1
    • LYD
      LYD
      03-18
      安卓是不是没问题?我是创建太rust中的对象后ios调用都会报错
      03-18
      回复
登录 后发表内容