Hey y’all. … new to Crystal but heard about the merge of WASM/WASI support and wanted to take it for a spin. I compiled from master and attempted a hello world…
fun _start()
puts "Hello World"
end
Build works fine:
⚡ ~/src/crystal/bin/crystal build hello_world.cr --cross-compile --target wasm32-unknown-wasi
Using compiled compiler at /Users/nickwesselman/src/crystal/.build/crystal
wasm-ld hello_world.wasm -o hello_world -lc -L/opt/homebrew/lib -lpcre
But using the output wasm-ld command doesn’t work for me on macOS 12.3:
⚡ wasmtime hello_world_final.wasm
Error: failed to run main module `hello_world_final.wasm`
Caused by:
0: failed to invoke command default
1: wasm trap: out of bounds memory access
wasm backtrace:
0: 0xeb8d - []
at /Users/nickwesselman/src/crystal/src/pointer.cr:117:6
$ git clone https://github.com/lbguilherme/crystal.git && cd crystal && make && cd ..
$ crystal/.build/crystal build hello.cr --cross-compile --target wasm32-unknown-wasi
Error: Unsupported architecture for target triple: wasm32-unknown-wasi
$ crystal/.build/crystal build hello.cr
Showing last frame. Use --error-trace for full trace.
In hello.cr:1:1
1 | puts "hello world"
^
Error: can't find file 'prelude'
If you're trying to require a shard:
- Did you remember to run `shards install`?
- Did you make sure you're running the compiler in the same directory as your shard.yml?
$ crystal/.build/crystal -v
Crystal 1.3.0-dev [ee9996728] (2021-12-22)
LLVM: 12.0.0
Default target: x86_64-pc-linux-gnu
$ cat /etc/os-release |head
NAME="Ubuntu"
VERSION="18.04.6 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.6 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
wasm-ld from LLVM 10 is probably too old and the linking format changed since then. Try to install a more recent version, from LLVM 12 for example. You compiled Crystal with LLVM 12, so it should be available for your system. Alternatively you my try compiling Crystal with LLVM 10, but I’m not sure that will work.
$ cat use_simple_in_wasmer.cr
require "../src/wasmer"
class AssertionError < RuntimeError
end
def assert
raise AssertionError.new unless yield
end
# Let's define the engine, that holds the compiler.
engine = Wasmer::Engine.new
# Let's define the store, that holds the engine, that holds the compiler.
store = Wasmer::Store.new(engine)
# Above two lines are same as invoking below helper method
# store = Wasmer.default_engine.new_store
# Let's compile the module to be able to execute it!
module_ = Wasmer::Module.new(store, File.read("#{__DIR__}/simple_final.wasm"))
# Now the module is compiled, we can instantiate it.
instance = Wasmer::Instance.new(module_)
# get the exported `sum` function
# function methods returns nil if it can't find the requested function. we know its there, so let's add `not_nil!`
sum = instance.function("sum").not_nil!
# Call the exported `sum` function with Crystal standard values. The WebAssembly
# types are inferred and values are casted automatically.
result = sum.call(5, 37)
puts result # => 42
$ crystal build use_simple_in_wasmer.cr
$ ./use_simple_in_wasmer
Unhandled exception: Missing hash key: "wasi_snapshot_preview1" (KeyError)
from /usr/local/share/crystal/src/hash.cr:1031:11 in '[]'
from /home/ubuntu/wasmer-crystal/src/wasmer/import.cr:25:86 in 'into_inner'
from /home/ubuntu/wasmer-crystal/src/wasmer/instance.cr:23:17 in 'initialize'
from /home/ubuntu/wasmer-crystal/src/wasmer/instance.cr:22:5 in 'new'
from /home/ubuntu/wasmer-crystal/src/wasmer/instance.cr:32:7 in 'new'
from use_simple.cr:16:1 in '__crystal_main'
from /usr/local/share/crystal/src/crystal/main.cr:115:5 in 'main_user_code'
from /usr/local/share/crystal/src/crystal/main.cr:101:7 in 'main'
from /usr/local/share/crystal/src/crystal/main.cr:127:3 in 'main'
from /lib/x86_64-linux-gnu/libc.so.6 in '__libc_start_main'
from ./use_simple in '_start'
from ???