-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Chapter 1 * [Ch02] Hello World in WebAssembly * [ch02] WAT Variables > Global Variables and Type Conversion * [ch02] WAT Variables > Local Variables * [ch02] WAT Variables > Unpacking S-Expressions * [ch03] Writing an is_prime Function * [ch03] ACCESSING THE STACK FROM A FUNCTION * [ch03] Performance Implications of External Function Calls * [ch03] Function Tables * [ch05] Passing the String Length to JavaScript * [ch05] Null-Terminated Strings * [ch05] Length-Prefixed Strings * [ch05] Copying Strings > Byte-by-Byte Copy * [ch05] Copying Strings > 64-Bit Copy * [ch05] Copying Strings > Combination Copy Function * [ch05] Creating Number Strings [skip] * [ch06] Linear Memory in WebAssembly * [ch06] JavaScript Memory Object > Creating the WebAssembly Memory Object * [ch06] JavaScript Memory Object > Logging to the Console with Colors * [ch06] JavaScript Memory Object > Creating the JavaScript in store_data.js * [ch06] JavaScript Memory Object (memo) * [ch06] Collision Detection * [ch07] Setting Up a Simple Node Server * [ch07] Our First WebAssembly Web Application * [ch07] Hex and Binary Strings * [ch07] memo * [ch08] Rendering to the Canvas * [ch08] The WAT Module > Imported Values * [ch08] The WAT Module > Clearing the Canvas * [ch08] The WAT Module > Absolute Value Function * [ch08] The WAT Module > Setting a Pixel Color * [ch08] The WAT Module > Drawing the Object * [ch08] The WAT Module > Setting and Getting Object Attributes * [ch08] The WAT Module > The $main function * [ch08] Summary * [ch09] Using a Profiler > Chrome Profiler * [ch09] wasm-opt * [ch09] Strategies for Improving Performance * [ch09] Comparing the Collision Detection App with JavaScript * [ch09] Hand Optimizing WAT * [ch09] Logging Performance * [ch09] More Sophisticated Testing with benchmark.js * [ch09] Comparing WebAssembly and JavaScript with `--print-bytecode` * [ch10] Debugging from the Console * [ch10] Stack Trace * [ch11] AssemblyScript CLI * [ch11] Hello World AssemblyScript * [ch11] Object Oriented Programming in AssemblyScript * [ch03] memo * memo
- Loading branch information
Showing
126 changed files
with
8,851 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.vscode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
## 疑問 | ||
|
||
- stack と local variable や global variable が格納される領域って違うの? | ||
- ch06 | ||
- `(global $obj_base_addr (import "env" "obj_base_addr") i32)` | ||
- これで import した値がセットされるんだっけ? global 変数の基本的な構文の話 | ||
- ch07 | ||
- `instantiate` と `instantiateStreaming` の違い (Node.js は前者しか使えない) | ||
- ch08 | ||
- `i32.load` と `i32.store` ってどういう動きになるんだっけ? | ||
|
||
## 学び | ||
|
||
### Chapter 2 WebAssembly Text Basics | ||
|
||
- importObject の第一階層、`env` である必要ないんだ | ||
- Rust で書く場合はどうかな | ||
- WAT は S 式 と linear instruction set の 2 つの書き方がある。混在もできる | ||
|
||
### Chapter 3 Functions And Tables |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
const fs = require("fs"); | ||
|
||
const bytes = fs.readFileSync(__dirname + "/AddInt.wasm"); | ||
const value_1 = parseInt(process.argv[2]); | ||
const value_2 = parseInt(process.argv[3]); | ||
|
||
(async () => { | ||
const obj = await WebAssembly.instantiate(new Uint8Array(bytes)); | ||
let add_value = obj.instance.exports.AddInt(value_1, value_2); | ||
console.log(`${value_1} + ${value_2} = ${add_value}`); | ||
})(); |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
(module | ||
(func (export "AddInt") | ||
(param $value_1 i32) (param $value_2 i32) | ||
(result i32) | ||
local.get $value_1 | ||
local.get $value_2 | ||
i32.add | ||
) | ||
) |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
(module) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# Chapter 2 WebAssembly Text Basics | ||
|
||
この Chapter で紹介すること | ||
|
||
- 2 comment styles in WebAssembly | ||
- 伝統的な hello world アプリケーション | ||
- 文字列扱うのが難しいので、いきなり hello world はやらない | ||
- import object を使って JS から Wasm にデータをインポートする方法 | ||
- named and unnamed global and local variables | ||
- S 式と、wat2wasm コンパイラーが S 式をどうアンパックするか | ||
- if/else , branch tables, loops, blocks | ||
|
||
## Writing the Simplest Module | ||
|
||
すべての WAT アプリケーションはモジュールでなければならない。よって最初は module シンタックスから始まる | ||
|
||
```wat | ||
(module | ||
;; This is where the module code goes. | ||
) | ||
``` | ||
|
||
- 複数行コメントは `(; ... ;)` | ||
|
||
## Hello World in WebAssembly | ||
|
||
### Creating Our Wat Module | ||
|
||
- linear memory | ||
|
||
```wat | ||
(module | ||
(import "env" "print_string" (func $print_string( param i32 ))) | ||
(import "env" "buffer" (memory 1)) | ||
) | ||
``` | ||
|
||
- `(memory 1)` は buffer が linear memory 1 ページになることを示している | ||
- page とは | ||
- linear memory に一度に割り当てることのできる最小のメモリの塊 | ||
- Wasm では 1 ページ 64KB | ||
|
||
以下はスキップ | ||
|
||
- if/else Conditional Logic | ||
- Loops and Blocks | ||
- The loop Expression | ||
|
||
## WAT Variables | ||
|
||
### Unpacking S-Expressions | ||
|
||
```wat | ||
(i32.mul | ||
(i32.add | ||
(i32.const 3) | ||
(i32.const 2) | ||
) | ||
(i32.sub | ||
(i32.const 9) | ||
(i32.const 7) | ||
) | ||
) | ||
``` | ||
|
||
は | ||
|
||
```wat | ||
i32.const 3 | ||
i32.const 2 | ||
i32.add | ||
i32.const 9 | ||
i32.const 7 | ||
i32.sub | ||
i32.mul | ||
``` | ||
|
||
と等価 | ||
|
||
## Loops and Blocks | ||
|
||
### The `block` Statement | ||
|
||
```wat | ||
;; This code is for demonstration and not part of a larger app | ||
(block $jump_to_end | ||
br $jump_to_end | ||
;; code below the branch does not execute. br jumps to the end of the block | ||
nop | ||
) | ||
;; This is where the br statement jumps to | ||
nop | ||
``` | ||
|
||
- `br` で `block` を抜ける (the code can only jump to the end of a `block` if it’s inside that `block`) | ||
|
||
## The loop Expression |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
const fs = require("fs"); | ||
const bytes = fs.readFileSync(__dirname + "/SumSquared.wasm"); | ||
const val1 = parseInt(process.argv[2]); | ||
const val2 = parseInt(process.argv[3]); | ||
|
||
(async () => { | ||
const obj = await WebAssembly.instantiate(new Uint8Array(bytes)); | ||
let sum_sq = obj.instance.exports.SumSquared(val1, val2); | ||
console.log(`(${val1} + ${val2}) * (${val1} + ${val2}) = ${sum_sq}`); | ||
})(); |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
(module | ||
(func (export "SumSquared") | ||
(param $value_1 i32) (param $value_2 i32) | ||
(result i32) | ||
(local $sum i32) | ||
|
||
(i32.add (local.get $value_1) (local.get $value_2)) | ||
local.set $sum | ||
|
||
(i32.mul (local.get $sum) (local.get $sum)) | ||
) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
(i32.mul ;; executes 7th (last) | ||
(i32.add ;; executes 3rd | ||
(i32.const 3) ;; executes 1st | ||
(i32.const 2) ;; executes 2nd | ||
) | ||
(i32.sub ;; executes 6th | ||
(i32.const 9) ;; executes 4th | ||
(i32.const 7) ;; executes 5th | ||
) | ||
) | ||
|
||
(; | ||
(i32.add ;; executes 3rd | ||
(i32.const 3) ;; executes 1st | ||
(i32.const 2) ;; executes 2nd | ||
) | ||
は | ||
i32.const 3 | ||
i32.const 2 | ||
i32.add | ||
と等価 | ||
;) | ||
i32.const 3 ;; Stack = [3] | ||
i32.const 2 ;; Stack = [2, 3] | ||
i32.add ;; 2 & 3 popped from stack, added sum of 5 pushed onto stack [5] | ||
|
||
i32.const 9 ;; Stack = [9,5] | ||
i32.const 7 ;; Stack = [7,9,5] | ||
i32.sub ;; 7 & 9 popped off stack . 9-7=2 pushed on stack [2,5] | ||
i32.mul ;; 2,5 popped off stack, 2x5=10 is pushed on the stack [10] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
const fs = require("fs"); | ||
const bytes = fs.readFileSync(__dirname + "/globals.wasm"); | ||
let global_test = null; | ||
|
||
let importObject = { | ||
js: { | ||
log_i32: (value) => { | ||
console.log("i32: ", value); | ||
}, | ||
log_f32: (value) => { | ||
console.log("f32: ", value); | ||
}, | ||
log_f64: (value) => { | ||
console.log("f64: ", value); | ||
}, | ||
}, | ||
env: { | ||
import_i32: 5_000_000_000, | ||
import_f32: 123.0123456789, | ||
import_f64: 123.0123456789, | ||
}, | ||
}; | ||
|
||
(async () => { | ||
let obj = await WebAssembly.instantiate(new Uint8Array(bytes), importObject); | ||
({ globaltest: global_test } = obj.instance.exports); | ||
global_test(); | ||
})(); |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
(module | ||
(global $import_integer_32 (import "env" "import_i32") i32) | ||
(global $import_float_32 (import "env" "import_f32") f32) | ||
(global $import_float_64 (import "env" "import_f64") f64) | ||
|
||
(import "js" "log_i32" (func $log_i32 (param i32))) | ||
(import "js" "log_f32" (func $log_f32 (param f32))) | ||
(import "js" "log_f64" (func $log_f64 (param f64))) | ||
|
||
(func (export "globaltest") | ||
(call $log_i32 (global.get $import_integer_32)) | ||
(call $log_f32 (global.get $import_float_32)) | ||
(call $log_f64 (global.get $import_float_64)) | ||
) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
const fs = require("fs"); | ||
const bytes = fs.readFileSync(__dirname + "/helloworld.wasm"); | ||
|
||
let hello_world = null; // function will be set later | ||
let start_string_index = 100; // linear memory location of string | ||
let memory = new WebAssembly.Memory({ initial: 1 }); // linear memory | ||
|
||
let importObject = { | ||
env: { | ||
buffer: memory, | ||
start_string: start_string_index, | ||
print_string: function (str_len) { | ||
const bytes = new Uint8Array(memory.buffer, start_string_index, str_len); | ||
const log_string = new TextDecoder("utf8").decode(bytes); | ||
console.log(log_string); | ||
}, | ||
}, | ||
}; | ||
|
||
(async () => { | ||
let obj = await WebAssembly.instantiate(new Uint8Array(bytes), importObject); | ||
({ helloworld: hello_world } = obj.instance.exports); | ||
hello_world(); | ||
})(); |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
(module | ||
;; param i32: length of string | ||
(import "env" "print_string" (func $print_string(param i32) )) | ||
;; memory 1: allocate 1 page(smallest chunk of memory) of linear memory | ||
(import "env" "buffer" (memory 1)) | ||
(global $start_string (import "env" "start_string") i32) | ||
(global $string_len i32 (i32.const 12)) | ||
(data (global.get $start_string) "hello world!") | ||
(func (export "helloworld") | ||
(call $print_string (global.get $string_len)) | ||
) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Chapter 3 Functions and Tables | ||
|
||
この Chapter で学ぶこと | ||
|
||
- WebAssembly の関数について学ぶ | ||
- いつ、どのように JS や他の WebAssembly モジュールから関数を import するのか | ||
- どのように WebAssembly の関数を export するのか | ||
- table について | ||
|
||
<!-- TOC --> | ||
|
||
- [When to Call Functions from WAT](#when-to-call-functions-from-wat) | ||
- [Writing an `is_prime` Function](#writing-an-is_prime-function) | ||
- [Passing Parameters](#passing-parameters) | ||
- [Declaring an Imported Function](#declaring-an-imported-function) | ||
- [Performance Implications of External Function Calls](#performance-implications-of-external-function-calls) | ||
- [Function Tables](#function-tables) | ||
|
||
<!-- /TOC --> | ||
|
||
## When to Call Functions from WAT | ||
|
||
- `(export)` | ||
- JS から Wasm の関数の呼び出しはオーバーヘッドがあるので、小さなタスクを実行するだけの関数であれば export すべきでないよ。JS でやった方がいい | ||
- Wasm の関数は大量のデータを何回もループで処理するようなものに適している | ||
- デバッグについては Chapter 10 | ||
- パフォーマンスチューニングの過程で、元々関数として切り出してたものをインライン化することもあるかもしれない | ||
- パフォーマンス・チューニングについて詳しくは Chapter 9 で | ||
|
||
## Writing an `is_prime` Function | ||
|
||
### Passing Parameters | ||
|
||
- `local.tee`: The local.tee command is like the local.set command in that it sets the value of the variable you pass to it to the value on top of the stack | ||
|
||
## Declaring an Imported Function | ||
|
||
### Performance Implications of External Function Calls | ||
|
||
- "When you call a JavaScript function | ||
in WAT, you lose some cycles to overhead. This number isn’t extremely large, but if you execute an external JavaScript function in a loop that iterates 4,000,000 times, it can add up." | ||
- 2 つのベンチマーク比較 | ||
1. 内部で Wasm の関数を 4_000_000 回呼び出し | ||
2. 内部で JS から import した関数を 4_000_000 回呼び出し | ||
|
||
### Function Tables | ||
|
||
- "Currently, tables only support the anyfunc type (anyfunc is a generic WebAssembly function type), but in the future they might support JavaScript objects and DOM elements as well." | ||
- "Unlike import objects, JavaScript and WebAssembly can dynamically change tables at runtime." | ||
- function table 経由での関数呼び出しは indirect なコールになるためパフォーマンスコストがある | ||
- "However, you cannot add a JavaScript function to a function table from within JavaScript. There is a WebAssembly.Table function set that allows you to set functions in a table, only with a function defined in a WebAssembly module. We can work around this restriction by importing the JavaScript function into a WebAssembly module and adding it to the table there." | ||
- table_export.wat で一度 import して table にセットしてるのはこれが理由 | ||
|
||
``` | ||
js_table_test time=67 | ||
js_import_test time=52 | ||
wasm_table_test time=26 | ||
wasm_import_test time=19 | ||
``` | ||
|
||
- オチとしては | ||
- JS より Wasm のほうが速い | ||
- table 経由より直接呼び出しのほうが速い |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
;; wat2wasm will fail | ||
(module | ||
(func $inner | ||
(result i32) | ||
(local $l i32) | ||
;; 99 is on the stack in the calling function | ||
local.set $l | ||
|
||
i32.const 2 | ||
) | ||
(func (export "main") | ||
(result i32) | ||
|
||
i32.const 99 ;; push 99 onto stack - [99] | ||
call $inner ;; 99 is on the stack here | ||
) | ||
) |
Oops, something went wrong.