Skip to content

Commit

Permalink
fix some wrong
Browse files Browse the repository at this point in the history
  • Loading branch information
skanehira committed Apr 27, 2024
1 parent f1b2b1f commit a414fc2
Show file tree
Hide file tree
Showing 11 changed files with 66 additions and 50 deletions.
8 changes: 4 additions & 4 deletions src/01_intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ Things you need to understand for the small Runtime include:

By the way, the Runtime to be implemented adheres to the specifications of version 1 ([specification](https://www.w3.org/TR/wasm-core-1/)). The specification may be challenging to read, but for those interested, we encourage you to continue implementing based on the explanations provided in this document.

## Target Audience {/examples/}
## Target Audience

The target audience of this document is as follows:

- Those who understand the basics of Rust and can read and write in it
- Those interested in Wasm
- Those who want to understand how Wasm is executed

## Glossary {/examples/}
## Glossary

The terms used in this document are as follows:

Expand All @@ -51,11 +51,11 @@ The terms used in this document are as follows:
Refers to the specifications of Wasm
This document adheres to the specifications of [version 1](https://www.w3.org/TR/wasm-core-1/)

## About This Document {/examples/}
## About This Document

The manuscript of this document is available in this [repository](https://github.com/skanehira/writing-a-wasm-runtime-in-rust), so if you find any confusing parts or strange explanations, please submit a pull request.

## About the Author {/examples/}
## About the Author

[skanehira](https://github.com/skanehira)

Expand Down
39 changes: 26 additions & 13 deletions src/04_wasm_binary_structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ A function signature is uniquely determined by the following combination:
For example, functions `$a` and `$b` in List 1 have differences in argument order and presence of return values, so they have different signatures, but `$a` and `$c` have the same signature.
Signatures essentially define the input and output of a function, independent of the function's content, so `$a` and `$c` will reference the same signature information.

```wat:List 1
List 1
```
(module
(func $a (param i32 i64))
(func $b (param i64 i32) (result i32 i64)
Expand All @@ -75,7 +76,8 @@ The detailed usage of signature information will be explained in the chapter on

List 2 represents the binary structure.

```:List 2
List 2
```
; section "Type" (1)
0000008: 01 ; section code
0000009: 0d ; section size
Expand Down Expand Up @@ -117,7 +119,8 @@ The remaining part of the section defines function signatures. Each function sig

In List 3, `func type 0` contains the signature information of `(func $a (param i32 i64))` and `(func $c (param i32 i64))`, while `func type 1` contains the signature information of `(func $b (param i64 i32) (result i32 i64))`.

```:List3
List3
```
; func type 0
000000b: 60 ; func ┐
000000c: 02 ; num params │ (func $a (param i32 i64))
Expand Down Expand Up @@ -149,7 +152,8 @@ The `Code Section` primarily stores the instruction information of functions.

List 4 represents the binary structure of the `Code Section`.

```:List4
List4
```
; section "Code" (10)
000001d: 0a ; section code
000001e: 0e ; section size
Expand Down Expand Up @@ -197,7 +201,8 @@ The `Function Section` holds information that links function bodies (`Code Secti

List 5 represents the binary structure.

```:List5
List5
```
; section "Function" (3)
0000017: 03 ; section code
0000018: 04 ; section size
Expand Down Expand Up @@ -225,15 +230,17 @@ Memory can be extended in page units, with 1 page being 64KiB as specified in th
Memory is formatted as `(memory $initial $max)` as shown in List 6, where `2` represents the initial memory page count, and `3` represents the maximum page count.
`max` is optional, and if not specified, there is no upper limit.

```:List6
List6
```
(module
(memory 2 3)
)
```

The binary structure is represented as shown in List 7.

```:List7
List7
```
; section "Memory" (5)
0000008: 05 ; section code
0000009: 04 ; section size
Expand All @@ -254,7 +261,8 @@ The `Data Section` is the area where data to be placed after memory allocation i

List 8 is an example defining the string `Hello, World!\n` in memory.

```:リスト8
List 8
```
(module
(memory 1)
(data 0 (i32.const 0) "Hello, World!\n")
Expand All @@ -271,7 +279,8 @@ In this example, the string `Hello, World!\n` is placed in the 0th byte of the 0

The binary structure is as shown in List 9.

```:リスト9
List 9
```
; section "Data" (11)
000000d: 0b ; section code
000000e: 14 ; section size
Expand Down Expand Up @@ -312,7 +321,8 @@ On the `Runtime` side, only exported functions can be called, so if, for example

List 10 is an example of exporting the function `$dummy` that the module itself has as `dummy`.

```:リスト10
List 10
```
(module
(func $dummy)
(export "dummy" (func $dummy))
Expand All @@ -323,7 +333,8 @@ The export format is `(export $name ($type $index))`. `$name` is the name to be

The binary structure is as shown in List 11.

```:リスト11
List 11
```
; section "Export" (7)
0000012: 07 ; section code
0000013: 09 ; section size
Expand All @@ -350,7 +361,8 @@ In this case, we are implementing WASI, and the actual implementation of WASI fu

List 12 is an example of importing a function named `add` from a module called `adder`.

```:List 12
List 12
```
(module
(import "adder" "add" (func (param i32 i32) (result i32)))
)
Expand All @@ -362,7 +374,8 @@ The import format is `(import $module $name $type)`.

The binary structure looks like List 13.

```:List 13
List 13
```
; section "Type" (1)
0000008: 01 ; section code
0000009: 07 ; section size
Expand Down
6 changes: 3 additions & 3 deletions src/05_how_decode_wasm_binary.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,11 @@ src/binary/module.rs
+
+ #[test]
+ fn decode_simplest_module() -> Result<()> {
+ // プリアンブルしか存在しないwasmバイナリを生成
+ // Generate wasm binary with only preamble present
+ let wasm = wat::parse_str("(module)")?;
+ // バイナリをデコードしてModule構造体を生成
+ // Decode binary and generate Module structure
+ let module = Module::new(&wasm)?;
+ // 生成したModule構造体が想定通りになっているかを比較
+ // Compare whether the generated Module structure is as expected
+ assert_eq!(module, Module::default());
+ Ok(())
+ }
Expand Down
20 changes: 10 additions & 10 deletions src/06_decode_function_1.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,11 @@ src/binary/module.rs
}

+fn decode_section_header(input: &[u8]) -> IResult<&[u8], (SectionCode, u32)> {
+ let (input, (code, size)) = pair(le_u8, leb128_u32)(input)?; //
+ let (input, (code, size)) = pair(le_u8, leb128_u32)(input)?; // 1
+ Ok((
+ input,
+ (
+ SectionCode::from_u8(code).expect("unexpected section code"), //
+ SectionCode::from_u8(code).expect("unexpected section code"), // 2
+ size,
+ ),
+ ))
Expand All @@ -125,7 +125,7 @@ src/binary/module.rs
use crate::binary::module::Module;
```

`pair()` returns a new parser based on two parsers. The reason for using `pair()` is that the formats of `section code` and `section size` are fixed, so by parsing each of them together, we can process them in a single function call.
1 `pair()` returns a new parser based on two parsers. The reason for using `pair()` is that the formats of `section code` and `section size` are fixed, so by parsing each of them together, we can process them in a single function call.

If `pair()` is not used, the implementation would look like this:

Expand All @@ -143,7 +143,7 @@ Note that in the `Wasm spec`, all numbers are required to be encoded with LEB128

</div>

`SectionCode::from_u8()` is a function implemented with the `num_derive::FromPrimitive` macro. It is used to convert the read 1-byte number to a `SectionCode`. Without using this, a manual solution like the following would be necessary:
2 `SectionCode::from_u8()` is a function implemented with the `num_derive::FromPrimitive` macro. It is used to convert the read 1-byte number to a `SectionCode`. Without using this, a manual solution like the following would be necessary:

```rust
impl From<u8> for SectionCode {
Expand Down Expand Up @@ -374,7 +374,7 @@ src/binary/module.rs
+fn decode_type_section(_input: &[u8]) -> IResult<&[u8], Vec<FuncType>> {
+ let func_types = vec![FuncType::default()];
+
+ // TODO: 引数と戻り値のデコード
+ // TODO: Decoding arguments and return values
+
+ Ok((&[], func_types))
+}
Expand Down Expand Up @@ -478,16 +478,16 @@ Function information consists of two parts:
In Rust, this is represented as follows:

```rust
// 関数の定義
// function definition
pub struct Function {
pub locals: Vec<FunctionLocal>,
pub code: Vec<Instruction>,
}

// ローカル変数の個数と型情報の定義
// Define the number of local variables and type information
pub struct FunctionLocal {
pub type_count: u32, // ローカル変数の個数
pub value_type: ValueType, // 変数の型情報
pub type_count: u32, // Number of local variables
pub value_type: ValueType, // Variable type information
}

// 命令の定義
Expand Down Expand Up @@ -613,7 +613,7 @@ src/binary/module.rs
}

+fn decode_code_section(_input: &[u8]) -> IResult<&[u8], Vec<Function>> {
+ // TODO: ローカル変数と命令のデコード
+ // TODO: Decoding local variables and instructions
+ let functions = vec![Function {
+ locals: vec![],
+ code: vec![Instruction::End],
Expand Down
4 changes: 2 additions & 2 deletions src/07_decode_function_2.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ src/binary/module.rs
+ input = rest;
+ }
+
+ // TODO: 命令のデコード
+ // TODO: Decoding instructions
+ body.code = vec![Instruction::End];
+
+ Ok((&[], body))
Expand Down Expand Up @@ -454,7 +454,7 @@ src/binary/module.rs
input = rest;
}

- // TODO: 命令のデコード
- // TODO: Decoding instructions
- body.code = vec![Instruction::End];
+ let mut remaining = input;
+
Expand Down
8 changes: 4 additions & 4 deletions src/08_how_function_execute.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ In Wasm Runtime, instructions are represented as an array, so the program counte
Representing this in pseudocode would look like the following.

```rust
let instructions = vec![...]; // 命令列
let mut stack: Vec<i32> = vec![]; // スタック
let mut locals: Vec<i32> = vec![]; // ローカル変数
let mut pc: usize = 0; // プログラムカウンタ
let instructions = vec![...]; // Instruction sequence
let mut stack: Vec<i32> = vec![]; // Stack
let mut locals: Vec<i32> = vec![]; // Local variables
let mut pc: usize = 0; // Program counter

loop {
if let Some(instruction) = instructions.get(pc) else {
Expand Down
12 changes: 5 additions & 7 deletions src/09_build_runtime_func_execute.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,11 +252,11 @@ use anyhow::Result;

#[derive(Default)]
pub struct Frame {
pub pc: isize, // プログラムカウンタ
pub sp: usize, // スタックポインタ
pub insts: Vec<Instruction>, // 命令列
pub arity: usize, // 戻り値の数
pub locals: Vec<Value>, // ローカル変数
pub pc: isize, // Program counter
pub sp: usize, // Stack pointer
pub insts: Vec<Instruction>, // Instructions
pub arity: usize, // Number of return values
pub locals: Vec<Value>, // Local variables
}

#[derive(Default)]
Expand Down Expand Up @@ -556,8 +556,6 @@ In `Runtime::call(...)`, the following steps are performed:

With this, a `Wasm Runtime` capable of executing addition functions has been created. Finally, write tests to ensure it functions correctly.

{/*examples*/}

src/execution/runtime.rs
```diff
diff --git a/src/execution/runtime.rs b/src/execution/runtime.rs
Expand Down
3 changes: 2 additions & 1 deletion src/11_build_runtime_external_func_call.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ As explained in the chapter on [Wasm Binary Structure](https://zenn.dev/skanehir
By the end of this section, you will be able to decode the following WAT.
Although it is similar to processing the `Export Section`, you should be able to understand it smoothly.

```wat:src/fixtures/import.wat
src/fixtures/import.wat
```wat
(module
(func $add (import "env" "add") (param i32) (result i32))
(func (export "call_add") (param i32) (result i32)
Expand Down
8 changes: 5 additions & 3 deletions src/12_build_runtime_additional_instruction.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ index c52de7b..9044e25 100644

Add tests combining with `local.set` to ensure the implementation is correct.

```wat:src/fixtures/i32_const.wat
src/fixtures/i32_const.wat
```wat
(module
(func $i32_const (result i32)
(i32.const 42)
Expand All @@ -178,7 +179,8 @@ Add tests combining with `local.set` to ensure the implementation is correct.
)
```

```wat:src/fixtures/local_set.wat
src/fixtures/local_set.wat
```wat
(module
(func $local_set (result i32)
(local $x i32)
Expand Down Expand Up @@ -286,7 +288,7 @@ index bcb8288..b5b7417 100644
}
}
}
+ _ => todo!(), // コンパイルエラーを回避するため命令処理は一旦TODO
+ _ => todo!(), // Instruction processing is set to TODO to avoid compilation errors
}
}
Ok(())
Expand Down
5 changes: 3 additions & 2 deletions src/13_build_runtime_initialize_memory.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ index 5666a39..efadc19 100644
};
use anyhow::{bail, Result};

+pub const PAGE_SIZE: u32 = 65536; // 64Ki
+pub const PAGE_SIZE: u32 = 65536; // 64KiB
+
#[derive(Clone)]
pub struct Func {
Expand Down Expand Up @@ -451,7 +451,8 @@ The instruction processing involves the following.

Finally, add tests to ensure the implementation is correct.

```wat:src/fixtures/i32_store.wat
src/fixtures/i32_store.wat
```wat
(module
(memory 1)
(func $i32_store
Expand Down
3 changes: 2 additions & 1 deletion src/14_build_runtime_wasi.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
In this chapter, we will implement the `fd_write` function of `WASI` to be able to output `Hello, World!`.
Eventually, we will be able to execute the following WAT.

```WAT:src/fixtures/hello_world.wat
src/fixtures/hello_world.wat
```wat
(module
(import "wasi_snapshot_preview1" "fd_write"
(func $fd_write (param i32 i32 i32 i32) (result i32))
Expand Down

0 comments on commit a414fc2

Please sign in to comment.