- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有一段非常简单的 Typescript 代码来解析特定的数据格式,输入是一个 UInt8Array。我已经尽可能地优化了它,但我认为这个相当简单的解析器应该能够比我让它作为 JS 运行得更快。我想尝试使用 AssemblyScript 在 Web 程序集中编写它,以确保我不会遇到 Javascript 引擎的任何怪癖。
我现在明白了,我不能只将 TypedArray 传递给 Wasm 并让它自动工作。据我所知,我可以传递一个指向数组的指针,并且应该能够直接从 Wasm 访问它而无需复制数组。但我无法让它与 AssemblyScript 一起工作。
以下是一个最小示例,展示了我如何无法将 ArrayBuffer 传递给 Wasm。
设置 Wasm 导出的代码主要来自自动生成的样板文件:
const fs = require("fs");
const compiled = new WebAssembly.Module(
fs.readFileSync(__dirname + "/build/optimized.wasm")
);
const imports = {
env: {
abort(msgPtr, filePtr, line, column) {
throw new Error(`index.ts: abort at [${line}:${column}]`);
}
}
};
Object.defineProperty(module, "exports", {
get: () => new WebAssembly.Instance(compiled, imports).exports
});
下面的代码调用了WASM,index.js是上面的胶水代码。
const m = require("./index.js");
const data = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
const result = m.parse(data.buffer);
编译成 WASM 的 AssemblyScript 如下:
import "allocator/arena";
export function parse(offset: usize): number {
return load<u8>(offset);
}
当我执行该代码时,出现“RuntimeError:内存访问越界”。
主要问题是我从 Wasm 返回的错误根本无法帮助我自己解决这个问题。我显然错过了这在幕后如何实际运作的一些主要方面。
我实际上如何使用 AssemblyScript 将 TypedArray 或 ArrayBuffer 从 JS 传递到 Wasm?
最佳答案
在 AssemblyScript 中,有多种方法可以从内存中读取数据。获取此数据的最快捷方式是在模块的函数导入中使用链接函数来返回指向数据本身的指针。
let myData = new Float64Array(100); // have some data in AssemblyScript
// We should specify the location of our linked function
@external("env", "sendFloat64Array")
declare function sendFloat64Array(pointer: usize, length: i32): void;
/**
* The underlying array buffer has a special property called `data` which
* points to the start of the memory.
*/
sendFloat64Data(myData.buffer.data, myData.length);
然后在 JavaScript 中,我们可以在链接函数中使用 Float64Array
构造函数直接返回值。
/**
* This is the fastest way to receive the data. Add a linked function like this.
*/
imports.env.sendFloat64Array = function sendFloat64Array(pointer, length) {
var data = new Float64Array(wasmmodule.memory.buffer, pointer, length);
};
但是,有一种更清晰的方法来获取数据,它涉及从 AssemblyScript 返回一个引用,然后使用 AssemblyScript 加载器。
let myData = new Float64Array(100); // have some data in AssemblyScript
export function getData(): Float64Array {
return myData;
}
然后在JavaScript中,我们可以使用AssemblyScript提供的ASUtil加载器。
import { instantiateStreaming } from "assemblyscript/lib/loader";
let wasm: ASUtil = await instantiateStreaming(fetch("myAssemblyScriptModule.wasm"), imports);
let dataReference: number = wasm.getData();
let data: Float64Array = wasm.getArray(Float64Array, dataReference);
出于代码清晰的原因,我强烈建议使用第二个示例,除非性能绝对至关重要。
祝您的 AssemblyScript 项目好运!
关于javascript - 如何将 ArrayBuffer 从 JS 传递到 AssemblyScript/Wasm?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54738197/
我想要一个ArrayBuffer的二维数组 像这样: var myRowOfStrings = new ArrayBuffer[String] val myArrayOfRows = new Arra
假设我有一个 ArrayBuffer,它是一个 mp4 文件。我想创建一个新的 ArrayBuffer,其中包含一些额外的字节用作 header 信息,然后将 mp4 缓冲区存储在新的 的其余部分Ar
我正在尝试使用 .slice() 从 ArrayBuffer 创建 Blob,因为我需要复制 ArrayBuffer > 因为我知道它将来会被我无法控制/想要更改的代码更改(其 byteLength
我创建了一个用于下载pdf的应用程序。 pdf 基于 html 表格。该应用程序在所有浏览器中都工作正常,但是当我在 IE9 中运行时,我收到函数错误:“ArrayBuffer”未定义 Referen
我目前正在为 WebAuthN 编写概念验证 Web 应用程序(FIDO U2F, FIDO2) 整合。 返回字段cred.rawId的数据类型为ArrayBuffer。在 Chromes 的开发者控
这个问题过去已经得到了答案,但我肯定地说它仍然没有得到答案。 一般来说,几乎都有关于 ArrayBuffers 的文档,更不用说特定应用程序了。我已经研究了好几天了,没有结果。 本质上,我需要尝试将从
我有一个 ArrayBuffer,它是通过使用 Frida 读取内存返回的。我正在将 ArrayBuffer 转换为字符串,然后使用 TextDecoder 和 TextEncoder 转换回 Arr
我的目标是将 TIFF 图像加载到 HTML Canvas 上。前端接收 TIFF 图像的 ArrayBuffer,我能够利用 UTIF 解码 ArrayBuffer 并将其呈现在 HTML Canv
当我从 angular 6 项目上传图像时,我正在尝试按照教程将图像转换为 Base64。当我按下提交按钮时,我可以获得作为值的输出:“base64 代码”,而且我还可以通过使用“将你的 Base64
我正在尝试从 Arweave 中获取加密的原始缓冲区数据 (AES-256) ,传递给解密函数并使用它来显示图像。我正在尝试在前端(在我的 React 应用程序中)获取和解密 ArrayBuffer。
是否有任何特殊的案例类来表示空 ArrayBuffer可用于类似于 Nil 的模式匹配对于列表? 还有为什么这有效: scala> collection.mutable.ArrayBuffer.emp
Scala 在过滤不可变序列方面非常优雅: var l = List(1,2,3,4,5,6) l = l.filter(_%2==1) 但是我如何使用像 ArrayBuffer 这样的可变集合来做到
我有这个功能: def getTime() : ArrayBuffer[Timestamp] = { val offset = Timestamp.valueOf("2015-01-01 00
我有一个 Javascript ArrayBuffer,我想将其转换为十六进制字符串。 有人知道我可以调用的函数或已经存在的预先编写的函数吗? 我只能找到数组缓冲区到字符串函数,但我想要数组缓冲区的十
我正在尝试使用 FileReader API 将本地文件读入 ArrayBuffer,如下所示 let reader = new FileReader(); reader.onload = funct
假设我创建了初始大小等于 10 的 ArrayBuffer val buf = new ArrayBuffer[Int](10) 如果我确实调用了方法 buf.size - 缓冲区的大小是否等于 0?
我正在尝试使用 AES-CTR 算法在浏览器上解密数据。 WebCrypto API需要将计数器作为 BufferSource 传递.如何将计数器(数字)转换为预期的输入(字节数组)? 我使用的是全零
我有通过 TCP 连接 (WebSocket) 发送的二进制信息。这以编码格式跟踪到控制台,如下所示: 53 54 41 52 54 45 44 3a 31 34 32 38 36 30 32 30
因此,我有一个 ArrayBuffer[Signal],其中每个 Signal 都有一个时间戳(数组按此时间戳排序)。我想进行二进制搜索并返回某个范围内的信号的 Seq[Signal]。现在是用线性搜
我想在我的程序中使用 ArrayBuffer 来保存数字列表。我想将它用作队列。每次删除列表中的第一项并使用它。然后我想知道每次我删除第一个项目时队列中的所有其他数字都会移动一个位置。我的意思是下次我
我是一名优秀的程序员,十分优秀!