Skip to content

Add Hexana (IntelliJ + VS Code plugin) to the tools matrix #543

@minamoto79

Description

@minamoto79

What this is

Hexana is a binary inspector for WebAssembly modules and components. It ships as two plugins built from one parser:

  • IntelliJ-platform plugin (IDEA, CLion, GoLand, RustRover, WebStorm, etc.) — https://plugins.jetbrains.com/plugin/29090-hexana
  • VS Code extension and Open VSX — marketplace.visualstudio.com/items?itemName=JetBrains.hexana-wasm, open-vsx.org/extension/JetBrains/hexana-wasm

Repo (issue tracker, not source): https://github.com/JetBrains/hexana
License: JetBrains User Agreement (proprietary, free to install)

The same Kotlin parser backs both plugins. It reads core modules and components and feeds an editor that shows section structure, type signatures, function bodies, and disassembled native code where applicable. No execution — Hexana is a viewer/analyzer, not a runtime.

Why I'm asking before sending a PR

The matrix on https://webassembly.github.io/website/features/ shows engines and toolchains, plus a tools column. Before I send a PR, I'd like to know which of these you'd prefer:

  1. Fit Hexana into the existing tools column. Binary inspectors aren't quite the same shape as wasm-tools / wabt / binaryen — they observe, they don't transform — but the column is the closest existing home.
  2. Add a new column for IDE integrations / inspectors. Hexana, and probably any future viewer-style entries, sit between engines and toolchains. If you'd accept a new column, I'd be happy to propose a schema.
  3. Not a fit for this matrix. Reasonable answer; I'll close this out and won't send the PR.

If (1) or (2): here is what I'd claim per row. I've kept "partial" rows narrow and stated the specific gap in one line.

Proposed feature-support rows (keys from features.json)

Key Status Gap, if any
bulkMemory full
componentModel partial See note below.
exceptions (legacy) full
exceptionsFinal full
extendedConst full
extendedNameSection full All 12 sub-sections read (module, functions, locals, labels, types, tables, memories, globals, elems, data segments, fields, tags).
gc full All 0xFB:0x000x1E opcodes; rectype groups; sub-typing with final/non-final marker; struct / array / func comptype.
memory64 partial 64-bit limit flags and memidx-carrying memory ops are decoded; not separately validated against the rest of the proposal scope.
multiValue partial Known bug: the empty block-type 0x40 is misdecoded as a reference type instead of "no type". Type-index multi-value blocks work.
mutableGlobals full
referenceTypes full ref.null (with heaptype), ref.is_null, ref.func, ref.eq, ref.as_non_null, br_on_null, br_on_non_null, funcref / externref.
relaxedSimd full Lane-select for i8/i16/i32/i64, relaxed madd/nmadd/min/max for f32x4 and f64x2, relaxed swizzle, q15-mul, dot products.
saturatedFloatToInt full
signExtensions full
simd full Full 0xFD prefix: v128 load/store/const, shuffle, splat, extract/replace_lane, comparison, bitwise, arithmetic, conversions.
tailCall full return_call, return_call_indirect, call_ref, return_call_ref.
threads partial Full atomic opcode family (0xFE prefix): notify, wait32/64, fence, atomic load/store, and the rmw add/sub/and/or/xor/xchg/cmpxchg families. Shared-memory limit flag 0x03 is parsed; open-shared flag 0x02 is not.
typedFunctionReferences full 0x63 nullable and 0x64 non-null typed refs; call_ref / return_call_ref.
compactImportSection none No dedicated handler.
customPageSizes none No dedicated handler.
wideArithmetic none No dedicated handler.
branchHinting none No dedicated handler.
stackSwitching none Opcodes in the reserved range are tolerated but not structurally decoded.

Note on componentModel

We treat the wasm-tools encoding as ground truth rather than the CG phase number. Against that bar:

  • Component preamble (\0asm 0x0d 0x00 0x01 0x00) detected; 10 of 13 top-level section IDs fully decoded (core-instance, core-type, nested component, instance, alias, type, import, export, plus custom delegated to the core path).
  • Component type model covers all 14 primitives including error-context, plus record / variant / list / array / tuple / flags / enum / option / result / own / borrow / stream / future, sync + async function types, and resource types.
  • The canon section is a stub. Specifically: canon.lift, canon.lower, canon.resource.{new,drop,rep} are not decoded, and the WASI 0.3 async built-ins stream.{new,read,write,cancel-read,cancel-write}, future.{new,read,write,cancel-read,cancel-write}, and error-context.{new,debug-message,drop} are not decoded either.
  • The component-level start section is a stub.
  • The value section has a latent ID issue on our side (the spec uses id 12).
  • The core:module section is recorded by offset/size but the embedded core module is not yet sub-parsed through the same handler.
  • The component-type custom section — the mechanism wasm-tools component embed / cargo-component / componentize-py use to ship a WIT world inside a binary — is not yet extracted.

So partial. I'd rather under-claim and upgrade later than over-claim.

WIT support

Hexana implements the Component Model's WIT grammar as a first-class IDE language, not as plain-text tokenisation. PSI-level features: highlighting, completion, references, find-usages, rename, folding, inspections, documentation-on-hover, breadcrumbs, brace matching, and a formatter. PSI-first constructs: package (with semver), interface, world, type alias, record, variant, enum, flags, resource (opaque and with body, including constructor / static / instance methods), function types (func and async func), handle types (borrow<T> and owned), list<T> / list<T, N>, option<T>, result<T,E>, tuple<...>, future<T>, stream<T>, use, include with rename map, and @since / @unstable / @deprecated feature gates. WASI 0.2 and 0.3 standard interfaces are indexed as built-ins.

Known WIT-side gaps, for honesty: error-context as a first-class type is not in the grammar yet; async func is parsed and highlighted but does not yet have a dedicated PSI subtype or async-specific inspections; named result lists (-> (name: ty, ...)) are not yet supported; flags fields do not have per-field PSI nodes (so per-bit rename and find-usages are not available).

If a dedicated WIT row in the matrix would make sense, I'm happy to discuss what the schema should look like — probably grammar coverage plus binary component-type round-trip status.

One more note

Hexana also parses DWARF debug info embedded as a WASM custom section. It isn't on this matrix and I don't expect it to be — flagging in case it's relevant to a future addition.

Offer

Hexana's source isn't public, so I can't link per-row to file paths the way a wasm-tools PR could. If you green-light a PR (option 1 or option 2 above), I'm happy to elaborate on any row in this thread — including, where useful, building a small reproducer module that demonstrates Hexana decoding the relevant section or opcodes — so the claims are verifiable end-to-end rather than just on my word.

Thanks for maintaining this list — it's the first place I send people who ask what the standard supports today.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions