
WebAssembly编译器和优化工具链库
Binaryen是一个C++编写的WebAssembly编译器和工具链库。它提供C和JavaScript API,支持WebAssembly输入,内部IR支持并行优化。其优化器可 改善代码大小和性能,能作为独立编译器后端。Binaryen简化了WebAssembly的编译和优化过程。
Binaryen is a compiler and toolchain infrastructure library for WebAssembly, written in C++. It aims to make [compiling to WebAssembly] easy, fast, and effective:
Easy: Binaryen has a simple [C API] in a single header, and can also be [used from JavaScript][JS_API]. It accepts input in [WebAssembly-like form][compile_to_wasm] but also accepts a general [control flow graph] for compilers that prefer that.
Fast: Binaryen's internal IR uses compact data structures and is designed for completely parallel codegen and optimization, using all available CPU cores. Binaryen's IR also compiles down to WebAssembly extremely easily and quickly because it is essentially a subset of WebAssembly.
Effective: Binaryen's optimizer has many passes (see an overview later down) that can improve code size and speed. These optimizations aim to make Binaryen powerful enough to be used as a [compiler backend][backend] by itself. One specific area of focus is on WebAssembly-specific optimizations (that general-purpose compilers might not do), which you can think of as wasm [minification], similar to minification for JavaScript, CSS, etc., all of which are language-specific.
Toolchains using Binaryen as a component (typically running wasm-opt) include:
For more on how some of those work, see the toolchain architecture parts of the V8 WasmGC porting blogpost.
Compilers using Binaryen as a library include:
AssemblyScript which compiles a variant of TypeScript to WebAssemblywasm2js which compiles WebAssembly to JSAsterius which compiles Haskell to WebAssemblyGrain which compiles Grain to WebAssemblyBinaryen also provides a set of toolchain utilities that can
Consult the contributing instructions if you're interested in participating.
Binaryen's internal IR is designed to be
There are a few differences between Binaryen IR and the WebAssembly language:
catch blocks in the
exception handling feature) are represented as pop subexpressions.--generate-stack-ir --print-stack-ir, which prints Stack IR,
this is guaranteed to be valid for wasm parsers.)ref.func must be either in the table, or declared via an
(elem declare func $..). Binaryen will emit that data when necessary, but
it does not represent it in IR. That is, IR can be worked on without needing
to think about declaring function references.local.get must be
structurally dominated by a local.set in order to validate (that ensures
we do not read the default value of null). Despite being aligned with the
wasm spec, there are some minor details that you may notice:
Block in Binaryen IR does not interfere with validation.
Nameless blocks are never emitted into the binary format (we just emit
their contents), so we ignore them for purposes of non-nullable locals. As
a result, if you read wasm text emitted by Binaryen then you may see what
seems to be code that should not validate per the spec (and may not
validate in wasm text parsers), but that difference will not exist in the
binary format (binaries emitted by Binaryen will always work everywhere,
aside for bugs of course).requiresNonNullableLocalFixups() hook in pass.h and the
LocalStructuralDominance class.br_if output types are more refined in Binaryen IR: they have the type of
the value, when a value flows in. In the wasm spec the type is that of the
branch target, which may be less refined. Using the more refined type here
ensures that we optimize in the best way possible, using all the type
information, but it does mean that some roundtripping operations may look a
little different. In particular, when we emit a br_if whose type is more
refined in Binaryen IR then we emit a cast right after it, so that the
output has the right type in the wasm spec. That may cause a few bytes of
extra size in rare cases (we avoid this overhead in the common case where
the br_if value is unused).stringview_wtf16 etc.) to be cast using
ref.cast. This simplifies the IR, as it allows ref.cast to always be
used in all places (and it is lowered to ref.as_non_null where possible
in the optimizer). The stringref spec does not seem to allow this though,
and to fix that the binary writer will replace ref.cast that casts a
string view to a non-nullable type to ref.as_non_null. A ref.cast of a
string view that is a no-op is skipped entirely.As a result, you might notice that round-trip conversions (wasm => Binaryen IR => wasm) change code a little in some corner cases.
src/wasm-stack.h). Stack IR allows a bunch of optimizations that are
tailored for the stack machine form of WebAssembly's binary format (but Stack
IR is less efficient for general optimizations than the main Binaryen IR). If
you have a wasm file that has been particularly well-optimized, a simple
round-trip conversion (just read and write, without optimization) may cause
more noticeable differences, as Binaryen fits it into Binaryen IR's more
structured format. If you also optimize during the round-trip conversion then
Stack IR opts will be run and the final wasm will be better optimized.Notes when working with Binaryen IR:
Binaryen intrinsic functions look like calls to imports, e.g.,
(import "binaryen-intrinsics" "foo" (func $foo))
Implementing them that way allows them to be read and written by other tools, and it avoids confusing errors on a binary format error that could happen in those tools if we had a custom binary format extension.
An intrinsic method may be optimized away by the optimizer. If it is not, it must be lowered before shipping the wasm, as otherwise it will look like a call to an import that does not exist (and VMs will show an error on not having a proper value for that import). That final lowering is not done automatically. A user of intrinsics must run the pass for that explicitly, because the tools do not know when the user intends to finish optimizing, as the user may have a pipeline of multiple optimization steps, or may be doing local experimentation, or fuzzing/reducing, etc. Only the user knows when the final optimization happens before the wasm is "final" and ready to be shipped. Note that, in general, some additional optimizations may be possible after the final lowering, and so a useful pattern is to optimize once normally with intrinsics, then lower them away, then optimize after that, e.g.:
wasm-opt input.wasm -o output.wasm -O --intrinsic-lowering -O
Each intrinsic defines its semantics, which includes what the optimizer is allowed to do with it and what the final lowering will turn it to. See intrinsics.h for the detailed definitions. A quick summary appears here:
call.without.effects: Similar to a call_ref in that it receives
parameters, and a reference to a function to call, and calls that function
with those parameters, except that the optimizer can assume the call has no
side effects, and may be able to optimize it out (if it does not have a
result that is used, generally).This repository contains code that builds the following tools in bin/ (see the building instructions):
wasm-opt: Loads WebAssembly and runs Binaryen IR passes on it.wasm-as: Assembles WebAssembly in text format (currently S-Expression
format) into binary format (going through Binaryen IR).wasm-dis: Un-assembles WebAssembly in binary format into text format
(going through Binaryen IR).wasm2js: A WebAssembly-to-JS compiler. This is used by Emscripten to
generate JavaScript as an alternative to WebAssembly.wasm-reduce: A testcase reducer for WebAssembly files. Given a wasm file
that is interesting for some reason (say, it crashes a specific VM),
wasm-reduce can find a smaller wasm file that has the same property, which is
often easier to debug. See the
docs
for more details.wasm-shell: A shell that can load and interpret WebAssembly code. It can
also run the spec test suite.wasm-emscripten-finalize: Takes a wasm binary produced by llvm+lld and
performs emscripten-specific passes over it.wasm-ctor-eval: A tool that can execute functions (or parts of functions)
at compile time.wasm-merge: Merges multiple wasm files into a single file, connecting
corresponding imports to exports as it does so. Like a bundler for JS, but
for wasm.wasm-metadce: A tool to remove parts of Wasm files in a flexible way
that depends on how the module is used.binaryen.js: A standalone JavaScript library that exposes Binaryen methods for creating and optimizing Wasm modules. For builds, see binaryen.js on npm (or download it directly from GitHub or unpkg). Minimal requirements: Node.js v15.8 or Chrome v75 or Firefox v78.All of the Binaryen tools are deterministic, that is, given the same inputs you should always get the same outputs. (If you see a case that behaves otherwise, please file an issue.)
Usage instructions for each are below.
Binaryen contains
a lot of optimization passes
to make WebAssembly smaller and faster. You can run the Binaryen optimizer by
using wasm-opt, but also they can be run while using other tools, like
wasm2js and wasm-metadce.
addDefaultFunctionOptimizationPasses.

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


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


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


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


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


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


像人一样思考的AI智能体
imini 是一款超级AI智能体,能根据人类指令,自主思考、自主完成、并且交付结果的AI智能体。


AI数字人视频创作平台
Keevx 一款开箱即用的AI数字人视频创作平台,广泛适用于电商广告、企业培训与社媒宣传,让全球企业与个人创作者无需拍摄剪辑,就能快速生成多语言、高质量的专业视频。


一站式AI创作平台
提供 AI 驱动的图片、视频生成及数字人等功能,助力创意创作


AI办公助手,复杂任务高效处理
AI办公助手,复杂任务高效处理。办公效率低?扣子空间AI助手支持播客生成、PPT制作、网页开发及报告写作,覆盖科研、商业、舆情等领域的专家Agent 7x24小时响应,生活工作无缝切换,提升50%效率!
最新AI工具、AI资讯
独家AI资源、AI项目落地

微信扫一扫关注公众号