#!/usr/bin/env nu # Extract the complete import table and generate explicit unsupported host modules. def main [binary: path, output: path] { mkdir $output let wat = (^wasm-tools print $binary) $wat | save --force ($output | path join git.wat) let types = ($wat | lines | parse -r '^ \(type \(;(?P\d+);\) \(func(?P.*)\)\)$') let imports = ($wat | lines | parse -r '^ \(import "(?P[^"]+)" "(?P[^"]+)" \(func .*\(type (?P\d+)\).*\)\)$' | each {|i| let sig = ($types | where id == $i.id | first | get sig) {module: $i.module, name: $i.name, signature: ($sig | str trim)} }) $imports | to json | save --force ($output | path join imports.json) for module in ($imports | get module | uniq | where {|m| $m | str starts-with 'host_' }) { let functions = ($imports | where module == $module | each {|i| let result = ($i.signature | parse -r '\(result (?P\w+)\)' | get ty | first) let value = if $i.name in ['fd_mode' 'path_mode'] { '420' } else if $i.name =~ '(size|blocks)$' { '-1' } else if $i.name in ['fd_getfd' 'fd_setfd' 'set_open_mode'] { '0' } else { '52' } ' (func (export "' + $i.name + '") ' + $i.signature + ' ' + $result + '.const ' + $value + ')' } | str join (char nl)) let file = ($output | path join $'($module).wat') ('(module' + (char nl) + $functions + (char nl) + ')') | save --force $file ^wasm-tools parse $file -o ($output | path join $'($module).wasm') } }