【问题标题】:How do I access data within linear memory [duplicate]如何访问线性内存中的数据[重复]
【发布时间】:2018-06-20 07:20:26
【问题描述】:

我的.wat 文件有以下两行代码。

(memory $buf 1)
(data (i32.const 0) "hello")

我想将 $buf 作为参数传递给导入的 Javascript 函数。 Javascript 端的代码如下所示:

 function consoleLogString(memory, offset,length){
        var bytes = new Uint8Array(memory.buffer, 0, 5);
        var string = new TextDecoder('utf8').decode(bytes);
        console.log(string);
    }
    var importObj = {console : {log: consoleLogString}};
    fetchAndInstantiate('stringLogger2.wasm',importObj).then(function(instance) {
        instance.exports.writeHi();
    });
}

在 wasm 方面,我希望能够做类似的事情

(import "console" "log" (func $log (param i32 i32 i32)))
(export "writeHi" (func $writeHi))
(memory $buf 1)
(data (i32.const 0) "hello")
(func $writeHi
      ;; how do I push my buffer onto the stack so it can be passed to the function?
      i32.const 0
      i32.const 5
      call $log
)

【问题讨论】:

    标签: javascript webassembly


    【解决方案1】:

    据我所知,WebAssembly 只支持 i32 / i64 / f32 / f64,所以这意味着你不能传入指针。

    Pass a JavaScript array as argument to a WebAssembly function

    但是您可以将 memory 导入到 wasm 实例,并且可以将日志功能与导入的 memory 链接>

    function consoleLogString(memory, offset, length) {
        var bytes = new Uint8Array(memory.buffer, offset, length);
        var string = new TextDecoder('utf8').decode(bytes);
        console.log(string);
    }
    const memory = new WebAssembly.Memory({ initial: 2 });
    const consoleLogStringWrapper = memory => (offset, length) => consoleLogString(memory, offset, length);
    var importObj = {
        imp : {
            mem: memory,
            log: consoleLogStringWrapper(memory)
        }
    };
    fetchAndInstantiate('stringLogger2.wasm', importObj).then(function(instance) {
        instance.exports.writeHi();
    });
    

    您的 wat 将与此类似:

        (module
            (import "imp" "log" (func $log (param i32 i32)))
            (memory (import "imp" "mem") 1)
            (func $writeHi
                 i32.const 0
                 i32.const 5
                 call $log
            )
            (data (i32.const 0) "hello")
            (export "writeHi" (func $writeHi))
        )
    

    使用以下js在wat2wasm上测试:

    function consoleLogString(memory, offset, length) {
        var bytes = new Uint8Array(memory.buffer, offset, length);
        var string = new TextDecoder('utf8').decode(bytes);
        console.log(string);
    }
    const memory = new WebAssembly.Memory({ initial: 2 });
    const consoleLogStringWrapper = memory => (offset, length) => consoleLogString(memory, offset, length);
    var importObj = {
        imp : {
            mem: memory,
            log: consoleLogStringWrapper(memory)
        }
    };
    
    const wasmInstance = new WebAssembly.Instance(wasmModule, importObj);
    const { writeHi } = wasmInstance.exports;
    writeHi();
    

    【讨论】:

    • 好的,所以我不能返回指针。这就说得通了。但是,如果您不介意再澄清一件事,那就太棒了。在您的示例中,您正在用 javascript 创建内存,用 wasm 填充它,然后用 javascript 访问它(记录它)。我想知道如何从 Web 程序集中访问内存。那么在我做了(data (i32.const 0) "hello")之后,如何访问数据段的各种偏移量。
    • @kablaa 要访问 WebAssembly 中的内存,您可以使用加载/存储运算符 github.com/WebAssembly/design/blob/master/…data 添加的值将存储在 (data (i32.const 0) "hello") 中设置的偏移量 0
    • 当我尝试执行 i32.load 时,它正在等待一条指令,但我似乎无法弄清楚是否有一个通过它。所以就像如果我想在我的函数中将 'hello' 中的 'h' 更改为 'H',我该怎么做?
    • 嗯,我不知道你为什么需要 i32.load。要更改内存中的值,您需要使用 i32.store。请参阅更改第一个字母 h -> H(72) 的简单示例。 (i32.store8 (i32.const 0) (i32.const 72) )gist.github.com/gskachkov/6ef172698137ab378231ece6b09e0a9b
    猜你喜欢
    • 2018-03-26
    • 2013-11-15
    • 2019-05-24
    • 1970-01-01
    • 2018-09-16
    • 2012-08-03
    • 1970-01-01
    • 1970-01-01
    • 2020-07-12
    相关资源
    最近更新 更多