网站首页 > 博客文章 正文
大家好,很高兴又见面了,我是"高级前端?进阶?",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!
今天给大家带来的主题是 wasmati,即支持使用 JavaScript 编写底层 WebAssembly 的公开库。在年初,我也确实使用 WebAssembly 将客户端应用成功移植到了 Web,这也是为什么我一直对 WebAssembly 充满好奇的原因。我甚至在头条上开了一个合集《WebAssembly 前沿技术》来专门探讨 WebAssembly ,并将持续关注 WebAssembly 的最新动态。
下面是已发布部分文章传送门(更多文章可以阅读我的头条专题):
- 《 2023 年让 WebAssembly 大火的 10+应用!》
- 《 万字长文!2023 年 WebAssembly 各个运行时性能对比!》
- 《 让 JavaScript 在 WebAssembly 上加速运行!》
- 《全网最火的5+优秀 WebAssembly 运行时!》
- 《 在线表格再添一员猛将excelize,支持 wasm! 》
正如大家所看到的,当我们还在迟疑是否要在日常开发中引入 WebAssembly 的时候,很多优秀的应用、工具已经开始吃 WebAssembly 的红利了,而且取得了不错的成就,这可能也是为什么各个浏览器厂商、开发者如此热衷 WebAssembly 的原因吧。
话不多说,直接进入正题!
1.什么是 wasmati
wasmati 用于从 JavaScript 编写底层 WebAssembly。本质上,wasmati 是一个用于在指令级别编写 Wasm 的 TypeScript 库,因此 API 看起来与 Webassembly 文本格式 WAT (Webassembly text format) 完全一样。
使用 wasmati 有以下几点需要重点声明:
- 借助于 wasmati 工具开发者可以创建底层、手动优化的 Wasm 库
- 借助 wasmati 开发者可以 JS 原生方式在应用程序中加入一些 Wasm 来加速关键代码
- 如果想从高级语言(如 Rust 或 C)编译 Wasm 模块,那么 wasmati 并不适合
要使用 wasmati 也非常简单,只需要通过 npm 安装相应的包后直接调用即可:
import { i64, func, local } from "wasmati";
const myMultiply = func({ in: [i64, i64], out: [i64] }, ([x, y]) => {
local.get(x); // put input x on the stack
local.get(y); // put input y on the stack
i64.mul(); // pop the two last values from the stack, multiply them, put the result on the stack
});
作为参考,下面是一个等效的 WAT 代码片段:
(func $myMultiply (param $x i64) (param $y i64) (result i64)
(local.get $x)
(local.get $y)
i64.mul
)
2.wasmati 已支持的特性
- 适用于所有现代浏览器、node 和 deno
- 与 WebAssembly 对等,API 直接对应 Wasm 操作码,如 i32.add 等。支持最新 WebAssembly 规范(2.0)的所有操作码和语言功能。
- 可读性强,使用 wasmati 具有更好的 DX
const myFunction = func({ in: [i32, i32], out: [i32] }, ([x, y]) => {
local.get(x);
local.get(y);
i32.add();
i32.const(2);
i32.shl();
call(otherFunction);
});
可选语法糖以减少样板程序集,如 local.get 和 i32.const:
const myFunction = func({ in: [i32, i32], out: [i32] }, ([x, y]) => {
i32.add(x, y); // local.get(x), local.get(y) are filled in
i32.shl($, 2); // $ is the top of the stack; i32.const(2) is filled in
call(otherFunction);
});
// or also
const myFunction = func({ in: [i32, i32], out: [i32] }, ([x, y]) => {
let z = i32.add(x, y);
call(otherFunction, [i32.shl(z, 2)]);
});
- 类型安全:比如局部变量是有类型的,指令知道输入类型:
const myFunction = func(
{ in: [i32, i32], locals: [i64], out: [i32] },
([x, y], [u]) => {
i32.add(x, u); // type error: Type '"i64"' is not assignable to type '"i32"'.
}
);
- 很棒的调试 DX:堆栈跟踪指向代码中调用无效操作码的确切行:
Error: i32.add: Expected i32 on the stack, got i64.
...
at file:///home/gregor/code/wasmati/examples/example.ts:16:9
- 易于构建模块:只需声明 exports,dependencies 和 imports 将自动收集。模块中没有任何导出或启动函数不需要的东西。
let mem = memory({ min: 10 });
let module = Module({ exports: { myFunction, mem } });
let instance = await module.instantiate();
- 出色的类型推断:比如导出的函数类型是从 func 定义中推断出来的:
instance.exports.myFunction;
// ^ (arg_0: number, arg_1: number) => number
- 原子导入声明:导入被声明为类型及其 JS 值。抽象出与“导入声明”分开的全局“导入对象”
const consoleLog = importFunc({ in: [i32], out: [] }, (x) =>
console.log("logging from wasm:", x)
);
const myFunction = func({ in: [i32, i32], out: [i32] }, ([x, y]) => {
call(consoleLog, [x]);
i32.add(x, y);
});
具有出色的可组合性和 IO:模块/函数/等的内部表示是一个可读的 JSON 对象;接近规范的类型布局(但在必要时提高可读性或 JS 人体工程学);使用 module.toBytes()、Module.fromBytes(bytes) 与 Wasm 字节码相互转换。
3.wasmati 目前暂未实现的功能
- Wasmati build: 用于添加一个可选的构建步骤,它将一个导出模块的文件作为输入,并将其编译为一个在运行时不依赖于 wasmati 的文件。 本质上是将 Wasm 字节码硬编码为 base64 字符串,像原始文件一样正确导入实例化的所有依赖项(import),实例化模块(top-level await)并导出模块的导出。
// example.ts
let module = Module({ exports: { myFunction, mem } });
export { module as default };
// example.ts
let module = Module({ exports: { myFunction, mem } });
export { module as default };
- 实验性 Wasm 操作码: wasmati 希望支持尚未符合规范的最近标准化或正在进行的功能提案(如本提案)中的操作码。 最终目标是在至少一个 JS 引擎中实施后立即支持提案。
- 自定义模块部分:wasmati 希望支持创建和解析“自定义部分”,例如:名称等
- 反编译器::wasmati 获取任何 Wasm 文件并从中创建 wasmati TS 代码用于修改、调试等
- source maps:这样开发者就可以在 Wasm 抛出错误时查看 JS 代码
- 可选的 JS 解释器,可以获取 DSL 代码并在 JS 中执行
- 可以启用更灵活的调试:检查堆栈、全局/局部范围等
本文总结
本文主要和大家介绍 wasmati,即支持使用 JavaScript 编写底层 WebAssembly 的工具。相信通过本文的阅读,大家对 wasmati 会有一个初步的了解。
因为篇幅有限,关于 wasmati 的更多用法和特性文章并没有过多展开,如果有兴趣,可以在我的主页继续阅读,同时文末的参考资料提供了大量优秀文档以供学习。最后,欢迎大家点赞、评论、转发、收藏,您的支持是我不断创作的动力。
参考资料
https://github.com/zksecurity/wasmati
https://www.zksecurity.xyz/blog/posts/wasmati/
封面图地址:https://malloc.fi/typescript-bridge-javascript-webassembly
猜你喜欢
- 2024-10-17 「B/S端开发」DevExtreme初级入门教程 - 支持TypeScript
- 2024-10-17 如何在 TypeScript 中使用装饰器(typescriptreact)
- 2024-10-17 何时使用 TypeScript:常见场景的详细介绍
- 2024-10-17 15. TypeScript编程实践(入门篇):正则表达式
- 2024-10-17 Vue3.x + TypeScript 的在线演示文稿(幻灯片)应用
- 2024-10-17 如何在 TypeScript 中创建自定义类型
- 2024-10-17 第一个 TypeScript 程序(typescript then)
- 2024-10-17 TypeScript 实践(typescript总结)
- 2024-10-17 「译」TypeScript终极指南一:安装与配置
- 2024-10-17 让人眼前一亮的 10 大 TypeScript 项目
你 发表评论:
欢迎- 367℃用AI Agent治理微服务的复杂性问题|QCon
- 360℃手把手教程「JavaWeb」优雅的SpringMvc+Mybatis整合之路
- 358℃初次使用IntelliJ IDEA新建Maven项目
- 351℃Maven技术方案最全手册(mavena)
- 348℃安利Touch Bar 专属应用,让闲置的Touch Bar活跃起来!
- 346℃InfoQ 2024 年趋势报告:架构篇(infoq+2024+年趋势报告:架构篇分析)
- 345℃IntelliJ IDEA 2018版本和2022版本创建 Maven 项目对比
- 342℃从头搭建 IntelliJ IDEA 环境(intellij idea建包)
- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)