Trying out WASM Support

That fixes it, thank you!

Could make_string return a String to Python ?
I tried:

fun print_string(str : Void*) 
  str = str.as(String)
  str
end

then got None in Python as this:

ret = instance.exports.print_string(make_crystal_string("hello"))
print(ret) ## ret is None

You need to do something like this:

fun print_string(str : Void*) : UInt8*
  str = str.as(String)

  p str

  str.to_unsafe
end
str_ptr = instance.exports.print_string(make_crystal_string("Hello!"))
str_buf = instance.exports.memory.uint8_view(offset = str_ptr)
str_len = 0
while str_buf[str_len] != 0:
  str_len += 1

str_bytes = bytearray(str_len)
for i in range(str_len):
  str_bytes[i] = str_buf[i]

str = codecs.decode(str_bytes, 'utf-8')
print(str)
1 Like

It works now as this,thanks for the detail reply!

Hi, @lbguilherme , it seem like hello world example not work after update for 1.6.1-dev?

Following is reproduce:

 ╰─ $ \cat hello.cr 
puts "hello"
 ╰─ $ crystal version
Crystal 1.6.1-dev [809c49ecb] (2022-10-11)

LLVM: 13.0.1
Default target: x86_64-alpine-linux-gnu

 ╰─ $ crystal build hello.cr --cross-compile --target wasm32-wasi
wasm-ld hello.wasm -o hello  -lc -L/home/zw963/Crystal/bin/../lib/crystal

 ╰─ $ wasm-ld hello.wasm -o hello  -lc -L/home/zw963/Crystal/bin/../lib/crystal -L"$PWD/wasm32-wasi-libs"

 ╰─ $ wasmtime ./hello
EXITING: Attempting to raise:
Not Implemented: Crystal::System::FileDescriptor.system_info (NotImplementedError)

Thanks.

1 Like

Yes, there’s a regression in 1.6.0. It’s fixed in Fix building Wasm32 on Crystal 1.6 (Regression) by lbguilherme · Pull Request #12580 · crystal-lang/crystal · GitHub and will be released in 1.6.1 shortly.

For experimental features such as WASM support or interpreter, I’d recommend to always use master or nightly builds.There’s much movement and often bugs are already fixed since the last release, leading to worse user experience and duplicate reports.

4 Likes

This thread was very helpful, I was able to compile Wasm from Crystal. Thank you.

UPDATE: 2024-01-02 Change the script to cover Crystal 1.10.1 and LLVM 17

I am testing WASM with Crystal 1.10.1 on MacOS (M1).
It works nice.

Just in case post my testings script:

$ brew install crystal wasmer wasmtime

$ crystal --version                                         
Crystal 1.10.1 (2023-10-13)

LLVM: 17.0.6
Default target: aarch64-apple-darwin23.2.0

$ mkdir ~/bin
$ export PATH=~/bin:$PATH
$ ln -sf /opt/homebrew/opt/llvm@17/bin/wasm-ld ~/bin/wasm-ld
$ wasm-ld --version      
Homebrew LLD 17.0.6

$ mkdir -p wasm32-wasi-libs
$ curl -L https://github.com/lbguilherme/wasm-libs/releases/download/0.0.3/wasm32-wasi-libs.tar.gz | tar -C wasm32-wasi-libs -xz

$ echo 'puts "Hello WebAssembly!"' > main.cr

$ crystal build main.cr --cross-compile --target wasm32-wasi
wasm-ld main.wasm -o main  -lc -L/opt/homebrew/Cellar/crystal/1.10.1_1/bin/../../../../lib -lpcre2-8

$ wasm-ld main.wasm -o main  -L "$PWD/wasm32-wasi-libs" -lc -L/opt/homebrew/Cellar/crystal/1.10.1_1/bin/../../../../lib -lpcre2-8 -lclang_rt.builtins-wasm32

$ wasmtime main
Hello WebAssembly!

$ wasmer main
Hello WebAssembly!

References

Crystal 1.4.0 is released!

8 Likes