为 WebAssembly 构建
我目前正在为 Memphis(我的 Rust 中的 Python 解释器)探索两个有趣的主题:构建 WebAssembly 和嵌入 CPython。由于本周没有重大里程碑要报告,我想分享一些正在进行的想法。对我来说,孟菲斯是一个通过实际实验扩展我的概念理解的项目 - 希望这篇文章可以为您做同样的事情,因为我们正在探索我正在探索的一些设计决策。
浏览器中的 Python
将 Memphis 编译为 WebAssembly 目标已经在我脑海中浮现了一段时间,两个星期六前,我终于尝试了一下。在杯垫上放了一杯温热的滴滤咖啡,我掰响指关节开始了。
WebAssembly 是现代 Web 浏览器内的沙盒执行环境,它补充了传统的 JavaScript 环境。 Wasm 环境更接近本机代码,可用于受益于更高性能的 CPU 上下文的任务;想想数字运算或愚蠢的繁忙循环。我对它的兴趣不是从性能的角度来看,而是因为它完全是可能的。 Rust 的卖点之一(实际上有无数卖点)是它可以针对 Wasm。有人可能会问,怎么办?这是可能的,因为 Rust 使用 LLVM 作为其编译器后端。 Rust 编译器前端生成 LLVM 中间表示 (IR) 代码,LLVM 可以将其编译为数十个目标的本机代码。
这是一个相当巨大的好处,我很好奇它是否只适用于孟菲斯。我之前对在浏览器中运行 Python 的想法几乎为零,所以这似乎是测试 Wasm 学习曲线的绝佳机会。
设置 wasm-pack 并构建 WebAssembly
我启动了人工智能助手并询问启动顺序。发出嘟嘟嘟嘟嘟的声音。以下是我一路上学到的注释的步骤。
# wasm-pack helps compile our Rust code to WebAssembly and bundle it # with JavaScript bindings we can call from our HTML/JavaScript page. cargo install wasm-pack # wasm-pack also downloads the wasm32-unknown-unknown target via # rustup for us. If for whatever reason it does not, you can use this: # rustup target add wasm32-unknown-unknown # We must specify a feature flag because our wasm_bindgen interface is # behind the wasm feature flag. wasm-pack build --target web --out-dir wasm_ui/pkg -- --features wasm
我第一次尝试就构建成功了!然而,因为我们没有将 Rust 二进制文件中的任何函数标记为可从 WebAssembly 调用,所以它没有做太多事情。
我们可以安装 wasm-bindgen 箱来执行此操作,我将其放在功能标志后面。我将其添加到我的 Cargo.toml 中。
[dependencies] wasm-bindgen = { version = "0.2", optional = true } [features] wasm = ["wasm-bindgen"]
这是我添加到 src/lib.rs 文件中的一小段代码,位于 wasm 功能标志后面。 greet 函数用 #[wasm_bindgen] 修饰,使该符号在 JavaScript 中可用。
# wasm-pack helps compile our Rust code to WebAssembly and bundle it # with JavaScript bindings we can call from our HTML/JavaScript page. cargo install wasm-pack # wasm-pack also downloads the wasm32-unknown-unknown target via # rustup for us. If for whatever reason it does not, you can use this: # rustup target add wasm32-unknown-unknown # We must specify a feature flag because our wasm_bindgen interface is # behind the wasm feature flag. wasm-pack build --target web --out-dir wasm_ui/pkg -- --features wasm
创建 JavaScript 界面
我还向我的人工智能助手询问了我可以用来测试我的 Wasm 界面的尽可能小的 JavaScript 片段。当我们调用 init() 时,浏览器会加载 .wasm 文件,执行 JIT 编译步骤以将可移植的 WebAssembly 二进制文件转换为本机代码,并初始化 WebAssembly 运行时的内存。
[dependencies] wasm-bindgen = { version = "0.2", optional = true } [features] wasm = ["wasm-bindgen"]
就像奇迹中的奇迹一样,它确实有效。诚然,我没有在浏览器中运行任何 Python 代码,但与我的二进制文件交互是一个巨大的步骤,年轻人不能低估它的价值。
下一步是给它一个用 JavaScript 定义的 Python 表达式,并让 Wasm 二进制文件处理数字。正如我在 REPL 文章中提到的,软件项目中的每个入口点都是改进我的抽象的机会,这里肯定会再次出现这种情况。当我翻阅我的 Memphis 存储库时,我意识到哇,我真的应该有一个更好的接口来传递字符串并将其作为 Python 进行评估。就像我说的,我喜欢新的入口点。
目前,我会使用我的交叉检查适配器。 Crosscheck 是我正在进行的测试框架,用于验证 Treewalk 解释器和字节码 VM 对于给定的 Python 输入产生相同的行为。它以空姐所做的事情命名。
这是我更新的 Rust 代码。
#[cfg(feature = "wasm")] mod wasm { use wasm_bindgen::prelude::wasm_bindgen; // Export a function to JavaScript #[wasm_bindgen] pub fn greet() -> String { "Hello from WebAssembly!".to_string() } }
这是我更新的 JavaScript 代码,它调用新的 Rust 评估函数。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Wasm Test</title> </head> <body> <script type="module"> import init, { greet } from './pkg/memphis.js'; async function run() { await init(); console.log(greet()); } run(); </script> </body> </html>
调试 WebAssembly 错误
现在,当我运行它时,我得到了……控制台错误。它因未实现的错误而崩溃。
我查了一下,并不清楚是什么原因造成的。您可以单击源代码,但对于 Wasm 构建来说,它只是一个汇编块,没有引用原始 Rust 函数。
我进行了一些人工智能聊天/谷歌搜索,发现了两种有用的方法。一种是用于 Wasm 构建的 console_log,它在浏览器控制台中显示来自 Rust 代码的日志语句。这对一些人有帮助,但我真正想要的是堆栈跟踪。输入console_error_panic_hook。它立即给了我 Rust 堆栈跟踪,即 CLUTCH。如果您正在构建自己的 Wasm,请立即停止阅读并添加此箱子。我什至不介意你永远读不完这篇文章。费里斯希望你使用这个箱子?以下是我将其添加到我的 Wasm 界面的方法。
#[cfg(feature = "wasm")] mod wasm { use wasm_bindgen::prelude::wasm_bindgen; use crosscheck::{InterpreterTest, TreewalkAdapter}; // Export a function to JavaScript #[wasm_bindgen] pub fn greet() -> String { "Hello from WebAssembly!".to_string() } #[wasm_bindgen] pub fn evaluate(code: String) -> String { let result = TreewalkAdapter.execute(&code); format!("{}", result) } }
我的堆栈跟踪指出了罪魁祸首:我使用 std::env 来请求一些操作系统资源,这在 Wasm 运行时(即沙盒部分)中是不允许的。我将这些调用放在功能标志后面(它们与我如何随意确定 Python 标准库在主机上的位置有关)并再次启动我的构建。在与正确显示我的返回类型相关的一些小失败之后......
它成功了。这是我现在在浏览器控制台中看到的内容。
# wasm-pack helps compile our Rust code to WebAssembly and bundle it # with JavaScript bindings we can call from our HTML/JavaScript page. cargo install wasm-pack # wasm-pack also downloads the wasm32-unknown-unknown target via # rustup for us. If for whatever reason it does not, you can use this: # rustup target add wasm32-unknown-unknown # We must specify a feature flag because our wasm_bindgen interface is # behind the wasm feature flag. wasm-pack build --target web --out-dir wasm_ui/pkg -- --features wasm
tldr 我可以在浏览器中运行Python。 (值得赞扬的是,RustPython 也这样做了:https://rustpython.github.io/demo/。我没有深入研究他们的项目,但它似乎很全面。)Python 列表理解是在 JavaScript 中以字符串形式定义的,响应列表由编译为 Wasm 的 Rust 代码评估,并转换回可由 JavaScript 显示的字符串。
此设置目前仅支持表达式。为了评估语句(并稍后读回其结果),我需要在 Rust 端保留状态。我也梦想构建一个 JavaScript REPL。这听起来像是未来的我的一个问题(而且是一个无聊的梦)。
结局
我已经聊得够久了,所以我打算推迟到下周一再讨论嵌入式 Python。
对诱饵和开关表示歉意。内容日历不等人。
需要明确的是,通过嵌入式 Python,我的意思是在孟菲斯内部嵌入 CPython 解释器,而不是在“嵌入式系统”环境中运行 Python。那会毫无理由地困难。与孟菲斯不同,孟菲斯很难好玩。
如果您想将更多类似的帖子直接发送到您的收件箱,您可以在这里订阅!
别处
除了指导软件工程师之外,我还写了我作为一名成人诊断自闭症患者的经历。更少的代码和相同数量的笑话。
- 为什么我渴望得到认可? - 来自 Scratch 点组织
以上是为 WebAssembly 构建的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Python适合数据科学、Web开发和自动化任务,而C 适用于系统编程、游戏开发和嵌入式系统。 Python以简洁和强大的生态系统着称,C 则以高性能和底层控制能力闻名。

两小时内可以学到Python的基础知识。1.学习变量和数据类型,2.掌握控制结构如if语句和循环,3.了解函数的定义和使用。这些将帮助你开始编写简单的Python程序。

2小时内可以学会Python的基本编程概念和技能。1.学习变量和数据类型,2.掌握控制流(条件语句和循环),3.理解函数的定义和使用,4.通过简单示例和代码片段快速上手Python编程。

Python在游戏和GUI开发中表现出色。1)游戏开发使用Pygame,提供绘图、音频等功能,适合创建2D游戏。2)GUI开发可选择Tkinter或PyQt,Tkinter简单易用,PyQt功能丰富,适合专业开发。

Python更易学且易用,C 则更强大但复杂。1.Python语法简洁,适合初学者,动态类型和自动内存管理使其易用,但可能导致运行时错误。2.C 提供低级控制和高级特性,适合高性能应用,但学习门槛高,需手动管理内存和类型安全。

要在有限的时间内最大化学习Python的效率,可以使用Python的datetime、time和schedule模块。1.datetime模块用于记录和规划学习时间。2.time模块帮助设置学习和休息时间。3.schedule模块自动化安排每周学习任务。

Python在web开发、数据科学、机器学习、自动化和脚本编写等领域有广泛应用。1)在web开发中,Django和Flask框架简化了开发过程。2)数据科学和机器学习领域,NumPy、Pandas、Scikit-learn和TensorFlow库提供了强大支持。3)自动化和脚本编写方面,Python适用于自动化测试和系统管理等任务。

Python在自动化、脚本编写和任务管理中表现出色。1)自动化:通过标准库如os、shutil实现文件备份。2)脚本编写:使用psutil库监控系统资源。3)任务管理:利用schedule库调度任务。Python的易用性和丰富库支持使其在这些领域中成为首选工具。
