This document describes changes between tagged Binaryen versions.
To browse or download snapshots of old tagged versions, visit https://github.com/WebAssembly/binaryen/releases.
Not all changes are documented here. In particular, new features, user-oriented fixes, options, command-line parameters, usage changes, deprecations, significant internal modifications and optimizations etc. generally deserve a mention. To examine the full set of changes between versions, visit the link to full changeset diff at the end of each section.
CallRef and ReturnCallRef matching the semantics of Call and ReturnCall.MI_NO_OPT_ARCH to fix Raspberry Pi 4 on Arm64. (#7837)wasm-split‘s --multi-split mode now supports more options: --no-placeholders, --import-namespace, --emit-module-names, --emit-text, --symbolmap, and --placeholdermap. Because --no-placeholders is false by default and until now --multi-split didn’t use placeholders at all, this is a breaking change. If you want to continue to do multi-split without placeholders, you need to explicitly specify --no-placeholders. (#7781, #7789, #7792)--string-lifting pass that raises imported string operations and constants into stringref in Binaryen IR (which can then be fully optimized, and typically lowered back down with --string-lowering). (#7389)BINARYEN_FUZZER_MAX_BYTES env var. (#7832)-all will enable that feature (among all others), and cause GC-using binaries to use that feature, which most VMs do not yet support. To avoid such VM errors, either enable only the features you want, or disable it: -all --disable-custom-descriptors.string is now a subtype of ext (rather than any). This allows better transformations for strings, like an inverse of StringLowering, but will error on codebases that depend on being able to pass strings into anyrefs. (#7373)--closed-world (but also it now provides fewer warnings to users that enable closed world on code which does not conform to the requirements of that mode, which can lead to changes in runtime behavior; for the long-term plans, see #6965). (#7019)exnref (newest version of Wasm EH) optimizations: #7013, #6996, #6997, #6983, #6980--preserve-type-order option that minimizes text format changes in type ordering. (#6916)--metrics=text will show that text before the metrics. Each instance of Metrics can have unique text, --metrics=before -O3 --metrics=after. (#6792)--skip-pass on the commandline multiple times (#6714).--heap-store-optimization pass. (#6882)(; has Stack IR ;) (as Stack IR only exists during binary writing).--generate-stack-ir, --optimize-stack-ir, and --print-stack-ir are now flags and not passes. That means the order of operations may seem different, as they apply during binary writing (or, if no binary is written but we were still asked to print StackIR, wasm-opt does it at the very end).BinaryenModulePrintStackIR and similar APIs do not receive an optimize flag, as they read the PassOption optimizeStackIR instead.else branches must now be placed above the instruction inside the else branch rather than on the else branch itself.BinaryenModuleReadWithFeatures function to the C API that allows to configure which features to enable in the parser. (#6380)string.const instructions must now be valid WTF-8.TraverseCalls flag for ExpressionRunner is removed.tuple.make 2 (#6169) (#6172) (#6170).if expressions now requires then and else to introduce the two branch arms, matching the spec (#6201).BINARYEN_PRINT_FULL. (#5904)--multimemory to match its naming in LLVM. (#5890)--reorder-functions-by-name. (#5811)BinaryenAddFunctionWithHeapType which is like BinaryenAddFunction but takes a heap type. The old function is kept for backwards compatibility and as a convenience. (#5829)wasm-merge tool. This is a full rewrite of the previous wasm-merge tool that was removed from the tree in the past. The new version is much simpler after recent improvements to multi-memory and multi-table. The rewrite was motivated by new use cases for merging modules in the context of WasmGC.--nominal and --hybrid command line options and related API functions have been removed. The only supported type system is now the standard isorecursive (i.e. hybrid) type system. (#5672)-O3 -Os now do the expected thing and run -O3 followed by -Os. Previously the last of them set the defaults that were used by all executions, so -O3 -Os was equivalent to -Os -Os. (There is no change to the default optimization level that other passes can see. For example, --precompute-propagate -O2 -O1 will run --precompute-propagate at opt level 1, as the global default is set to 2 and then overridden to 1. The only change is that the passes run by -O2 will actually run -O2 now, while before they'd use the global default which made them do -O1.)--closed-world flag. This enables more optimizations in GC mode as it lets us assume that we can change types inside the module.ref.is_func, ref.is_data, and ref.is_i31 have been removed from the C and JS APIs and RefIs has been replaced with RefIsNull.Data and Dataref have been replaced with types Struct and Structref in the C and JS APIs.BinaryenStringNew now takes an additional last argument, try_, indicating whether the instruction is one of string.new_utf8_try respectively string.new_utf8_array_try.BinaryenStringEq now takes an additional second argument, op, that is either BinaryenStringEqEqual() if the instruction is string.eq or BinaryenStringEqCompare() if the instruction is string.compare.memory64 argument for BinaryenSetMemory and new BinaryenMemoryIs64 C-API method to determine 64-bit memory. (#4963)TypeBuilderSetSubType now takes a supertype as the second argument.call_ref now takes a mandatory signature type immediate.THROW_ON_FATAL is defined at compile-time, then fatal errors will throw a std::runtime_error instead of terminating the process. This may be used by embedders of Binaryen to recover from errors.none, nofunc, and noextern. RefNull expressions and null Literals must now have type nullref, nullfuncref, or nullexternref.BinaryenTypeI31ref and BinaryenTypeDataref now return nullable types.sign-extension and mutable-globals features are now both enabled by default in all tools. This is in order to match llvm's defaults (See https://reviews.llvm.org/D125728).--pass-arg=directize-initial-contents-immutable which indicates the initial table contents are immutable. That is the case for LLVM, for example, and it allows us to optimize more indirect calls to direct ones. (#4942)BinaryenTypeDataref()). (#4755)BinaryenModulePrintStackIR, BinaryenModuleWriteStackIR and BinaryenModuleAllocateAndWriteStackIR now have an extra boolean argument optimize. (#4832)let instruction that has been removed from the typed function references spec.i31ref and dataref are now nullable to match the latest GC spec. (#4843)extern.externalize and extern.internalize. (#4975)pip3 install -r requirements-dev.txt.getSideEffects(). It is now mandatory to pass in the module.import Binaryen from "path/to/binaryen.js"; const binaryen = await Binaryen(); ...
Add BinaryenUpdateMaps to the C API.
Adds a TrapsNeverHappen mode (#4059). This has many of the benefits of IgnoreImplicitTraps, but can be used safely in more cases. IgnoreImplicitTraps is now deprecated.
Adds type argument for BinaryenAddTable method (#4107). For the binaryen.js api this parameter is optional and by default is set to funcref type.
Replace BinaryenExpressionGetSideEffects's features parameter with a module parameter.
OptimizeInstructions now lifts identical code in select/if arms (#3828). This may cause direct BinaryenTupleExtract(BinaryenTupleMake(...)) to use multivalue types.
BinaryenSetFunctionTable and module.setFunctionTable have been removed in favor of BinaryenAddTable and module.addTable respectively.BinaryenIsFunctionTableImported is removed.BinaryenElementSegmentRef has been added to the C API with new apis in both C & JS:BinaryenAddActiveElementSegmentBinaryenAddPassiveElementSegmentBinaryenRemoveElementSegmentBinaryenGetElementSegmentBinaryenGetElementSegmentByIndexBinaryenElementSegmentGetNameBinaryenElementSegmentSetNameBinaryenElementSegmentGetTableBinaryenElementSegmentSetTableBinayenElementSegmentIsPassivemodule.addActiveElementSegmentmodule.addPassiveElementSegmentmodule.removeElementSegmentmodule.getElementSegmentmodule.getElementSegmentByIndexmodule.getTableSegmentsmodule.getNumElementSegmentsbinaryen.getElementSegmentInfoBinaryenAddTable and module.addTable no longer take offset and function names.BinaryenGetNumFunctionTableSegments is replaced with BinaryenGetNumElementSegments.BinaryenGetFunctionTableSegmentOffset is replaced with BinaryenElementSegmentGetOffset.BinaryenGetFunctionTableSegmentLength is replaced with BinaryenElementSegmentGetLength.BinaryenGetFunctionTableSegmentData is replaced with BinaryenElementSegmentGetData.bool instead of int.wasm-dis now supports options to enable or disable Wasm features.call_indirect and return_call_indirect now take an additional table name parameter. This is necessary for reference types support.call_indirect table name:BinaryenCallIndirectGetTableBinaryenCallIndirectSetTableCallIndirect.tableBinaryenAddTableBinaryenRemoveTableBinaryenGetNumTablesBinaryenGetTableBinaryenGetTableByIndexBinaryenTableGetNameBinaryenTableGetInitialBinaryenTableHasMaxBinaryenTableGetMaxBinaryenTableImportGetModuleBinaryenTableImportGetBasemodule.addTablemodule.removeTablemodule.getTablemodule.getTableByIndexmodule.getNumTablesbinaryen.getTableInfo--zero-filled-memory. Large binaries with lots of empty bytes in the data section may regress without that flag. Toolchains like Emscripten can pass the flag automatically for users if they know it is right to assume, which can avoid any regressions. (#3306)RefFunc C and JS API constructors (BinaryenRefFunc and ref.func respectively) now take an extra type parameter, similar to RefNull. This is necessary for typed function references support.module.atomic.notify -> module.memory.atomic.notifymodule.i32.atomic.wait -> module.memory.atomic.wait32module.i64.atomic.wait -> module.memory.atomic.wait64NUM_PARAMS in FuncCastEmulation a runtime configuration option named max-func-params. This defaults to the original value of 16.BinaryenGetFunction, BinaryenGetGlobal and BinaryenGetEvent now return NULL instead of aborting when the respective element does not yet exist.--fast-math mode. (#3155)--enable-anyref enables just the anyref type incl. basic subtyping of externref, funcref and exnref (if enabled).Host expression and its respective APIs have been refactored into separate MemorySize and MemoryGrow expressions to align with other memory instructions.BinaryenBlockGetChild to BinaryenBlockGetChildAtBinaryenSwitchGetName to BinaryenSwitchGetNameAtBinaryenCallGetOperand to BinaryenCallGetOperandAtBinaryenCallIndirectGetOperand to BinaryenCallIndirectGetOperandAtBinaryenHostGetOperand to BinaryenHostGetOperandAtBinaryenThrowGetOperand to BinaryenThrowGetOperandAtBinaryenTupleMakeGetOperand to BinaryenTupleMakeGetOperandAtBinaryenSetAPITracing and the JS-API’s setAPITracing have been removed because this feature was not very useful anymore and had a significant maintainance cost.stackSave, stackAlloc, stackRestore function. It not expects them to be included in the input file.multivalue feature has been added. It allows functions and control flow structures to return tuples and for locals and globals to have tuple types. Tuples are created with the new tuple.make pseudoinstruction and their elements are retrieved with the new tuple.extract pseudoinstruction.dylink section in Binaryen IR, so we can read, write, and update it.BinaryenExpressionGetSideEffects (C API) and getSideEffects (JS API) now takes an additional features parameter.ref.null, ref.is_null, ref.func, and typed select. Table instructions are not supported yet. For typed select, C/JS API can take an additional ‘type’ parameter.local.tee's C/Binaryen.js API now takes an additional type parameter for its local type, like local.get. This is required to handle subtypes.notify -> atomic.notifyi32.wait / i64.wait -> i32.atomic.wait / i64.atomic.waitflags argument in setMemory function is removed.atomic.fence instruction support is added.mutable parameter to BinaryenAddGlobalImport.offset parameter to BinaryenSetFunctionTable.params and results types local to each function.binaryen_wasm target. Unlike the JS variant, the Wasm variant requires asynchronously awaiting the Wasm blob's instantiation and initialization before being usable, using the binaryen.ready promise, e.g. binaryen.ready.then(() => ...).binaryen (was Binaryen) as its global name to align with the npm package.getMemorySegmentInfoByIndex now has the same structure as the respective inputs on creation (byteOffset -> offset).tail-call feature including the return_call and return_call_indirect instructions is ready to use.typeuse ::= (type index|name)+ |
(type index|name)+ (param ..)* (result ..)* |
(param ..)* (result ..)*
Also, all (local) nodes in function definition should be after all typeuse elements.get_local / getLocalset_local / setLocaltee_local / teeLocalget_global / getGlobalset_global / setGlobalcurrent_memory / currentMemorygrow_memory / growMemory They are now available as their new instruction names: local.get, local.set, local.tee, global.get, global.set, memory.size, and memory.grow.namedGlobals to metadata output of wasm-emscripten-finalizesegmentPassive argument to BinaryenSetMemory for marking segments passive.-o - print to stdout instead of a file named “-”.RelooperCreate in the C API now has a Module parameter, and RelooperRenderAndDispose does not.Relooper constructor receive the Module.BinaryenSetFunctionTable in the C API no longer accepts an array of functions, instead it accepts an array of function names, const char** funcNames. Previously, you could not include imported functions because they are of type BinaryenImportRef instead of BinaryenFunctionRef. #1650
BinaryenSetFunctionTable in the C API now expects the initial and maximum table size as additional parameters, like BinaryenSetMemory does for pages, so tables can be grown dynamically. #1687
Add shared parameters to BinaryenAddMemoryImport and BinaryenSetMemory, to support a shared memory. #1686