crystal-binaryen

Crystal bindings for binaryen

crystal-binaryen

Crystal bindings for binaryen. Two layers: a hand-curated LibBinaryen FFI and an idiomatic Binaryen::* wrapper around it.

Installation

dependencies:
  binaryen:
    github: bcardiff/crystal-binaryen

You also need libbinaryen available at link time. Suggestions:

  • macOS via Homebrew: brew install binaryen
  • nix / devenv: see this repo's devenv.nix
  • Linux distros: package name varies; or build from source

Usage

The shortest example:

require "binaryen"

Binaryen::Module.open do |mod|
  i32 = Binaryen::Type.i32
  body = mod.binary(Binaryen::Op::AddI32,
    mod.local_get(0_u32, i32),
    mod.local_get(1_u32, i32))
  mod.add_function("add",
    params: Binaryen::Type[i32, i32], results: i32,
    vars: [] of Binaryen::Type, body: body)
  mod.add_function_export("add", "add")
  mod.validate!
  puts mod.to_wat
end

See examples/ for a few more, including a memory + import example (double_and_log.cr) and a small block DSL form (add_dsl.cr).

Architecture

  • src/binaryen/lib_binaryen.cr — hand-curated raw FFI for tier-1 surface (~80 functions). Everything has correct return types.
  • src/binaryen/*.cr — idiomatic wrappers (Module, Type, Literal, Op, Expression, Function, Export, Import, Global, Memory, errors, Disposable mixin).
  • src/binaryen/dsl.cr — optional block DSL (require "binaryen/dsl"), used in examples.
  • src/binaryen/raw.cr — re-exports LibBinaryen for power users (require "binaryen/raw").

Status

Tier-1 (current): module create/dispose, value types, MVP expressions, function add/export/import, memory, validate, optimize, write/read text+binary.

Tier-2 / Tier-3 (future): atomics, SIMD, multivalue refinements, ref types, exceptions, tail calls, table operations, element segments, tags, GC types, type builder, relooper, expression runner. Adding any of these is bounded work — look up the C signature in binaryen-c.h, add a fun line to src/binaryen/lib_binaryen.cr, write a thin Crystal wrapper.

Known limitations

  • Binaryen::Module.parse_text does not catch invalid WAT cleanly: the underlying BinaryenModuleParse aborts the process on parse errors rather than returning null. Pass only WAT you trust.
  • The shard does not run wasm. It only emits, optimizes, parses, and prints modules. Use a runtime (wasmtime, wasmer, browser) to execute.

License

MIT — see LICENSE.

Repository

crystal-binaryen

Owner
Statistic
  • 0
  • 0
  • 0
  • 0
  • 0
  • 19 days ago
  • May 7, 2026
License

MIT License

Links
Synced at

Thu, 07 May 2026 17:20:07 GMT

Languages