
从零构建的JavaScript到WebAssembly编译器和运行时
Porffor是一个从零开始构建的JavaScript到WebAssembly/C编译器和运行时。它采用全AOT编译,无常量运行时代码,最少化Wasm导入。Porffor支持部分JavaScript功能,包括基本语言特性、内置函数和一些提案。项目还包含Wasm引擎Asur、正则表达式引擎Rhemyn和Wasm到C编译器2c。Porffor在支持的功能范围内性能表现优异,尤其是编译为原生二进制文件时。
一个从零开始的实验性 AOT 优化 JS/TS -> Wasm/C 引擎/编译器/运行时,用 JS 编写。研究项目,目前尚不适合严肃使用。<br>
<img src="https://github.com/CanadaHonk/porffor/assets/19228318/de8ad753-8ce3-4dcd-838e-f4d49452f8f8" alt="终端截图显示 Porffor 运行和编译 hello world" width="60%">Porffor 是一个非常独特的 JS 引擎,采用了许多完全不同的方法。它有严重的限制,但它能做的事情,做得相当不错。主要区别:
Porffor 主要是从零开始构建的,唯一不是的部分是解析器(使用 Acorn)。不使用 Binaryen 等,我们自己制作最终的 wasm 二进制文件。你可以将其想象成编译一种是 JavaScript 的子集(某些功能不支持)和超集(新的/自定义 API)的语言。不基于任何特定的规范版本。
不要期望一切都能正常工作!目前仅支持非常有限的 JS。请参见 bench 文件夹中的示例。
npm install -g porffor@latest。就是这么简单(希望如此):)
porf。直接运行,不带脚本文件参数。
porf path/to/script.js
porf wasm path/to/script.js out.wasm。目前它不使用像 WASI 这样的导入标准,所以单独使用基本上是不可用的。
[!警告] 编译为原生二进制 文件使用 2c,Porffor 自己的 Wasm -> C 编译器,这是实验性的。
porf native path/to/script.js out(.exe)。你可以用 --compiler=clang|gcc|zig 指定编译器(默认为 clang),用 --cO=Ofast|O3|O2|O1|O0 指定使用的优化级别(默认为 Ofast)。输出的二进制文件默认也会被剥离。
[!警告] 编译为 C 使用 2c,Porffor 自己的 Wasm -> C 编译器,这是实验性的。
porf c path/to/script.js (out.c)。当不包含输出文件时,将会打印到标准输出。
[!警告] 非常实验性的进行中功能!
porf profile path/to/script.js
[!警告] 非常实验性的进行中功能!
porf debug path/to/script.js
[!警告] 非常实验性的进行中功能!
porf debug-wasm path/to/script.js
--parser=acorn|@babel/parser|meriyah|hermes-parser(默认:acorn)设置使用哪个解析器--parse-types 启用解析类型注解/typescript。如果未设置 -parser,默认更改为 @babel/parser。不进行类型检查--opt-types 使用类型注解作为编译器提示进行优化。不进行类型检查--valtype=i32|i64|f64(默认:f64)设置值类型-O0 禁用优化-O1(默认)启用基本优化(简化指令,树摇 wasm 导入)-O2 启用高级优化(部分求值)。不稳定!eval()/Function() 等(因为是 AOT)Asur 是 Porffor 自己的 Wasm 引擎;它是一个用 JS 编写的有意简化的解释器。它还在开发中。更多详情请参见其自述文件。
Rhemyn 是 Porffor 自己的正则表达式引擎;它将字面正则表达式 AOT 编译为 Wasm 字节码(想起什么了吗?)。它相当基础且还在开发中。更多详情请参见其自述文件。
2c 是 Porffor 自己的 Wasm -> C 编译器,使用生成的 Wasm 字节码和内部信息来生成特定且高效/快速的 C 代码。很少的样板/前置代码或所需的外部文件,仅用于 CLI 二进制文件(与 wasm2c 非常不同)。
有关已实现/支持的优化,请参见优化部分。
这些包括一些早期(阶段 1/0)和/或已停止(最后提交已多年)的提案,但我认为它们相当不错,所以。
Math 提案(阶段 1/0)Math.clamp 提案:Math.clamp(阶段 0 - 最后提交于 2023 年 4 月)Math 扩展提案:Math.scale、Math.radians、Math.degrees、Math.RAD_PER_DEG、Math.DEG_PER_RAD(阶段 1 - 最后提交于 2020 年 9 月)Math.signbit 提案:Math.signbit(阶段 1 - 最后提交于 2020 年 2 月)returnlet/const/var)+-/*%)&|)==、!=等)>、<、>=等)!、+、-)&&、||)let a, b = 0)let [a, ...b] = foo)var/无修饰符)if和if ... elseconst foo = function() { ... })undefined/nulla++、++b、c--等)for循环(for (let i = 0; i < N; i++)等)console.logwhile循环break和continue+=、-=、>>=、&&=等)cond ? a : b)return)throw(仅支持字面量,用于new Error的hack)try { ... } catch { ... }(不提供错误信息)f(a, b); f(0); f(1, 2, 3);)typeofReferenceError), 非函数的运行时错误(TypeError)[]创建数组(如let arr = [ 1, 2, 3 ])arr[ind]访问数组成员(如arr[0])'hello world')str[ind]访问字符串成员(字符)(如str[0])+)(如'a' + 'b')!'' == true)'a' == 'a'、'a' != 'b')??)for...of(数组和字符串)for...inarr[0] = 2、arr[0] += 2等)Array(5)、new Array(1, 2, 3))foo: while (...))do...while循环(foo = 'bar') => { ... })(...foo) => { ... })thisnew Foo)class A {})await promise)NaN和InfinityisNaN()和isFinite()Number的大部分功能(MAX_VALUE、MIN_VALUE、MAX_SAFE_INTEGER、MIN_SAFE_INTEGER、POSITIVE_INFINITY、NEGATIVE_INFINITY、EPSILON、NaN、isNaN、isFinite、isInteger、isSafeInteger)Math函数(sqrt、abs、floor、sign、round、trunc、clz32、fround、random、exp、log、log2、log10、pow、expm1、log1p、sqrt、cbrt、hypot、sin、cos、tan、sinh、cosh、tanh、asinh、acosh、atanh、asin、acos、atan、atan2)globalThis支持Boolean和Numbereval用于字面量Math.random()performance的部分功能(now()、timeOrigin)Array.prototype的大部分方法(at、push、pop、shift、fill、slice、indexOf、lastIndexOf、includes、with、reverse、toReversed、forEach、filter、map、find、findLast、findIndex、findLastIndex、every、some、reduce、reduceRight、join、toString)Array的大部分方法(of、isArray)String.prototype的大部分方法(at、charAt、charCodeAt、toUpperCase、toLowerCase、startsWith、endsWith、indexOf、lastIndexOf、includes、padStart、padEnd、substring、substr、slice、trimStart、trimEnd、trim、toString、big、blink、bold、fixed、italics、small、strike、sub、sup、trimLeft、trimRight、trim)crypto的部分功能(randomUUID)escapebtoaNumber.prototype的大部分方法(toString、toFixed、toExponential)parseIntDateUint8Array、Int32Array等)PromisePorffor使用独特的版本控制系统,示例如下:0.18.2+2aa3f0589。让我们来分解一下:
0 - 主版本号,始终为0,因为Porffor还未准备就绪18 - 次版本号,总Test262通过百分比(向下取整到最接近的整数)2 - 微版本号,该次版本的构建编号(每次发布/git推送时递增)2aa3f0589 - 提交哈希值对于大多数支持的功能,Porffor与大多数解释器和常见引擎(在不使用JIT的情况下)相比速度极快。对于那些使用JIT的引擎,默认情况下通常较慢,但可以通过编译器参数和类型化输入赶上,在编译为本机二进制文件时更是如此。
主要用于减小体积。我不太关心编译器性能/时间,只要合理即可。我们不使用/依赖外部优化工具(如wasm-opt等),而是在编译器内部进行优化,创建比wasm-opt本身产生的代码体积更小的代码,因为我们拥有更多内部信息。
--tail-call标志后面)local.set、local.get -> local.teei32.const 0、i32.eq -> i32.eqzi64.extend_i32_s、i32.wrap_i64 -> ``f64.convert_i32_u、i32.trunc_sat_f64_s -> ``return、end -> endf64.const、i32.trunc_sat_f64_s -> i32.const)br 指令)Porffor 可以通过一些技巧/转换来运行 Test262,这些技巧/转换移除了不支持的特性,同时仍然执行相同的断言(例如使用仅包含字面量的简化错误消息)。目前通过率超过 14%(具体数据和详情请查看最新提交描述)。使用 node test262 进行测试,它还会显示上次提交和当前结果之间的整体差异。
compiler:包含编译 器本身
2c.js:porffor 的自定义 wasm-to-c 引擎allocators.js:支持各种语言特性的静态和动态分配器assemble.js:将 wasm 操作和元数据组装成 wasm 模块/文件builtins.js:引擎的所有手动编写的内置功能(规范、自定义、变量、函数)builtins_object.js:所有各种内置对象(如 String、globalThis 等)builtins_precompiled.js:从 builtins/ 文件夹动态生成的内置功能codegen.js:代码(wasm)生成,ast -> wasm。主要工作量在此cyclone.js:wasm 部分常量求值器(快速且危险,因此称为"cyclone")decompile.js:用于调试信息的基本 wasm 反编译器diagram.js:生成 Mermaid 图表embedding.js:嵌入常量的工具encoding.js:将内容编码为 wasm 所需字节的工具expression.js:将大多数运算符映射到操作码(高级运算符作为内置功能,如 f64_%)havoc.js:wasm 重写库(它对 wasm 字节码造成破坏,因此称为"havoc")index.js:执行所有编译器步骤,输入代码,输出 wasmopt.js:自制的 wasm 字节码优化器parse.js:简单封装 acorn 的解析器pgo.js:基于概要引导的优化器precompile.js:生成 builtins_precompied.js 的工具prefs.js:读取命令行参数的工具prototype.js:一些内置原型函数types.js:每个内置类型的定义wasmSpec.js:来自 wasm 规范的"枚举"/信息wrap.js:编译器的包装器,实例化并生成友好的导出runner:包含使用编译器运行 JS 的工具
index.js:主文件,您可能想使用这个info.js:运行时打印额外信息repl.js:基本的 repl(使用 node:repl)rhemyn:包含 Rhemyn - 我们的正则表达式引擎(由 Porffor 使用)
compile.js:将正则表达式 ast 编译为 wasm 字节码parse.js:自己的正则表达式解析器test:包含许多测试文件,用于测试大多数支持的功能
test262:test262 运行器和工具
目前,Porffor 在功能和特性上有严重限制,但它有一些关键优势:
没有特定顺序,也不做保证,只是可能很快发生的事情™
escape() 优化vscode-ext 中有一个 vscode 扩展,它调整了 JS 语法高亮,使其更适合 porffor 特性(例如,在内联汇编中高亮 wasm)。
Porffor 有意不使用尚未广泛实现的 Wasm 提案(例如 GC),以便它可以在尽可能多的地方使用。
威尔士语中的"紫色"是 porffor。为什么选择紫色?
是的!
不,它们在内部完全不同,并且有着非常不同的目标和理念:


AI一键生成PPT,就用博思AIPPT!
博思AIPPT,新一代的AI生成PPT平台,支持智能生成PPT、AI美化PPT、文本&链接生成PPT、导入Word/PDF/Markdown文档生成PPT等,内置海量精美PPT模板,涵盖商务、教育、科技等不同风格,同时针对每个页面提供多种版式,一键自适应切换,完美适配各种办公场景。


AI赋能电商视觉革命,一站式智能商拍平台
潮际好麦深耕服装行业,是国内AI试衣效果最好的软件。使用先进AIGC能力为电商卖家批量提供优质的、低成本的商拍图。合作品牌有Shein、Lazada、安踏、百丽等65个国内外头部品牌,以及国内10万+淘宝、天猫、京东等主流平台的品牌商家,为卖家节省将近85%的出图成本,提升约3倍出图效率,让品牌能够快速上架。


企业专属的AI法律顾问
iTerms是法大大集团旗下法律子品牌,基于最先进的大语言模型(LLM)、专业的法律知识库和强大的智能体架构,帮助企业扫清合规障碍,筑牢风控防线,成为您企业专属的AI法律顾问。


稳定高效的流量提升解决方案,助力品牌曝光
稳定高效的流量提升解决方案,助力品牌曝光


最新版Sora2模型免费使用,一键生成无水印视频
最新版Sora2模型免费使用,一键生成无水印视频


实时 语音翻译/同声传译工具
Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。


选题、配图、成文,一站式创作,让内容运营更高效
讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。


AI辅助编程,代码自动修复
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。


最强AI数据分析助手
小浣熊家族Raccoon,您的AI智能助手,致力于通过先进的人工智能技术,为用户提供高效、便捷的智能服务。无论是日常咨询还是专业问题解答,小浣熊都能以快速、准确的响应满足您的需求,让您的生活更加智能便捷。


像人一样思考的AI智能体
imini 是一款超级AI智能体,能根据人类指令,自主思考、自主完成、并且交付结果的AI智能体。
最新AI工具、AI资讯
独家AI资源、AI项目落地

微信扫一扫关注公众号