让我们在Ubuntu上尝试运行WasmEx

前提事项验证用的操作系统是Ubuntu 20.04,
已安装Elixir,
请参考https://elixir-lang.org/install.html。

让我们创建一个可以使用WasmEx的环境。请查看以下网站:
https://github.com/tessi/wasmex
查看开发部分:
a)安装Rust
b)安装Rust相关工具

e.png

准备开始

$ sudo apt install git
$ sudo apt install curl

a) 安装Rust 

执行以下操作

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

请在下面显示的屏幕上输入”1″并按下回车键。

Current installation options:


   default host triple: x86_64-unknown-linux-gnu
     default toolchain: stable (default)
               profile: default
  modify PATH variable: yes

1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
>1

你可以通过按下Ctrl + Alt + T来打开一个新的终端,以便重新启动终端。
这样做是为了使Rust工具路径生效,前提是你正在使用本地的Ubuntu系统。

b) 安装Rust相关工具

$ rustup component add rustfmt
$ rustup component add clippy
$ rustup target add wasm32-unknown-unknown
$ rustup target add wasm32-wasi

确认动作
克隆Git仓库并运行“mix test”。

git clone https://github.com/tessi/wasmex.git
cd wasmex
mix deps.get
mix compile --force
mix rustler_precompiled.download Wasmex.Native --only-local
mix test

启动iex

$ iex -S mix

请参考 README.md 中的示例进行操作验证。

Erlang/OTP 25 [erts-13.0.4] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

Compiling 7 files (.ex)

17:48:30.529 [debug] Copying NIF from cache and extracting to /home/user/wasmex/_build/dev/lib/wasmex/priv/native/libwasmex-v0.7.1-nif-2.16-x86_64-unknown-linux-gnu.so
Generated wasmex app
Interactive Elixir (1.13.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> {:ok, bytes } = File.read("test/wasm_test/target/wasm32-unknown-unknown/debug/wasmex_test.wasm")
{:ok,
 <<0, 97, 115, 109, 1, 0, 0, 0, 1, 118, 19, 96, 2, 127, 127, 0, 96, 3, 127, 127,
   127, 1, 127, 96, 2, 127, 127, 1, 127, 96, 3, 127, 127, 127, 0, 96, 1, 127, 1,
   127, 96, 0, 1, 127, 96, 1, 126, 1, ...>>}
iex(2)> {:ok, module} = Wasmex.Module.compile(bytes)
{:ok, #Wasmex.Module<#Reference<0.1531479610.3425435661.13361>>}
iex(3)> {:ok, instance } = Wasmex.start_link(%{module: module})
{:ok, #PID<0.346.0>}
iex(4)> {:ok, [42]} == Wasmex.call_function(instance, "sum", [50, -8])
true
iex(5)> 

让我们尝试用Rust创建实验性的WebAssembly。

$ cargo new hoge_wasm --lib
$ cd hoge_wasm

在Cargo.toml中添加

[package]
name = "hoge_wasm"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

+ [lib]
+ crate-type =["cdylib"]

将 src/lib.rs 文件覆盖为下面所示

#[no_mangle]
pub extern "C" fn hoge(a: i32) -> i32 {
    a * 777
}

建设

$ cargo build --target=wasm32-unknown-unknown

请确认是否已生成了 hoge_wasm.wasm 文件。

$ ls target/wasm32-unknown-unknown/debug/
build  deps  examples  hoge_wasm.d  hoge_wasm.wasm  incremental

创建Elixir项目
创建项目

$ mix new hoge
$ cd hoge

编辑mix.exs文件
添加wasmex

defmodule Hoge.MixProject do
  use Mix.Project

  def project do
    [
      app: :hoge,
      version: "0.1.0",
      elixir: "~> 1.13",
      start_permanent: Mix.env() == :prod,
      deps: deps()
    ]
  end

  # Run "mix help compile.app" to learn about applications.
  def application do
    [
      extra_applications: [:logger]
    ]
  end

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
+     {:wasmex, "~> 0.7.1"}
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
    ]
  end
end

执行mix deps.get

$ mix deps.get

编辑lib/hoge.ex

defmodule Hoge do
  @moduledoc """
  Documentation for `Hoge`.
  """

  @doc """
  Hello world.

  ## Examples

      iex> Hoge.hello()
      :world

  """
  def hello do
    :world
  end

+ def test do
+   {:ok, bytes } = File.read("hoge_wasm.wasm")
+   {:ok, module} = Wasmex.Module.compile(bytes)
+   {:ok, instance } = Wasmex.start_link(%{module: module})
+   Wasmex.call_function(instance, "hoge", [10])
+ end

end

将hoge_wasm.wasm文件复制到Elixir项目的根目录下。

$ cp ../hoge_wasm/target/wasm32-unknown-unknown/debug/hoge_wasm.wasm ./

在IEX中进行验证。

iex -S mix
iex(1)> Hoge.test()
{:ok, [7770]}

10 * 777 = 7770我们已确认其工作正

已通过运行测试的其他操作系统。・Windows 10 WSL2(Ubuntu 20.04)
・macOS Monterey 12.3 Mac mini(M1, 2020)

确认您调用的是 Rust 函数

aaa.png如果你做 2147483647 + 1,你会得到 -214483648…
RUST 引起了恐慌!

bannerAds