Current section
Files
Jump to
Current section
Files
lib/mix/tasks/firebird.inspect.ex
defmodule Mix.Tasks.Firebird.Inspect do
@moduledoc """
Inspect a WASM module and display its exports.
## Usage
mix firebird.inspect fixtures/math.wasm
mix firebird.inspect fixtures/go_math.wasm --wasi
mix firebird.inspect fixtures/math.wasm --generate MyApp.Math
mix firebird.inspect fixtures/math.wasm --generate MyApp.Math --style wasm_module
## Options
- `--wasi` - Enable WASI support (required for Go/TinyGo modules)
- `--generate MODULE` - Generate an Elixir module wrapper
- `--style module|wasm_module` - Module style (default: module)
"""
use Mix.Task
@shortdoc "Inspect a WASM module's exports and types"
@switches [
wasi: :boolean,
generate: :string,
style: :string
]
@impl Mix.Task
def run(args) do
Mix.Task.run("app.start")
{opts, rest, _} = OptionParser.parse(args, switches: @switches)
case rest do
[path] ->
wasi = Keyword.get(opts, :wasi, false)
case Firebird.Inspector.inspect_file(path, wasi: wasi) do
{:ok, info} ->
if gen_name = Keyword.get(opts, :generate) do
style =
case Keyword.get(opts, :style, "module") do
"wasm_module" -> :wasm_module
_ -> :module
end
code = Firebird.Inspector.generate_module(gen_name, path, wasi: wasi, style: style)
Mix.shell().info(code)
else
print_info(path, info)
end
{:error, reason} ->
Mix.shell().error("Error: #{inspect(reason)}")
end
_ ->
Mix.shell().info(@moduledoc)
end
end
defp print_info(path, info) do
Mix.shell().info("🔍 WASM Module: #{path}")
Mix.shell().info(" Size: #{info.size_bytes} bytes")
Mix.shell().info(" Exports: #{info.export_count} total (#{info.function_count} functions)")
Mix.shell().info("")
if length(info.functions) > 0 do
Mix.shell().info(" Functions:")
for f <- info.functions do
params = Enum.join(Enum.map(f.params, &to_string/1), ", ")
results = Enum.join(Enum.map(f.results, &to_string/1), ", ")
sig = "(#{params}) -> #{results}"
Mix.shell().info(" #{f.name}#{sig}")
end
end
if length(info.memories) > 0 do
Mix.shell().info("")
Mix.shell().info(" Memories:")
for m <- info.memories do
Mix.shell().info(" #{m.name}: #{m.min_pages} pages (#{m.min_pages * 64}KB)")
end
end
if length(info.globals) > 0 do
Mix.shell().info("")
Mix.shell().info(" Globals:")
for g <- info.globals do
Mix.shell().info(" #{g.name}: #{g.type} (#{g.mutability})")
end
end
end
end