Learning WASM #2
June 4, 2021•235 words
Protocol Bufferフォーマットを使用して、dotnetとwasmの間でオブジェクトをやり取りするコードを書いてみた。
https://github.com/iwate/learn-wasm-with-dotnet/tree/main/challenge01
こんな感じのプロトファイルを用意して、
syntax = "proto3";
option csharp_namespace = "Iwate.WasmtimeChallenge";
package greet;
message Hello {
string message = 1;
}
dotent側で生成した Hello
をバイナリに書き出して、wasmのshared memoryに書き込んでから wasmモジュールのrun
を実行する。
shared memoryから Hello
をパースするとwasmで加工された情報が受け取れる。
using System;
using System.IO;
using Google.Protobuf;
using Iwate.WasmtimeChallenge;
using Wasmtime;
var bytes = new byte[32];
using (var stream = new MemoryStream(bytes))
{
new Hello { Message = "Hello, " }.WriteDelimitedTo(stream);
stream.Flush();
}
using var engine = new Engine();
using var module = Module.FromTextFile(engine, "memory.wat");
using var host = new Host(engine);
using var mem = host.DefineMemory("", "mem");
for (var i = 0; i < bytes.Length; i++)
{
mem.WriteByte(100 + i, bytes[i]);
}
using dynamic instance = host.Instantiate(module);
instance.run();
var result = mem.Span.Slice(100, 32).ToArray();
using var stream1 = new MemoryStream(result);
var hello = Hello.Parser.ParseDelimitedFrom(stream1);
Console.WriteLine(hello.Message);
Console.WriteLine(Helpers.HexDump(result));
出力結果はこんな感じ。
wasmに渡す前は Hello,
だったのが Hello,WASM!
になって返ってきてる。
Hello,WASM!
00000000 0E 0A 0C 48 65 6C 6C 6F 2C 57 41 53 4D 21 00 00 ・・・Hello,WASM!・・
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ・・・・・・・・・・・・・・・・
wasmはこんな感じ
(module
(import "" "mem" (memory 1))
(data (i32.const 0) "WASM!")
(func $run
(memory.copy (i32.add (i32.load8_u (i32.const 102)) (i32.const 102)) (i32.const 0) (i32.const 5))
(i32.store8 (i32.const 102) (i32.add (i32.load8_u (i32.const 102)) (i32.const 5)))
(i32.store8 (i32.const 100) (i32.add (i32.load8_u (i32.const 102)) (i32.const 2)))
)
(export "run" (func $run))
)
うまいこといった。shared memoryにコピーするのなんかバカっぽいなあ。最初からそっちのバイナリに書き込めればいいんだけど、Span<byte>
をStream
にする方法がよくわからない。
次は、wasmをwasファイルからじゃなくて、rustとかで生成したやつで試そう。
rust用のprotocol bufferからシリアライズ、デシリアライズしたバイナリでdotnetと通信させてみたい。