Control flow (制御フロー) - MDN Web Docs 用語集: ウェブ関連用語の定義

Control flow (制御フロー)
====================

*制御フロー*（制御の流れ）は、コンピューターがスクリプト内の文を実行する順序です。

条件やループなどの（非常によく出てくる）制御フローを変更する構造にコンピューターが出合わない限り、コードはファイルの最初の行から順に最後の行まで実行します。

たとえば、ウェブページのフォームからのユーザーのデータを検証するために使用されるスクリプトを想像してみてください。 スクリプトは有効なデータを送信しますが、ユーザーが必要なフィールドを空のままにしておくと、スクリプトはそれを入力するように要求します。 これを行うには、スクリプトは条件付き構造または `if...else` を使用し、フォームが完全であるかどうかによって異なるコードを実行します。
```

if (field==empty) {
    promptUser();
} else {
    submitForm();
}
```

JavaScript や PHP などの一般的なスクリプトには、条件付き、ループ、関数などの多くの制御構造が含まれています。 スクリプトの一部は、イベントが発生したときに実行するように設定することもできます。

たとえば、上記の抜粋は、ユーザーがフォームの [送信] ボタンをクリックしたときに実行される関数内にある可能性があります。 この関数にはループを含めることもできます。 ループは、フォーム内のすべてのフィールドを反復し、それぞれを順にチェックします。 `if` と `else` のセクションのコードを振り返ってみると、`promptUser` と `submitForm` という行はスクリプト内の他の関数を呼び出すこともできます。 ご覧のように、制御構造はわずか数行のコードでも複雑な処理フローを指示することがあります。

制御フローとは、スクリプトを読むときに、最初から最後まで読むだけでなく、プログラムの構造や実行順序にどのように影響するかを調べる必要があることを意味します。

より詳しく知る
-------

### 一般知識

* Wikipedia 上の 制御構造
### 技術文書

* MDN の JavaScript リファレンス - 制御フロー
### それについて学ぶ

* MDN の 文（制御フロー）


accent (強調表示) - MDN Web Docs 用語集: ウェブ関連用語の定義

accent (強調表示)
=============

**強調表示** は主に明るい色によって、配色内でよりわかりやすく背景色と前景色を引き立たせます。これらは多くのプラットフォームの視覚スタイルに存在します (しかしながら、全てではありません) 。

ウェブにおいて、強調表示は `<input>` 要素で操作の活性状態の部分に使われることがあります。例えばチェックした checkbox の背景です。

関連情報
----

### 強調表示に関連する CSS

特定の要素の CSS `accent-color` プロパティに適切な `<color>` 値を設定することで、強調表示の色を設定できます。

### 強調表示を持つHTML要素

* `<input type="checkbox">`
* `<input type="radio">`
* `<input type="range">`


First-class Function (第一級関数) - MDN Web Docs 用語集: ウェブ関連用語の定義

First-class Function (第一級関数)
============================

あるプログラミング言語が**第一級関数 (First-class functions)** を持つと言われる場合、その言語の関数がその他の変数と同様に扱われることを表します。例えば、こうした言語では、関数を他の関数への引数として渡したり、他の関数から返却したり、変数の値として代入したりすることができます。

例
-

### 関数を変数へ代入

```js
const foo = () => {
  console.log("foobar");
};
foo(); // 変数を使用して呼び出し
// foobar
```

ここでは**無名関数**を変数に代入してから、変数を使用して末尾に括弧 `()` を追加することで、その関数を呼び出しています。

**メモ:** **関数に名前があっても**、変数を使用してその関数を呼び出すことができます。名前を付けるとコードをデバッグするときに役立ちますが、*呼び出し方法に影響はありません*。

### 引数として関数を渡す

```js
function sayHello() {
  return "Hello, ";
}
function greeting(helloMessage, name) {
  console.log(helloMessage() + name);
}
// `sayHello` を `greeting` 関数の引数として渡す
greeting(sayHello, "JavaScript!");
// Hello, JavaScript!
```

ここでは `sayHello()` 関数を `greeting()` 関数の引数として渡しており、関数を**変数**として扱っていることを示しています。

**メモ:** 他の関数へ引数として渡される関数は、**コールバック関数** と呼ばれます。 *`sayHello` はコールバック関数です。*

### 関数を返す

```js
function sayHello() {
  return () => {
    console.log("Hello!");
  };
}
```

この例では、関数を他の関数から返す必要があります。 - *関数を返すことができるのは、 JavaScript では関数を値として扱っているからです。*

**メモ:** 関数を返す関数は**高階関数**と呼ばれます。

関連情報
----

* ウィキペディアの第一級関数
* MDN Web Docs 用語集
    + コールバック関数
    + 関数
    + 変数


Global scope (グローバルスコープ) - MDN Web Docs 用語集: ウェブ関連用語の定義

Global scope (グローバルスコープ)
========================

プログラミング環境において、グローバルスコープとは、他のすべてのスコープを含み、他のすべてのスコープからアクセス可能なスコープを指します。

クライアントサイド JavaScript においては、一般的にすべてのコードが実行されている Web ページがグローバルスコープとなります。

関連項目
----

### これについて学習する

* JavaScript の変数スコープ入門
* Wikipedia の スコープ


Card sorting (カードソート) - MDN Web Docs 用語集: ウェブ関連用語の定義

Card sorting (カードソート)
=====================

カードソート（カードの並べ替え）は、ウェブサイト（または他のタイプの製品）の設計に関わる人々が製品に含めるべきコンテンツ/サービス/機能を書き留めるよう請い、それからこれらの機能をカテゴリまたはグループに編成する、情報アーキテクチャで使用される単純な手法です。 これは、例えば、ウェブサイトの各ページに何をすべきかを決めるために使用することができます。 その名前は、文字通りカードに並べ替えるための項目を書いてから、カードを積み重ねて整理することによって、しばしばカードの並べ替えが行われるという事実から来ています。

より詳しく知る
-------

### 一般知識

* Wikipedia 上の Card sorting （英語）


Localization (ローカライゼーション) - MDN Web Docs 用語集: ウェブ関連用語の定義

Localization (ローカライゼーション)
=========================

**ローカライゼーション**（ローカライズ）とは、ソフトウェアのユーザーインターフェイスを特定の文化に適合させるプロセスです。

考慮するべき共通点は以下の通りです。

* 言語
* 計測単位（例えば、ヨーロッパではキロメートル、アメリカではマイル）
* 文字の方向（例えば、ヨーロッパ言語では左から右へ、アラビア語では右から左へ）
* アルファベットの大文字・小文字（例えば、英語では週に大文字を使い、スペイン語では小文字を使う）
* ことわざの対応（例えば、 "raining cats and dogs" は直訳すると意味不明になる）
* 言葉遣いの使用（例えば、日本語では敬語は常体と異なる）
* 数値形式（例えば、ドイツでは 10 000,00 がアメリカでは 10,000.00）
* 日付形式
* 通貨
* 文化的な基準
* 用紙の大きさ
* 色の心理
* 法令
* 祝日
* 個人名
詳細情報
----

### 一般知識

* ウィキペディアのローカライゼーション
* ウィキペディアの国際化と地域化


MitM (中間者攻撃) - MDN Web Docs 用語集: ウェブ関連用語の定義

MitM (中間者攻撃)
============

**Man-in-the-middle attack**（MitM、中間者攻撃）は、2 つのシステム間の通信を傍受します。たとえば、Wi-Fi ルーターが侵害される可能性があります。

これを物理的な郵便と比較します。もしあなたがお互いに手紙を書いているなら、郵便配達員はあなたが郵送するそれぞれの手紙を傍受することができます。彼らはそれを開き、それを読んで、最終的にそれを修正してから、その手紙を再び包み、あなたが手紙を送ろうとした人にそれを送ります。元の受取人はあなたに手紙を郵送し、郵便配達員は再度手紙を開き、それを読んで、最終的にそれを修正し、それを再び包み、あなたにそれを与えるでしょう。コミュニケーションチャンネルの中間に人がいることはわかりません – 郵便配達員はあなたとあなたの受取人には見えません。

物理的な郵便やオンライン通信では、MITM 攻撃は防御するのが難しいです。いくつかのヒント:

* 証明書の警告を無視しないでください。フィッシング詐欺サーバーまたは偽者サーバーに接続するかもしれません。
* 公衆 Wi-Fi ネットワーク上で HTTPS 暗号化のない機密のサイトは信頼できません。
* ログインする前にアドレスバーにある HTTPS を確認し、暗号化が行われていることを確認してください。
より詳しく知る
-------

* OWASP の記事: Man-in-the-middle attack （英語）
* Wikipedia 上の 中間者攻撃
* `Public-Key-Pins` (en-US) ヘッダー（HPKP）は、ウェブサイトへのその後のすべての接続にホワイトリスト証明書を要求するようにブラウザーに指示することで、MITM のリスクを大幅に低減できます。


Domain name (ドメイン名) - MDN Web Docs 用語集: ウェブ関連用語の定義

Domain name (ドメイン名)
===================

**ドメイン名**は インターネット 上でのウェブサイトの住所です。ドメイン名は URL で特定のウェブページが所属するサーバーを識別するために使用されています。ドメイン名はピリオド (ドット) で区切られ、トップレベルドメインで終わる階層的な名前で構成されています。

詳細情報
----

### 基礎知識

* Wikipedia 上の記事: ドメイン名
* ドメイン名を理解する


IPv4 - MDN Web Docs 用語集: ウェブ関連用語の定義

IPv4
====

IPv4 は、インターネットの基礎となる通信プロトコルの第 4 のバージョンで、広範囲に展開された最初のバージョンです。

最初に 1981 年に公式化された IPv4 は、ARPAnet の最初の開発作業にそのルーツをたどります。IPv4 は、パケット交換リンクレイヤネットワーク（イーサネット）で使用されるコネクションレスプロトコルです。IPv6 は、IPv4 のセキュリティ上の問題とそのアドレスフィールドの限界のために徐々に IPv4 を置き換えています。（バージョン番号 5 は 1979 年に実験的なインターネットストリームプロトコルに割り当てられましたが、これは決して IPv5 と呼ばれていませんでした）。

より詳しく知る
-------

### 一般知識

Wikipedia 上の IPv4


Domain (ドメイン) - MDN Web Docs 用語集: ウェブ関連用語の定義

Domain (ドメイン)
=============

ドメインとは、インターネット上の独自のリソースを識別し管理する機関のことです。 "ドメイン名"は、URLの階層の一部として使用します。たいていはブランド名のような最も記憶に残る部分です。

完全修飾ドメイン名（FQDN）には、インターネットのDNSシステムを使用してこの権限を名前で一意に検索するために必要なすべてが含まれています。

例として、"developer.mozilla.org"というドメイン名の場合：

1. "org"は、 トップレベルドメイン です。トップレベルドメインは、 IANA によってインターネット標準として登録されています。 ここでは"org"とは、最上位のドメインレジストリで定義される"organization（組織）"を意味します。
2. "mozilla"は、ドメインです。ドメインを所有したい場合は、最上位のドメインレジストリで許可されているドメイン名 レジストラのひとつとして登録する必要があります。
3. "developer"は、サブドメインです。あなたがドメインの所有者であると自分自身を定義することができます。 多くのドメイン所有者はWorld\_Wide\_Webリソースを指すようにサブドメインに "www"を選択しますが、必須ではありません（ただし、余り好ましくないです）。
詳細情報
----

* Wikipedia 上の記事： ドメイン名


Quality values - MDN Web Docs 用語集: ウェブ関連用語の定義

Quality values
==============

**品質値**、もしくは q 値と q ファクターは、値の優先順位をコンマ区切りのリストで記述するために使用されます。これはいくつかの HTTP ヘッダーと HTML で許される特別な構文です。 値の重要性はサフィックス `';q='` の直後に `0` と `1` の間の値が含まれ、最大 3 つの 10 進数で最高の優先度を示します。存在しない場合、デフォルト値は `1` です。

例
-

次の構文
```

text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
```

優先順位を示します。

| 値 | 優先度 |
| --- | --- |
| `text/html` and `application/xhtml+xml` | `1.0` |
| `application/xml` | `0.9` |
| `*/*` | `0.8` |

最初の 2 つの値に優先順位が定義されていない場合、リスト内の順序は関係ありません。それにもかかわらず、同じ品質であれば、より具体的な値よりも優先度が低くなります。
```

text/html;q=0.8,text/*;q=0.8,*/*;q=0.8
```

| 値 | 優先度 |
| --- | --- |
| `text/html` | `0.8` (but totally specified) |
| `text/*` | `0.8` (partially specified) |
| `*/*` | `0.8` (not specified) |

`Accept` のようないくつかの構文は、`text/html;level=1` のような追加の指定子を許可します。これらは価値の特異性を高めます。それらを使用することは非常にまれです。

ブラウザ固有の情報
---------

### Firefox

Firefox 18 以降、品質係数の値は小数点以下 2 桁に固定されます。 以前のバージョン (Firefox バグ 672448) では小数点以下 1 桁にしかクランプされませんでした。

詳細情報
----

* HTTP headers using q-values in their syntax: `Accept`, `Accept-Charset`, `Accept-Language`, `Accept-Encoding`, `TE` (en-US).


Grid Cell (グリッドセル) - MDN Web Docs 用語集: ウェブ関連用語の定義

Grid Cell (グリッドセル)
==================

CSS グリッドレイアウトにおける CSS グリッドの最小単位が**グリッドセル**です。 4 つの交差する グリッド線 に囲まれた領域のことで、表におけるセルと考え方はほぼ同じです。

![グリッド上の個々のセルを示す図。](/ja/docs/Glossary/Grid_Cell/1_grid_cell.png)

各アイテムのグリッド配置の方法を指定しなければ、グリッドコンテナ直下の子アイテムは自動配置アルゴリズムに従って個別のグリッドセルに一つずつ配置されます。全てのアイテムを保持できるように、行もしくは列 トラック が自動的に追加されます。

例
-

この例では 3 列のトラックグリッドを作成しています。5 つのアイテムはまず最初の行の 3 つのグリッドセルに配置され、新しい行を作って残りの 2 つのアイテムが配置されます。
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 100px;
}
```

```html
<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
</div>
```

関連情報
----

### プロパティリファレンス

* `grid-template-columns`
* `grid-template-rows`
* `grid-auto-rows`
* `grid-auto-columns`
### 参考資料

* CSS グリッドレイアウトガイド: グリッドレイアウトの基本概念
* CSS グリッドレイアウト仕様におけるグリッドセルの定義


SGML - MDN Web Docs 用語集: ウェブ関連用語の定義

SGML
====

*Standard Generalized Markup Language* (**SGML**) は、宣言型のマークアップ言語を定義するための ISO 規格です。

ウェブにおいて、HTML 4、 XHTML、 XML は広く普及した SGML ベースの言語です。HTML は、第 5 版からもはや SGML を基にしておらず、独自の構文解析規則をもつ点は注意が必要です。

関連情報
----

* Wikipedia 上の SGML
* Introduction to SGML


Flex - MDN Web Docs 用語集: ウェブ関連用語の定義

Flex
====

`flex` は CSS `display`のプロパティに新しく追加された値です。`inline-flex` と同じく、使用すると Element(要素)に Flex コンテナ が適用されます。また、その Element(要素)の子 Element(要素)それぞれには Flex アイテム が適用されます。flex アイテムが適用された Element(要素)は flex layout を構成し、CSS Flexible Box Layout Module で定義されているプロパティの全てが適用されるはずです。

`flex` プロパティは flexbox プロパティを縮めて表したプロパティです。`flex-grow` や `flex-shrink`、`flex-basis` 等があります。

`<flex>` については、CSS Grid Layout 内の flexible length にて確認できます。

関連項目
----

### プロパティリファレンス

* `align-content`
* `align-items`
* `align-self`
* `flex`
* `flex-basis`
* `flex-direction`
* `flex-flow`
* `flex-grow`
* `flex-shrink`
* `flex-wrap`
* `justify-content`
* `order`
### 参考文献

* *CSS Flexible Box Layout Module Level 1 Specification*
* CSS フレックスボックスガイド: *フレックスボックスの基本概念*
* CSS フレックスボックスガイド: *フレックスボックスと他のレイアウト方法の関係*
* CSS フレックスボックスガイド: *フレックスコンテナー内のアイテムの配置*
* CSS フレックスボックスガイド: *フレックスアイテムの順序*
* CSS フレックスボックスガイド: *主軸方向のフレックスアイテムの比率の制御*
* CSS フレックスボックスガイド: *フレックスアイテムの折り返しをマスターする*
* CSS フレックスボックスガイド: *フレックスボックスの典型的な用途*


WebDAV - MDN Web Docs 用語集: ウェブ関連用語の定義

WebDAV
======

**WebDAV** (*Web Distributed Authoring and Versioning*) は Web 開発者がリモートでウェブクライントからコンテンツを更新できる HTTP 拡張機能です。

WebDAV 単体で使われる事はまれで、CalDAV(リモートで使えるカレンダー） とCardDAV(リモートで使えるアドレス帳）の 2 つの拡張機能と共に使われるのが一般的です。

WebDAV を使用すると、クライアントから次の事ができます。

* ウェブページのメタデータ（例：著者や作成者など）の追加、削除、照会
* 任意のメディアタイプのページを関連するものにリンクする機能
* ドキュメントセットを作成し、階層構造のリストを取得
* ウェブページのコピーや移動
* 複数人での編集を回避するためのドキュメントのロック

関連項目
----

### 一般知識

* Wikipedia の WebDAV
### 技術リファレンス

* RFC 2518
* RFC 3253
* RFC 3744


Adobe Flash - MDN Web Docs 用語集: ウェブ関連用語の定義

Adobe Flash
===========

Flash は Adobe によって開発された廃れつつある技術で、表現力のあるウェブアプリ、マルチメディアコンテンツ、ストリーミングメディアを表示します。 Adobe Flash は対応しているウェブブラウザーでプラグインを用いて実行することができます。

1. 公式ウェブサイト
2. Shumway: Mozilla によるフリーな実装
3. Gnash: GNU によるフリーな実装
4. 用語集
    1. ブラウザー
5. Wikipedia の記事
    1. Adobe\_Flash


Metadata (メタデータ) - MDN Web Docs 用語集: ウェブ関連用語の定義

Metadata (メタデータ)
================

**メタデータ**とは — 最もシンプルな定義では — データを記述するデータです。例えば HTML 文書はデータですが、HTML には `<head>` 要素の中に文書を記述するメタデータ(誰が書いたのかや要約など)も含んでいます。

関連項目
----

### 一般知識

* Wikipedia の metadata
### HTML メタデータ

* MDN での `<meta>` 要素


Perceived performance (知覚的パフォーマンス) - MDN Web Docs 用語集: ウェブ関連用語の定義

Perceived performance (知覚的パフォーマンス)
==================================

**知覚的パフォーマンス**は、ウェブサイトがユーザーにとってどれだけ速く、レスポンスよく、信頼できるものと感じるかの尺度です。サイトのパフォーマンスに対する認識は、実際の読み込み時間やレスポンス時間よりもユーザー体験に大きな影響を与える可能性があります。

関連情報
----

* 知覚的パフォーマンス


CRUD - MDN Web Docs 用語集: ウェブ関連用語の定義

CRUD
====

**CRUD** (Create, Read, Update, Delete) は、格納されたデータの操作を行う方法の頭文字をとった語です。永続化されたストレージの 4 つの基本的な機能を覚えるのに役立ちます。CRUD は通常、データベースやデータストアに対する操作を示しますが、データが実際には削除されずに、状態によって削除されたと扱われる「ソフトデリート」のような、アプリケーションの上位レベルの機能にも適用できます。

関連項目
----

### 一般知識

* Wikipedia の CRUD


FTP - MDN Web Docs 用語集: ウェブ関連用語の定義

FTP
===

**FTP** (File Transfer Protocol、ファイル転送プロトコル) は、あるホストから別のホストに、インターネットを介してファイルを転送するための長年の標準的なプロトコルでした。しかし、チームやホスティングアカウントは FTP を許可せず、代わりに Git などのバージョン管理システムに依存することが増えています。古いホスティングアカウントでも使用されていますが、もはや FTP はベストプラクティスとは見なされていないと言っても過言ではありません。

もっと学ぶ
-----

### 一般知識

* FTP を介してファイルをアップロードする初心者向けのガイド
* Wikipedia の FTP 記事


Exception (例外) - MDN Web Docs 用語集: ウェブ関連用語の定義

Exception (例外)
==============

**例外**とは、通常のコード実行を強制停止する条件です。 JavaScript 構文エラー は、とてもよくある例外の情報源です。

より詳しく知る
-------

### 一般知識

* Wikipedia での 例外処理


Baseline (互換性) - MDN Web Docs 用語集: ウェブ関連用語の定義

Baseline (互換性)
==============

**Baseline** （ベースライン）は、ブラウザー間で動作するウェブプラットフォームの機能を確認します。Baseline は、サイトの訪問者に互換性の問題を引き起こす可能性が低くなった時期を示すことで、その機能を使用するタイミングを決定するのに役立ちます。

API、一連の CSS プロパティ、JavaScript 構文などの Baseline 機能は、Chrome、Edge、Firefox、Safari など、デスクトップやモバイルで広く使われている有名なブラウザーで一貫して動作します。

Baseline 機能とは、現在の安定したブラウザーで新たに利用可能になったか、あるいは長期にわたる継続的なサポートにより広く利用可能になった機能のことを言います。

バッジ
---

![チェックマークが付いた緑色のウィジェット：Baseline: Widely available. 4 つのブラウザーのロゴ、すべてチェックマーク付き。](/ja/docs/Glossary/Baseline/Compatibility/high.png)

**Widely available** である Baseline バッジが表示されている場合、その機能は各 Baseline ブラウザーで一貫してサポートされてきた歴史があると信頼できます。*Widely available* である機能とは、何年も前から複数のブラウザーでサポートされている機能です。まだ最新のブラウザーリリースに対応していないものであっても、多くのブラウザーやデバイスで動作します。

![チェックマークが付いた青色のウィジェット：Baseline 2022: Newly available. 4 つのブラウザーのロゴ、すべてチェックマーク付き。](/ja/docs/Glossary/Baseline/Compatibility/limited.png)

**Newly available** である Baseline バッジが表示されている場合、その機能は少なくとも各 Baseline ブラウザーの最新の安定版で動作しており、多くの場合それ以上の動作が確認されています。*Newly available* である機能は、最新のブラウザーでは動作しますが、古いブラウザーやデバイスでは動作しない可能性があります。*Newly available* である機能を使用する前に、サイトの利用者をよく検討してください。

![バツマークが付いた灰色のウィジェット：Limited availability. 4 つのブラウザーのロゴ、2 つにチェックマーク、2 つにバツマーク。](/ja/docs/Glossary/Baseline/Compatibility/low.png)

**Limited availability** バッジが表示されている場合、その機能は Baseline ではありません。その機能に依存する前に、あなたのサイトのユーザーを対象とした調査とテストを行うか、Baseline になるのを待ちましょう。

ブラウザーセット
--------

Baseline は、以下のブラウザーでの可用性を追跡します。

* Apple Safari (iOS)
* Apple Safari (macOS)
* Google Chrome (Android)
* Google Chrome (desktop)
* Microsoft Edge (desktop)
* Mozilla Firefox (Android)
* Mozilla Firefox (desktop)
その他の注意事項
--------

Baseline はサポートの概要であり、すべての状況をカバーしているわけではありません。もしあなたのサイトが、古いデバイスやブラウザーのリリース、または Baseline でカバーされていないブラウザーで動作する必要がある場合、あなた自身で調査やテストを行う必要があるかもしれません。Baseline があなたの状況をカバーしていない場合は、その機能を採用する前に MDN にあるブラウザーの互換性テーブルを読んだり caniuse.com を参照することを検討してください。

貢献するには
------

Baseline は W3C WebDX Community Group のコミュニティ活動であり、MDN のオープンソースブラウザー互換性データに依存しています。質問やフィードバックがある場合、または Baseline のステータスレポートがカバーする機能の更新や拡張に協力したい場合は、web-platform-dx/web-features にアクセスして参加してください。

関連情報
----

* クロスブラウザーテスト
* web-platform-dx/web-features repository
* W3C WebDX Community Group
* mdn/browser-compat-data repository


Baseline (typography) - MDN Web Docs 用語集: ウェブ関連用語の定義

Baseline (typography)
=====================

**ベースライン**とは、ヨーロッパおよび西アジアの書体で使用される用語で、フォントの文字がその上に載る概念上の線を意味します。

関連情報
----

* Baseline (Wikipedia)
* CSS ボックス配置 (MDN)


DSL (デジタル加入者線) - MDN Web Docs 用語集: ウェブ関連用語の定義

DSL (デジタル加入者線)
==============

**DSL (デジタル加入者線)** は、ブロードバンドインターネット接続の一種で、電話回線を使って有線データ通信を行うものです。

 ダウンロードとアップロードの速度は同じである必要はありません。このような場合、回線は *非対称* と言われ、 ADSL の略称が使用されます。
 ケーブル、光ファイバー、ダイヤルアップ接続とは対照的となります。

関連情報
----

* Wikipedia 上の デジタル加入者線


DSL (ドメイン固有言語) - MDN Web Docs 用語集: ウェブ関連用語の定義

DSL (ドメイン固有言語)
==============

**DSL（ドメイン固有言語）** とは、あるアプリケーションドメイン内の特定の問題に対処するために設計された、範囲が限定されたコンピューター言語の一種です。

DSL は、ドメインにまたがる様々な問題に対応するように設計された *汎用言語（GPL）* とは対照的となります。

関連情報
----

* Wikipedia 上の ドメイン固有言語
* martinfowler.com 上の DSL Guide


Signature (署名 (セキュリティ) ) - MDN Web Docs 用語集: ウェブ関連用語の定義

Signature (署名 (セキュリティ) )
========================

**署名** もしくは*デジタル署名*とは、メッセージが正当であることを示す プロトコル です。

**署名プロセス**では最初に、与えられたメッセージのハッシュから、署名する主体にリンクされたデジタル署名を、主体の秘密鍵を用いて生成します。

メッセージを受信する際は、**認証プロセス**は

* *送信者の認証* - 送信者の公開鍵を使用して署名を復号し、送信者の秘密鍵によってのみ生成可能なハッシュを復元します。さらに、
* *メッセージの完全性をチェック* - 受信したドキュメントから新たに算出されたハッシュとの比較を行います (もしドキュメントが改竄されていれば、2 つのハッシュは異なるでしょう)。

このシステムは、秘密鍵が漏洩したり、受信者が不正に間違った公開鍵を受信した場合には機能しなくなります。

関連情報
----

* Wikipedia 上の デジタル署名
* ダイジェスト, 暗号化 を参照


Signature (functions) (シグネチャ (関数)) - MDN Web Docs 用語集: ウェブ関連用語の定義

Signature (functions) (シグネチャ (関数))
==================================

**関数シグネチャ** (もしくは型シグネチャ、メソッドシグネチャ) は関数やメソッドの入力と出力を定義します。

シグネチャは以下のものを含みます:

* パラメーター とその 型
* 返り値とその型
* スローされる可能性のある例外
* オブジェクト指向 プログラムにおける利用可能性の情報(`public`、`static`、`prototype` のようなキーワード)。
さらに詳しく
------

### JavaScript におけるシグネチャ

JavaScript は型付けの弱い動的言語です。なので先行して変数の型を宣言する必要がありません。プログラムが処理される間に自動的に型が決定します。JavaScript のシグネチャはそれでもやはりメソッドの情報を付与します:

```js
MyObject.prototype.myFunction(value);
```

* メソッドは `MyObject` という オブジェクト に追加される
* メソッドは静的メソッドになるのとは対照的に `MyObject` の `prototype` に追加される (したがってインスタンスメソッド (en-US)となる)。
* 関数名は `myFunction` である。
* メソッドは未定義の `value` という一つのパラメータを受け取る。
### Java におけるシグネチャ

Javaでは、シグネチャは仮想マシンコードレベルでメソッドやクラスを区別するために使用されます。 Java コードを実行できるように変数の型をコード中で宣言する必要があります。 Java は*強い型付け*がなされ、コンパイル中にすべてのパラメーターが正しいかどうかをチェックします。

```java
public static void main(String[] args)
```

* `public` キーワードはアクセス修飾子ですべてのオブジェクトからこのメソッドを呼び出すことができることを明示します。
* `static` キーワードはこのメソッドがインスタンスメソッドとは対照的にクラスメソッドであることを明示します。
* `void` キーワードはこのメソッドの返り値が無いことを明示します。
* メソッド名は `main` です。
* メソッドは `args` という `String` 配列型のパラメータを一つ受け取ります。
`さらに学ぶ`
-------

### `一般知識`

* Wikipedia の Java internal type signatures


Property (プロパティ) (CSS) - MDN Web Docs 用語集: ウェブ関連用語の定義

Property (プロパティ) (CSS)
======================

**CSS のプロパティ**は、関連付けられた値によりブラウザーがどのように要素を表示するかを定義する特性です。

以下に CSS のルールの例を示します：

```css
/\* "div" はドキュメント中の全ての div 要素が \*/
/\* このルールによってスタイルを整えることを示すセレクタです。\*/
div {
  /\* 値 "black" を持つプロパティ "color" は、\*/
  /\* テキストの色が黒くなることを示します。\*/
  color: black;

  /\* 値 "white" を持つプロパティ "background-color" は、\*/
  /\* 要素の背景色が白くなることを示します。 \*/
  background-color: white;
}
```

詳細情報
----

### 一般知識

* Learn CSS
### 技術リファレンス

* MDN 上の CSS リファレンス
* CSS ワーキンググループの現在の成果


Property (プロパティ) (JavaScript) - MDN Web Docs 用語集: ウェブ関連用語の定義

Property (プロパティ) (JavaScript)
=============================

**JavaScript プロパティ**は、多くの場合データ構造と関連付けられた属性を記述する、オブジェクトの特性です。

プロパティは 2 種類あります。

* *インスタンスプロパティ*は、特定のオブジェクトインスタンスに固有のデータを保持します。
* *静的プロパティ*は、すべてのオブジェクトインスタンス間で共有されるデータを保持します。

プロパティは名前 ( 文字列) と値 (プリミティブ、メソッド、オブジェクト参照) のいずれかを持ちます。「プロパティが値を保持する」というのは、「プロパティがオブジェクト*参照*を保持している」という意味です。プロパティの値を変更しても、元の参照オブジェクトは変更されないため、この区別は重要です。

関連項目
----

### 一般知識

* Wikipedia 上の記事「プロパティ」
* オブジェクト志向 JavaScript 入門


Safe (安全) (HTTP メソッド) - MDN Web Docs 用語集: ウェブ関連用語の定義

Safe (安全) (HTTP メソッド)
=====================

HTTP メソッドが**安全**であるとは、その HTTP メソッドがサーバーの状態を変更しないということです。言い換えれば、読み取り専用操作につながる場合、メソッドは安全です。一般的な HTTP メソッドのうちでは `GET`, `HEAD`, `OPTIONS` が安全です。安全な HTTP メソッドはすべてべき等でもあります。しかし、すべてのべき等なメソッドが安全とは限りません。例えば、 `PUT` や `DELETE` はべき等ですが、安全ではありません。

安全なメソッドは、意味の上では読み取り専用ですが、実際にはサーバーは状態を変更することもあります。例えば、サーバーはログを記録したり、統計情報を保存したりできます。ここで重要なことは、安全なメソッドを呼び出すことによって、クライアント自体はサーバー変更を要求していないため、サーバーに不必要な負荷や責務をかけないことです。ブラウザーは、サーバーに何らかの害を及ぼすことを心配することなく安全なメソッドを呼び出すことができます。これにより、リスクなしで先読みなどの操作を実行できます。また、ウェブクローラーも、安全なメソッドの呼び出しに依拠しています。

安全なメソッドは静的ファイルのみを提供ものである必要はありません。サーバーは、生成スクリプトが安全を保証する限り、すなわち、電子商取引ウェブサイトで注文を発生させるなどの外部効果を引き起こすのではないのであれば、安全なメソッドへの返答をその場で生成することができます。

安全なメソッドを意味通りに実装するのはサーバー上のアプリケーションの責任であり、 Apache, Nginx, IIS などのウェブサーバー自体は、そのことを強制できません。特に、アプリケーションは `GET` リクエストによってサーバーの状態を変更することを許可してはいけません。

サーバーの状態を変更しない、安全なメソッドの呼び出し:
```

GET /pageX.html HTTP/1.1
```

サーバーの状態を変更する可能性のある、安全でないメソッドの呼び出し:
```

POST /pageX.html HTTP/1.1
```

べき等ではあるが安全でないメソッドの呼び出し:
```

DELETE /idX/delete HTTP/1.1
```

関連情報
----

* HTTP 仕様書における safe の定義
* 一般的な安全なメソッドの説明: `GET`, `HEAD`, `OPTIONS`
* 一般的な安全でないメソッドの説明: `PUT`, `DELETE`, `POST`


Block (ブロック) (CSS) - MDN Web Docs 用語集: ウェブ関連用語の定義

Block (ブロック) (CSS)
==================

ウェブページにおいて **ブロック** (block) は、新しい行、つまり、横書きでは前の要素の下、次の要素の上に現れる HTML の要素です（よく*ブロックレベル要素*として知られています）。例えば、 `<p>` は既定ではブロックレベル要素であり、それに対して `<a>` は*インライン要素*です。 — HTML ソース内で複数のリンクを互いに隣に置くことができ、出力時には互いに同じ行に表示されます。

`display` プロパティを使用すると、要素がインラインで表示されるかブロックで表示されるか (他の多数のオプションの中で) 変更することができます。**ブロック**は配置方法や `position` の使用にも影響します。

関連情報
----

* 視覚整形モデル


Block (ブロック) (スクリプティング) - MDN Web Docs 用語集: ウェブ関連用語の定義

Block (ブロック) (スクリプティング)
=======================

JavaScript では、ブロックは、中括弧 ("`{}`") で囲まれた関連する文の集合です。 たとえば、 `if (条件)` ブロックの後に文のブロックを置くことができます。これは、条件が真であればインタープリターがブロック内のコードを実行する必要があることを示し、条件が偽の場合はブロック全体をスキップします。

関連情報
----

* JavaScript のブロック文


Node (networking) - MDN Web Docs 用語集: ウェブ関連用語の定義

Node (networking)
=================

ネットワークでは、 **node** はネットワーク内の接続ポイントです。物理ネットワークでは通常、コンピューターやルーターなどのデバイスです。

詳細情報
----

### 基礎知識

* Wikipedia 上の記事「Node」


Node (DOM) - MDN Web Docs 用語集: ウェブ関連用語の定義

Node (DOM)
==========

DOMとしての node は、node tree 内の 1 点を指しています。node はドキュメント自身であり、Element(要素)やテキスト、コメント等の色々なものがあります。

詳細
--

### テクニカルリファレンス

* WHATWG のnode tree仕様


Media (CSS) - MDN Web Docs 用語集: ウェブ関連用語の定義

Media (CSS)
===========

CSS (Cascading Style Sheets) の文脈において、***メディア***という用語はレンダリングエンジンによって描画される文書の出力先を参照します。これはふつうは端末の画面ですが、プリンターや読み上げ装置、点字ディスプレイ、あるいはそのほかの装置の可能性もあります。

CSS には、閲覧者の端末のメディアの**種類** (画面や印刷など) やメディアの**能力** (幅、解像度、その他の値など) に応じて、文書のスタイルを微調整したり、異なるスタイルを提供したりすることができる機能がいくつかあります。

関連項目
----

### 一般知識

* メディアクエリーの使用
### 技術リファレンス

メディアクエリー

メディアクエリの中括弧内で指定された CSS スタイルを適用する条件となる特性または引数のセットを定義します。例えば、768 ピクセル以下の端末のみに特定の CSS スタイルを適用する、などです。

`@media` アット規則

メディアクエリの結果に基づいて、スタイルシートの一部を条件付きで適用します。

`Window.matchMedia()`

表示装置に対するメディアクエリをテストします。


Boolean attribute (論理属性) (HTML) - MDN Web Docs 用語集: ウェブ関連用語の定義

Boolean attribute (論理属性) (HTML)
===============================

HTML における **論理属性** (boolean attribute) とは、`true`（真） か `false`（偽）のどちらか一方の値をとる属性です。

論理属性の注目すべき特徴として、存在していれば `true` をとり、存在していなければ `false` をとる、という点があります。

こちらは HTML の論理属性 `checked` の例です。

```html
<!-- 次のチェックボックスは最初にレンダリングされた際、チェックされた状態でレンダリングされます -->
<input type="checkbox" checked />
<input type="checkbox" checked="" />
<input type="checkbox" checked="true" />
<input type="checkbox" checked="false" />
<input type="checkbox" checked="any value" />

<!-- 次のチェックボックスは最初にレンダリングされた際、チェックされていない状態でレンダリングされます -->
<input type="checkbox" />
```

関連情報
----

* 列挙型


Boolean attribute (論理属性) (ARIA) - MDN Web Docs 用語集: ウェブ関連用語の定義

Boolean attribute (論理属性) (ARIA)
===============================

ARIA における **論理属性** (boolean attribute) とは、列挙されたリストの中に `true` (真) または `false` (偽) の含む 列挙型 の属性のことです。

ARIA においては、論理型 (boolean) は文字列 `"true"` および `"false"` の形式でのみ利用されます。

関連情報
----

* 列挙型


Boolean (ブーリアン) (JavaScript) - MDN Web Docs 用語集: ウェブ関連用語の定義

Boolean (ブーリアン) (JavaScript)
============================

JavaScript において **Boolean** は プリミティブ値で `true` か `false` を表します。

`Boolean` オブジェクトはプリミティブ値の wrapper です。

関連情報
----

* Boolean
* JavaScript のデータ型とデータ構造


WebAssembly の概要 - WebAssembly

WebAssembly の概要
===============

この記事では、WebAssembly がどのように機能しているか、その目標、解決している問題、ウェブブラウザーのレンダリングエンジン内での動作などの概念について説明します。

WebAssembly とは何か
----------------

WebAssembly は最近のウェブブラウザーで動作し、新たな機能と大幅なパフォーマンス向上を提供する新しい種類のコードです。基本的に直接記述ではなく、C、C++、Rust 等の低水準の言語にとって効果的なコンパイル対象となるように設計されています。

この機能はウェブプラットフォームにとって大きな意味を持ちます。ウェブ上で動作するクライアントアプリで従来は実現できなかった、ネイティブ水準の速度で複数の言語で記述されたコードをウェブ上で動作させる方法を提供します。

それ以上に、その利点を享受するために利用者は WebAssembly のコードをどのように作成するのか知る必要さえ有りません。 WebAssembly モジュールはウェブ (あるいは Node.js) アプリにインポートすることができ、 WebAssembly の機能は JavaScript を経由して他の領域から利用できる状態になります。 JavaScript 製フレームワークでは、大幅なパフォーマンス改善と開発中の新機能をウェブ開発者が容易に利用できるようにするために WebAssembly を用いることができます。

WebAssembly の目標
---------------

WebAssembly は W3C WebAssembly Community Group 内で策定されるオープン標準として以下を目標に定めて作成されています。

* 高速で、高効率であり、ポータブルであること — WebAssembly のコードは 共通ハードウェア対応環境 を利用して異なるプラットフォーム間でネイティブ水準の速度で実行可能です。
* 可読性を持ちデバッグ可能であること — WebAssembly は低水準のアセンブリー言語ですが、人間が読めるテキスト形式があります（その仕様策定は終わっていないものの）。この形式は人の手で読み書きできて、デバッグもできます。
* 安全であること — WebAssembly は安全でサンドボックス化された実行環境上で動作するように設計されています。他のウェブ言語と同様に、ブラウザーに対して same-origin および権限ポリシーの確認を強制します。
* ウェブを破壊しないこと — WebAssembly は他のウェブ技術と協調し、後方互換性を維持するように設計されます。

**メモ:** WebAssembly はまたウェブの領域外の JavaScript 環境での利用も行います (Non-web embeddings を参照)。

WebAssembly はどのようにウェブプラットフォームに適合するのか
------------------------------------

ウェブプラットフォームは 2 つの領域からなると考えることができます。

* ウェブアプリのコードを実行する仮想マシン (VM) 、例としてアプリを動作させる JavaScript コード。
* ウェブブラウザー / デバイスの機能をコントロールして物事を実現するためにウェブアプリが呼ぶことのできる Web API のセット (DOM、 CSSOM、 WebGL、 IndexedDB、 Web Audio API 等)。

以前、仮想マシンは JavaScript だけを読み込むことができました。 JavaScript は、今日のウェブにあるほとんどの問題を解決するのに十分強力なので、これはうまく動作しています。しかし、 3D ゲーム、仮想現実、拡張現実、コンピュータービジョン、画像/動画編集、その他ネイティブなパフォーマンスを必要とする多くの領域など、より集中的な使用例で JavaScript を使用しようとすると、パフォーマンスの問題に直面します（詳しいアイデアは WebAssembly use cases をご覧ください）。

加えて巨大な JavaScript アプリケーションのダウンロード、構造の解析とコンパイルのコストは異常に高いものになりえます。モバイルや他のリソースが限られたプラットフォームではこのようなパフォーマンスのボトルネックの影響をずっと強く受けることになります。

WebAssembly は JavaScript とは異なる言語ですが、置き換えを意図しているわけではありません。その代わり、JavaScript の足りない所を補強して併用し、ウェブ開発者に双方の以下のような利益を提供することを狙いとしています。

* JavaScript は高水準の言語であり、ウェブアプリケーションを作る上で十分な柔軟性と表現力を持っています。そして多くの利点 — 動的型付け言語である、コンパイルが必須でない、強力なフレームワーク、ライブラリーやツールを提供する豊富な土壌等を持っています。
* WebAssembly はネイティブに近いパフォーマンスで動作して、C++ や Rust のような低水準のメモリー管理を行う言語がウェブ上で動作するようコンパイルされる対象となる、コンパクトなバイナリー形式を持つ低水準なアセンブリーに似た言語です (WebAssembly は将来的にガベージコレクションによるメモリー管理を行う言語をサポートする 高レベルの目標 を持っていることに注意してください)。

ブラウザーにおける WebAssembly の登場によって、私たちが先述したような仮想マシンはこれから 2 つの種類の言語をロードして実行することになります — JavaScript と WebAssembly です。

必要に応じてこの異なったコードは互いを呼び出し合うことができます — WebAssembly JavaScript API はエクスポートした WebAssembly のコードを普遍的に呼び出せる JavaScript 関数でラップし、WebAssembly のコードは通常の JavaScript 関数をインポートして同期的に呼び出せます。実際、WebAssembly のコードの基本単位はモジュールと呼ばれ、 WebAssembly のモジュールは ES モジュールと多くの対になる概念を持っています。

### WebAssembly の主要概念

ブラウザー上で WebAssembly がどのように動作するかを理解するため必要となる主要概念がいくつか存在します。これらのコンセプトはそれぞれが WebAssembly JavaScript API に一対一で対応しています。

* **モジュール** (Module): ブラウザーによって実行可能な機械語にコンパイルされた WebAssembly のバイナリーを表します。モジュールはステートレスであるため、`Blob` のように、ウィンドウやウェブワーカーと（`postMessage()` を経由して）共有することができます。モジュールは ES のモジュールのように import と export の宣言を行います。
* **メモリー** (Memory): WebAssembly の低水準なメモリーアクセス命令によって読み込みおよび書き込みが行われるバイト列を一次元の配列として保持している、リサイズ可能な ArrayBuffer です。
* **テーブル** (Table): メモリー内に（安全性および可搬性を維持するため）バイト列として保持することができなかった（関数等に対する）参照を保持しているリサイズ可能な型付き配列です。
* **インスタンス** (Instance): メモリー、テーブル、インポートされた値を含む実行時に利用されるすべての状態と対となるモジュールです。インスタンスは特定の import によって特定のグローバル環境にロードされた ES モジュールのようなものです。

JavaScript API はモジュール、メモリー、テーブルおよびインスタンスを作る機能を開発者に提供します。 WebAssembly のインスタンスが与えられれば、JavaScript はその中で export されたオブジェクトを、一般的な JavaScript で渡せる状態にされた関数同様に、同期的に呼び出すことができます。また任意の JavaScript の関数はその関数を WebAssembly のインスタンスに import することで WebAssembly のコードから同期的に呼び出されるようにすることもできます。

JavaScript は WebAssembly のコードがどのようにダウンロードされ、コンパイルされて実行されるかを完全に制御できるため、JavaScript 開発者は WebAssembly を単に効果的に高いパフォーマンスを発揮する JavaScript の機能のようにとらえることもできます。

将来的には、WebAssembly モジュールは（`<script type='module'>` を利用して）ES2015 モジュールのようにロード可能 となり、これは JavaScript が WebAssembly モジュールを ES2015 モジュールと同じくらい簡単に取得、コンパイル、インポートできるようになることを意味します。

WebAssembly をどのようにアプリで用いるか
--------------------------

ここまで私たちは WebAssembly がウェブプラットフォームに付加する基本的な原則について話しました。つまりコードのバイナリー形式とバイナリーコードを読み込み実行する API について。ここからは実際にこれらの原則をどのように活かすのかについて話します。

WebAssembly のエコシステムはまだ黎明期の状態にあります。もっと多くのツール群によってこの状況が進展するのは間違いありません。現時点では主に 4 つの入口があります。

* Emscripten を用いて C/C++ 製アプリケーションを移植する。
* アセンブリー水準で WebAssembly を記述もしくは直接生成する。
* Rust アプリケーションを書き、 WebAssembly を出力ターゲットとする。
* TypeScript によく似た AssemblyScript を用いて、 WebAssembly バイナリーに出力する

これらの選択肢について考えてみましょう。

### C/C++ からの移植

Wasm コードを作成するための多くのオプションのうちの 2 つは、オンラインの Wasm アセンブラーまたは Emscripten です。 Wasm のオンラインアセンブラーには、次のようなものがあります。

* WasmFiddle
* WasmFiddle++
* WasmExplorer

これらは、どこから始めるべきかを把握しようとしている人にとっては素晴らしいリソースですが、 Emscripten のツールと最適化には欠けています。

Emscripten ツールは C/C++ ソースコードを取得し、それを Wasm モジュール、加えてモジュールを読み出して実行するために必要な JavaScript に "glue" コードとコードの結果を表示するための HTML 文書にコンパイルおよび出力します。

![図: Emscripten は C/C++ ソースコードをコンパイルし、JavaScript グルーコードを伴う HTML 文書であるWasm モジュールに変換します。](/ja/docs/WebAssembly/Concepts/emscripten-diagram.png)

簡潔に言えば、このプロセスは以下のようになります。

1. Emscripten は最初に C/C++ を Clang + LLVM — 完成度の高いオープンソースの C/C++ コンパイラー・ツールチェインであり、OSX の XCode の一部として提供される等の利用例が有る、に注入します。
2. Emscripten が Clang + LLVM によるコンパイル結果を Wasm バイナリーに変換します。
3. それ自体だけでは WebAssembly は現時点で DOM に直接アクセスできません; JavaScript を呼び出して、整数型もしくは浮動小数点型の基本データを渡せるだけです。そのため、ウェブ API にアクセスするためには、WebAssembly は JavaScript を呼び出す必要が有り、この時点でウェブ API の呼び出しが行われます。そのため Emscripten は結果を得るための HTML と JavaScript のグルーコードを生成します。

**メモ:** 将来的に WebAssembly に直接ウェブ API を呼ばせることを許容する 計画があります。

JavaScript グルーコードは多くの人が想像するほど簡単な構造をしていません。はじめに、 Emscripten は SDL、 OpenGL、 OpenAL および POSIX の一部といった主な C/C++ ライブラリーを組み込みます。これらのライブラリー群はウェブ API の観点から組み込まれ、各々が WebAssembly を既存のウェブ API に接続するためにいくつかの JavaScript グルーコードを必要とします。

そのためグルーコードの一部は C/C++ コードによって利用されるそれぞれのライブラリーの機能を組み込みます。グルーコードはまた Wasm ファイルを取得、ロード、実行するため先述した WebAssembly JavaScript API を呼び出すロジックも含んでいます。

生成された HTML 文章は JavaScript グルーコードのファイルを読み込んで `<textarea>` に標準出力を書き出します。もしアプリケーションが OpenGL を利用している場合、その HTML はまた出力先となる `<canvas>` 要素を含みます。Emscripten の出力結果を修正して必要とするウェブアプリに変換するのは非常に簡単です。

Emscripten に関する完全なドキュメントは emscripten.org で参照でき、このツールチェインの組み込みと自身の C/C++ アプリを Wasm へとコンパイルするガイドとしては C/C++ を WebAssembly にコンパイルする が参考になります。

### WebAssembly を直接記述する

独自のコンパイラー、ツール、あるいは WebAssembly を実行時に生成する JavaScript のライブラリーを作りたいとお考えですか？

実際のアセンブリー言語同様、 WebAssembly バイナリー形式はテキスト表現を持っています — これらは一対一で対応しています。なんらかの WebAssemby テキスト表現バイナリー変換ツール を用いることでテキスト表現を直接記述してバイナリー形式に変換することができます。

この手順に関しては、 WebAssembly テキスト表現を Wasm 形式に変換する の項目を参照ください。

### WebAssembly をターゲットとした Rust の記述

Rust WebAssembly ワーキンググループの不断の仕事のおかげで、Rust コードを書いて WebAssembly にコンパイルすることも可能です。必要なツールチェーンをインストールし、サンプル Rust プログラムを WebAssembly npm パッケージにコンパイルし、ウェブアプリケーションのサンプルを使用して、 Rust から WebAssembly へのコンパイルの記事を読むことができます。

### AssemblyScript の使用

C や Rust の詳細を学ぶ必要なく、 TypeScript のような慣れ親しんだ言語の快適さの中で WebAssembly を試したいウェブ開発者にとって、 AssemblyScript は最良の選択肢になるでしょう。 AssemblyScript は TypeScript の厳密なバージョンを WebAssembly にコンパイルし、ウェブ開発者は Prettier、ESLint、VS Code IntelliSense など、使い慣れた TypeScript 互換のツールを引き続き使用することができます。ドキュメントは https://www.assemblyscript.org/ で確認することができます。

まとめ
---

本項目では WebAssembly が何であるか、どういった利便性が有るか、どのようにしてウェブに適用するかとどのように活用するかについて説明しました。

関連情報
----

* WebAssembly articles on Mozilla Hacks blog
* WebAssembly on Mozilla Research
* WebAssembly コードの読み込みと実行 — ウェブページでどのようにして自作の WebAssembly モジュールをロードするかについての理解が深まります。
* WebAssembly JavaScript API の使用 — WebAssembly JavaScript API のその他の利用法について理解が深まります。


WebAssembly コードの読み込みと実行 - WebAssembly

WebAssembly コードの読み込みと実行
=======================

JavaScript で WebAssembly を使用するには、まずコンパイル/インスタンス化の前にモジュールをメモリーにプルする必要があります。この記事では、WebAssembly バイトコードをフェッチするために使用できるさまざまなメカニズムのリファレンスと、それをコンパイル/インスタンス化して実行する方法について説明します。

どんな方法があるの?
----------

WebAssembly は `<script type='module'>` または `import` 文とまだ統合されていないため、インポートを使用してブラウザーでモジュールをフェッチする組み込みの方法はありません。

以前の `WebAssembly.compile`/`WebAssembly.instantiate` メソッドでは、生のバイトをフェッチした後 WebAssembly モジュールのバイナリーを含む `ArrayBuffer` を作成し、コンパイル/インスタンス化する必要があります。これは文字列（JavaScript ソースコード）をバイトの配列バッファー（WebAssembly ソースコード）で置き換えることを除いて、`new Function(string)` に似ています。

新しい `WebAssembly.compileStreaming`/`WebAssembly.instantiateStreaming` メソッドは、より効率的です。ネットワークからの生のバイトストリームに対して直接アクションを実行し、 `ArrayBuffer` ステップの必要性がなくなりました。

では、どのようにバイト列を配列バッファーに読み込んでコンパイルするのでしょうか? 次の節で説明します。

Fetch を使用する
-----------

Fetch はネットワークリソースを取得するための便利で新しい API です。

wasm モジュールをフェッチする最も簡単で効率的な方法は、新しい `WebAssembly.instantiateStreaming()` メソッドを使用することです。このメソッドは最初の引数として `fetch()` を呼び出すことができ、1 つのステップでフェッチ、モジュールをインスタンス化し、サーバからストリームされる生のバイトコードにアクセスします。

```js
WebAssembly.instantiateStreaming(fetch("simple.wasm"), importObject).then(
  (results) => {
    // Do something with the results!
  },
);
```

直接ストリームでは動作しない古い `WebAssembly.instantiate()` メソッドを使用した場合、フェッチされたバイトコードを `ArrayBuffer` に変換する必要があります。次のようにです。

```js
fetch("module.wasm")
  .then((response) => response.arrayBuffer())
  .then((bytes) => WebAssembly.instantiate(bytes, importObject))
  .then((results) => {
    // コンパイルされた結果 (results) で何かする!
  });
```

### 余談: instantiate() のオーバーロード

`WebAssembly.instantiate()` 関数は 2 つのオーバーロードを持ちます。 1 つ目（上の例を参照）はバイトコードを受け取ってプロミスを返します。解決されたプロミスでコンパイルされたモジュールと、それをインスタンス化したものを含むオブジェクトとして受け取ります。オブジェクトの構造は以下のようになります。

```js
{
  module: Module, // コンパイルされた WebAssembly.Module オブジェクト,
  instance: Instance, // モジュールオブジェクトから生成された WebAssembly.Instance
}
```

**メモ:** 通常はインスタンスのみを気にしますが、キャッシュする場合や、`postMessage()` を使用して別のワーカーやウィンドウと共有する場合や、インスタンスをさらに作成したい場合に備えて、モジュールを用意すると便利です。

**メモ:** 第二のオーバーロード形式は `WebAssembly.Module` オブジェクトを引数としてとり、結果としてインスタンスオブジェクトを直接含む Promise を返します。第二のオーバーロードの例を参照してください。

### WebAssembly コードを実行する

JavaScript 内で WebAssembly インスタンスが有効になったら `WebAssembly.Instance.exports` プロパティを通してエクスポートされた機能を使い始めることができます。コードは以下のようになります。

```js
WebAssembly.instantiateStreaming(fetch("myModule.wasm"), importObject).then(
  (obj) => {
    // Call an exported function:
    obj.instance.exports.exported\_func();

    // or access the buffer contents of an exported memory:
    const i32 = new Uint32Array(obj.instance.exports.memory.buffer);

    // or access the elements of an exported table:
    const table = obj.instance.exports.table;
    console.log(table.get(0)());
  },
);
```

**メモ:** WebAssembly モジュールからのエクスポートの仕組みの詳細については WebAssembly JavaScript API の使用 と WebAssembly テキストフォーマットを理解する を参照してください。

XMLHttpRequest の使用
------------------

`XMLHttpRequest` は Fetch よりやや古いですが、引き続き型付き配列を取得するために適切に使用することができます。繰り返しますが、モジュール名は `simple.wasm` とします。

1. `XMLHttpRequest()` インスタンスを生成して、`open()` メソッドでリクエストをオープン、リクエストメソッドを `GET` に設定し、フェッチするためのパスを宣言します。
2. キーは `responseType` を使用してレスポンスタイプを `'arraybuffer'` にすることです。
3. 次に `XMLHttpRequest.send()` を使用してリクエストします。
4. そのあと、ダウンロードが終了したときに `load` のイベントハンドラーから関数を実行します。この関数内で `response` プロパティから array buffer を取得し、Fetch で行ったように `WebAssembly.instantiate()` メソッドに渡します。

最終的なコードは以下のようになります。

```js
const request = new XMLHttpRequest();
request.open("GET", "simple.wasm");
request.responseType = "arraybuffer";
request.send();

request.onload = () => {
  const bytes = request.response;
  WebAssembly.instantiate(bytes, importObject).then((results) => {
    results.instance.exports.exported\_func();
  });
};
```

**メモ:** 動作例は xhr-wasm.html を参照してください。


エクスポートされた WebAssembly 関数 - WebAssembly

エクスポートされた WebAssembly 関数
========================

エクスポートされた WebAssembly 関数は WebAssembly 関数が JavaScript でどのように表現されるのか、この記事では、もう少し詳しく説明します。

エクスポートされた...とは?
---------------

エクスポートされた WebAssembly 関数は、 WebAssembly 関数を表現する JavaScript の単なるラッパーです。呼び出されると、バックグラウンドでいくつかの動作を行います。引数を Wasm で使える型に（例えば、 JavaScript の数値を Int32 に）変換し、Wasm モジュール内の関数に渡し、実行し、結果を変換して JavaScript 側に戻します。

エクスポートされた WebAssembly 関数は次の 2 つの方法で取得できます。

* 既存のテーブルの `Table.prototype.get()` を呼び出す。
* Wasm モジュールインスタンスの `Instance.exports` を通してエクスポートされた関数にアクセスする。

いずれにしても、同じ種類の内在する関数のラッパーを取得できます。 JavaScript からみると、すべての Wasm 関数は JavaScript の関数のようにみえます。しかし、これは Wasm 関数オブジェクトインスタンスによってカプセル化されており、アクセスする方法は限られています。

例
-

物事を明らかにするために例を見ていきましょう（例は GitHub の table-set.html と 動作例、Wasm の テキスト表現 を参照してください）。

```js
const otherTable = new WebAssembly.Table({ element: "anyfunc", initial: 2 });

WebAssembly.instantiateStreaming(fetch("table.wasm")).then((obj) => {
  const tbl = obj.instance.exports.tbl;
  console.log(tbl.get(0)()); // 13
  console.log(tbl.get(1)()); // 42
  otherTable.set(0, tbl.get(0));
  otherTable.set(1, tbl.get(1));
  console.log(otherTable.get(0)());
  console.log(otherTable.get(1)());
});
```

ここでは、`WebAssembly.Table` コンストラクターを使用して JavaScript からテーブル (`otherTable`) を作成し、`table.wasm` をページに読み込むために `WebAssembly.instantiateStreaming()` ユーティリティ関数を使用しています。

そのあと、モジュールからエクスポートされた関数を取得し、関数の参照を `tbl.get()` を通して取り出し、それぞれを実行した結果をコンソールに出力します。次に、 `set()` を使用して、`tbl` テーブルと同じ関数への参照を `otherTable` テーブルに含まれるようにします。

確認するために、`otherTable` から参照を取得し直し、その結果もコンソールに出力します(同じ結果が得られます)。

それらは本物の関数です
-----------

前の例で、`Table.prototype.get()` のそれぞれの返値はエクスポートされた WebAssembly 関数でした。まさに私たちが話していたことです。

これらは WebAssembly 関数のラッパーであるのに加えて本物の JavaScript 関数であることに注意してください。上の例を WebAssembly に対応しているブラウザーで読み込み、以下の行をコンソールで実行してみてください。

```js
const testFunc = otherTable.get(0);
typeof testFunc;
```

結果として関数が返されます。この関数は他の JavaScript の関数と同じように扱うことができます。例えば `call()` や `bind()` などです。 `testFunc.toString()` は興味深い結果を返します。
```

function 0() {
    [native code]
}
```

これで、よりラッパーの性質がよくわかると思います。

エクスポートされた WebAssembly 関数について他の注意事項を挙げます。

* length プロパティは Wasm 内の関数シグネチャで宣言されている引数の数です。
* name プロパティは `toString()` の結果で見えている Wasm モジュール内での関数のインデックスです。
* i64 型の値を受け取る、または返すエクスポートされた Wasm 関数を呼び出そうとすると、現在 JavaScript 上で i64 を表現する的確な方法がないためエラーが発生します。。これは将来的に変わる可能性があります。新しい int64 型が将来の標準で検討されており、 Wasm によって使用される可能性があります。


WebAssembly - WebAssembly

WebAssembly
===========

**`WebAssembly`** は JavaScript のオブジェクトで、 WebAssembly に関するすべての機能の名前空間の役割をします。

他のグローバルオブジェクトとは異なり、 `WebAssembly` はコンストラクターではありません (関数オブジェクトではありません) 。数学の定数や関数の名前空間である `Math` や 、国際化のコンストラクターやその他の言語を意識した関数ための `Intl` と同様のものです。

概要
--

`WebAssembly` オブジェクトの主な用途は次のとおりです。

* `WebAssembly.instantiate()` 関数を用いた WebAssembly コードの読み込み。
* `WebAssembly.Memory()`/`WebAssembly.Table()` コンストラクターによる新しいメモリーやテーブルインスタンスの生成。
* `WebAssembly.CompileError()`/`WebAssembly.LinkError()`/`WebAssembly.RuntimeError()` コンストラクターによる、WebAssembly で発生するエラーの処理する機能の提供。
コンストラクタープロパティ
-------------

`WebAssembly.CompileError()`

WebAssembly のデコードまたは検証中のエラーを示します。

`WebAssembly.Global()`

グローバル変数のインスタンスを表し、 JavaScript からアクセス可能で、 1 つ以上の `WebAssembly.Module` インスタンスの間でインポート/エクスポート可能です。これにより、複数のモジュールを動的リンクすることができます。

`WebAssembly.Instance()`

ステートフルで、実行可能な WebAssembly.Module のインスタンスです。

`WebAssembly.LinkError()`

(関数開始後のトラップではなく) モジュールの初期化時に発生したエラーを示します。

`WebAssembly.Memory()`

`buffer` プロパティが可変長の ArrayBuffer であり、これが WebAssembly の `Instance` からアクセス可能なメモリーのバイト列を保持しています。

`WebAssembly.Module()`

ステートレスの WebAssembly のコードであり、ブラウザーでコンパイルされ、効率的にワーカーと共有することができ、複数回インスタンス化することができます。

`WebAssembly.RuntimeError()`

WebAssembly がトラップを指定するたびに例外として発生するエラー型です。

`WebAssembly.Table()`

WebAssembly のテーブルを表す配列風の構造で、関数の参照を保持します。

静的メソッド
------

`WebAssembly.instantiate()`

WebAssembly コードをコンパイル、インスタンス化するための主要な API で、 `Module` と、その最初の `Instance` を返します。

`WebAssembly.instantiateStreaming()`

ソースのストリームから直接 WebAssembly モジュールをコンパイル、インスタンス化し、 `Module` と、その最初の `Instance` を返します。

`WebAssembly.compile()`

`WebAssembly.Module` を用いて WebAssembly バイナリコードからコンパイルします。インスタンス化は別ステップとして分離されます。

`WebAssembly.compileStreaming()`

ソースのストリームから直接 `WebAssembly.Module` にコンパイルします。インスタンス化は別ステップとして分離されます。

`WebAssembly.validate()`

WebAssembly バイナリコードの型付き配列を検証し、バイト列が有効な WebAssembly コードか (`true`) 否か (`false`) を返します。

例
-

.wasm モジュールを読み込み、コンパイルし、インスタンス化する
---------------------------------

次の例 (GitHub 上の instantiate-streaming.html のデモと、動作例も参照) は、基礎となるソースから .wasm モジュールを直接ストリーミングし、コンパイルしてインスタンス化し、 `ResultObject` で履行されるプロミスを返します。 `instantiateStreaming()` 関数は `Response` オブジェクトのプロミスを受け付けるので、 `fetch()` の呼び出し結果を直接渡すと、履行されたときにレスポンスを関数に渡すことができます。

```js
var importObject = { imports: { imported\_func: (arg) => console.log(arg) } };

WebAssembly.instantiateStreaming(fetch("simple.wasm"), importObject).then(
  (obj) => obj.instance.exports.exported\_func(),
);
```

それから `ResultObject` の instance メンバーにアクセスすると、呼び出し対象のエクスポートされた関数が入っています。

仕様書
---

| Specification |
| --- |
| WebAssembly JavaScript Interface # webassembly-namespace |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* WebAssembly 概要ページ
* WebAssembly の概念
* WebAssembly JavaScript API の使用


既存の C モジュールから WebAssembly へのコンパイル - WebAssembly

既存の C モジュールから WebAssembly へのコンパイル
=================================

WebAssembly の主な用途は、既存の C ライブラリーのエコシステムを取得し、開発者がウェブ上でそれらを利用できるようにすることです。

これらのライブラリーは、C の標準ライブラリー、オペレーティングシステム、ファイルシステムやその他のものにしばしば依存します。 Emscripten は、いくつかの制限はあるものの、これらの機能のほとんどを提供しています。

例として、 WebP のエンコーダーを wasm にコンパイルしてみましょう。WebP コーデックのソースは C 言語で書かれており、 GitHub にあり、拡張 API のドキュメントも同様に利用できます。これはとても良いスタート地点です。

```bash
git clone https://github.com/webmproject/libwebp
```

簡単な例から始めましょう。 `WebPGetEncoderVersion()` を `encode.h` から JavaScript に公開するために、 `webp.c` という C のファイルを書きます。

```cpp
#include "emscripten.h"
#include "src/webp/encode.h"

EMSCRIPTEN_KEEPALIVE
int version() {
  return WebPGetEncoderVersion();
}
```

これは libwebp のソースコードをコンパイルできるかテストするのに適したシンプルなプログラムです。この関数を呼び出すのに引数や複雑なデータ構造は必要ありません。

このプログラムをコンパイルするには、コンパイラーに `-I` フラグを使って libwebp のヘッダーファイルがどこにあるか指示し、さらに libwebp の必要な C ファイルをすべて渡す必要があります。コンパイラーに**すべての** C ファイルを渡し、コンパイラーが不要なものをすべて取り除いてくれるようにすると便利です。これはこのライブラリーではうまくいくようです。

```bash
$ emcc -O3 -s WASM=1 -s EXTRA\_EXPORTED\_RUNTIME\_METHODS='["cwrap"]' \
    -I libwebp \
    webp.c \
    libwebp/src/{dec,dsp,demux,enc,mux,utils}/*.c
```

**メモ:** この方法はすべての C プロジェクトでうまくいく訳ではありません。多くのプロジェクトでは、コンパイルの前にシステム固有のコードを生成するため、 autoconf/automake に依存しています。 Emscripten は、これらのコマンドをラップして適切な引数を注入するための `emconfigure` と `emmake` を提供しています。詳細は Emscripten のドキュメントを読んでください。

これで、新しいモジュールを読み込むために必要なのは HTML と JavaScript だけになりました。

```html
<script src="./a.out.js"></script>
<script>
 Module.onRuntimeInitialized = async () => {
 const api = {
 version: Module.cwrap("version", "number", []),
 };
 console.log(api.version());
 };
</script>
```

そして、正しいバージョン番号が出力されます。

![正しいバージョン番号を示すデベロッパーツールのコンソールのスクリーンショット](/ja/docs/WebAssembly/existing_C_to_Wasm/version.png)

**メモ:** libwebp は現在のバージョン a.b.c を 16 進数の 0xabc で返します。例えば、v0.6.1 は 0x000601 = 1537 としてエンコードされています。

### JavaScript から Wasm に画像を取得する

エンコーダーのバージョン番号を取得するのは素晴らしいことですが、画像をエンコードした方が印象的です。どうすればいいのでしょうか？

最初に答えなければならない質問は、どうやって画像を wasm に入れるのかということです。libwebp の Encoding API を見ると、RGB、RGBA、BGR、BGRA のバイト列を期待していることがわかります。幸いにも Canvas API には `CanvasRenderingContext2D.getImageData` があり、RGBA の画像データを含む `Uint8ClampedArray`が得られます。

```js
async function loadImage(src) {
  // Load image
  const imgBlob = await fetch(src).then((resp) => resp.blob());
  const img = await createImageBitmap(imgBlob);
  // Make canvas same size as image
  const canvas = document.createElement("canvas");
  canvas.width = img.width;
  canvas.height = img.height;
  // Draw image onto canvas
  const ctx = canvas.getContext("2d");
  ctx.drawImage(img, 0, 0);
  return ctx.getImageData(0, 0, img.width, img.height);
}
```

これで、残った「唯一の」問題は、 JavaScript から wasm にデータをコピーすることだけです。そのためには、追加で 2 つの関数を公開する必要があります。 1 つは、 wasm 内で画像のためのメモリーを確保する関数、もう 1 つは、それを再び解放する関数です。

```cpp
#include <stdlib.h> // required for malloc definition

EMSCRIPTEN_KEEPALIVE
uint8\_t\* create\_buffer(int width, int height) {
  return malloc(width \* height \* 4 \* sizeof(uint8\_t));
}

EMSCRIPTEN_KEEPALIVE
void destroy\_buffer(uint8\_t\* p) {
  free(p);
}
```

`create_buffer()` 関数は RGBA 画像用です。したがって、ピクセル当たり 4 バイトのバッファーを確保します。 malloc() が返すポインターは、そのバッファーの最初のメモリーセルのアドレスです。ポインターが JavaScript に返されると、それは単なる数値として扱われます。この関数を cwrap を使って JavaScript に公開した後、その数値を使ってバッファーの開始点を見つけ、画像データをコピーすることができます。

```js
const api = {
  version: Module.cwrap("version", "number", []),
  create\_buffer: Module.cwrap("create\_buffer", "number", ["number", "number"]),
  destroy\_buffer: Module.cwrap("destroy\_buffer", "", ["number"]),
  encode: Module.cwrap("encode", "", ["number", "number", "number", "number"]),
  free\_result: Module.cwrap("free\_result", "", ["number"]),
  get\_result\_pointer: Module.cwrap("get\_result\_pointer", "number", []),
  get\_result\_size: Module.cwrap("get\_result\_size", "number", []),
};

const image = await loadImage("./image.jpg");
const p = api.create\_buffer(image.width, image.height);
Module.HEAP8.set(image.data, p);
// ... call encoder ...
api.destroy\_buffer(p);
```

### 画像をエンコードする

wasm で画像を使えるようになりました。いよいよ WebP エンコーダーを呼び出して動かす時が来ました。WebP のドキュメントを見ると、`WebPEncodeRGBA`がふさわしいようです。この関数は、入力画像へのポインターと画像の寸法、そして 0 から 100 の間の品質オプションを受け取ります。また、出力バッファーを確保するので、 WebP 画像の処理が終わったら `WebPFree()` を使って解放する必要があります。

エンコード処理の結果は、出力バッファーとその長さになります。C 言語の関数は（メモリーを動的に確保しない限り）返値の型として配列を使うことができないため、この例では静的なグローバル配列を使用しています。これはクリーンな C 言語とは言えないかもしれません。実際、これは wasm ポインターが 32 ビット幅であることに依存しています。しかし、これは話を単純にするための公正な手段です。

```cpp
int result[2];
EMSCRIPTEN_KEEPALIVE
void encode(uint8\_t\* img_in, int width, int height, float quality) {
  uint8\_t\* img_out;
  size_t size;

  size = WebPEncodeRGBA(img_in, width, height, width \* 4, quality, &img_out);

  result[0] = (int)img_out;
  result[1] = size;
}

EMSCRIPTEN_KEEPALIVE
void free\_result(uint8\_t\* result) {
  WebPFree(result);
}

EMSCRIPTEN_KEEPALIVE
int get\_result\_pointer() {
  return result[0];
}

EMSCRIPTEN_KEEPALIVE
int get\_result\_size() {
  return result[1];
}
```

これで、エンコーディング関数を呼び出し、ポインターと画像サイズを取得し、それをあなたの JavaScript バッファーに格納し、プロセス中で確保されたすべての wasm バッファーを解放することができるようになりました。

```js
api.encode(p, image.width, image.height, 100);
const resultPointer = api.get\_result\_pointer();
const resultSize = api.get\_result\_size();
const resultView = new Uint8Array(
  Module.HEAP8.buffer,
  resultPointer,
  resultSize,
);
const result = new Uint8Array(resultView);
api.free\_result(resultPointer);
```

**メモ:** `new Uint8Array(someBuffer)` は同じメモリーチャンク上に新しいビューを作成し、 `new Uint8Array(someTypedArray)` はデータをコピーします。

画像のサイズによっては、 wasm が入力画像と出力画像を格納するためのメモリーを十分に大きくすることができないというエラーが発生する可能性があります。

![Screenshot of the DevTools console showing an error.](/ja/docs/WebAssembly/existing_C_to_Wasm/error.png)

幸いにも、この問題の解決策はエラーメッセージの中にあります。コンパイルコマンドに `-s ALLOW_MEMORY_GROWTH=1` を追加するだけです。

これで完了です。 WebP エンコーダーをコンパイルし、 JPEG 画像を WebP にトランスコードしました。うまくいったことを証明するために、結果のバッファーを blob にして`<img>`要素で使用してください。

```js
const blob = new Blob([result], { type: "image/webp" });
const blobURL = URL.createObjectURL(blob);
const img = document.createElement("img");
img.src = blobURL;
document.body.appendChild(img);
```

見よ、新しい WebP 画像の栄光を。

デモ | 原著

![ デベロッパーツールのネットワークパネルと生成された画像。](/ja/docs/WebAssembly/existing_C_to_Wasm/result.jpg)


C/C++ から WebAssembly へのコンパイル - WebAssembly

C/C++ から WebAssembly へのコンパイル
============================

C / C ++のような言語でコードを書いたら、Emscripten のようなツールを使って WebAssembly にコンパイルすることができます。 どのように動作するかを見てみましょう。

Emscripten の環境設定
----------------

まず、必要な開発環境をセットアップしましょう。

### 準備

Emscripten SDK を取得します。以下の指示に従ってください。https://emscripten.org/docs/getting\_started/downloads.html

サンプルコードをコンパイルする
---------------

環境を設定した後は、C のサンプルコードを Wasm にコンパイルする方法を見てみましょう。 Emscripten でコンパイルするときにはいくつかのオプションがありますが、この記事でカバーする主な 2 つのシナリオは次のとおりです。

* Wasm にコンパイルし、コードを実行するための HTML とウェブ環境上で Wasm を実行するための全ての JavaScript グルーコードを生成する。
* Wasm にコンパイルと JavaScript の生成だけ行う。

2 つについて見てみましょう。

### HTML と JavaScript を生成する

最も簡単なケースを見てみましょう。コードを WebAssembly としてブラウザーで実行するための全てを Emscripten で生成するようにします。

1. まずはコンパイルするためのサンプルコードを用意します。以下の C のサンプルコードをコピーして `hello.c` としてローカルドライブの新しいディレクトリーに保存してください。

```cpp
#include <stdio.h>

int main() {
    printf("Hello World\n");
    return 0;
}
```

2. Emscripten コンパイラー環境を導入したターミナルウィンドウを使用して、`hello.c` ファイルと同じディレクトリーに移動し、次のコマンドを実行します。

```bash
emcc hello.c -o hello.html
```

このコマンドで渡されたオプションは次のとおりです。

* `-o hello.html` — コードを実行するための HTML ページを指定します。Wasm モジュールとそれをウェブ環境で使用できるようにコンパイル、インスタンス化するための JavaScript 「グルー」コードも出力に含まれます。

この時点でソースディレクトリーに以下のファイルが出力されているはずです。

* バイナリーの Wasm モジュールコード (`hello.wasm`)
* ネイティブの C の関数と JavaScript/Wasm の間で変換を行う JavaScript ファイル (`hello.js`)
* Wasm コードを読み込み、コンパイルし、インスタンス化し、ブラウザーに出力するための HTML ファイル (`hello.html`)
### サンプルコードの実行

WebAssembly に対応しているブラウザーで `hello.html` を読み込むだけです。既定で有効なのは Firefox 52, Chrome 57, Opera 44 以降です。

**メモ:** 生成された HTML ファイル (`hello.html`) をローカルのハードドライブから直接開こうとすると（例: `file://your_path/hello.html`）、 \_`both async and sync fetching of the wasm failed` という複数行のエラーメッセージが表示されます。 HTML ファイルを HTTP サーバー (`http://`) で実行する必要があります。詳しくは ローカルのテストサーバーを設定するには を参照してください。

 全てが計画通りに機能していれば、ウェブページ上の Emscripten コンソールに "Hello world" の出力が表示されるはずです。おめでとうございます、ようやく C を WebAssembly にコンパイルしてブラウザーで実行することができました。

 ![image](/ja/docs/WebAssembly/C_to_Wasm/helloworld.png)

### カスタム HTML テンプレートを使う

場合によっては、カスタム HTML テンプレートを使用することもできます。 どうやってできるかを見てみましょう。

1. まず、次の C のコードを `hello2.c` として新しいディレクトリーに保存します。

```cpp
#include <stdio.h>

int main() {
    printf("Hello World\n");
    return 0;
}
```

2. `shell_minimal.html` を emsdk リポジトリーから探します。先ほど作成した新しいディレクトリーに `html_template` というサブディレクトリーを作って、そこにコピーします。
3. 新しいディレクトリーに移動して（Emscripten コンパイラー環境があるターミナルウィンドウで）、次のコマンドを実行します。

```bash
emcc -o hello2.html hello2.c -O3 --shell-file html_template/shell_minimal.html
```

今回渡したオプションは少しだけ異なります。
    * `-o hello2.html` と指定したことで、今回コンパイラーは JavaScript グルーコードと `.html` を出力します。
    * `-O3` はコードを最適化するために使用されます。 Emcc には他の C コンパイラと同様に、最適化レベルとして `-O0`（最適化しない）、`-O1`、`-O2`、`-Os`、`-Oz`、`-Og`、`-O3` があります。 `-O3` は、リリースビルドに適した設定です。
    * さらに `--shell-file html_template/shell_minimal.html` と指定しました — これは例を実行する HTML を生成するための、HTML テンプレートパスです。
4. この例を実行してみましょう。上記のコマンドで hello2.html が生成されます。これは生成された Wasm コードに対してロード、実行などを行うグルーコードを含むテンプレートと同じ内容を持ちます。ブラウザーを開いて最後の例と同じ出力であることを確認してください。

**メモ:** HTML ファイルの代わりに .js ファイルを `-o` フラグで指定することで、完全な HTML ではなく、 JavaScript の「グルー」ファイル*だけ*を出力するように指定することができます。例えば `emcc -o hello2.js hello2.c -O3` とします。そうすると、完全にスクラッチでカスタム HTML を作成することができますが、これは高度なアプローチであり、通常は提供されている HTML テンプレートを使用する方が簡単です。

Emscripten は、メモリー割り当て、メモリーリーク、その他多くの問題を処理するために、多種多様な JavaScript の「グルー」コードを必要とします。

### C で定義されたカスタム関数を呼び出す

C で定義された関数があって、それを JavaScript から呼び出したい場合、 Emscripten の `ccall()` 関数と `EMSCRIPTEN_KEEPALIVE` 宣言（対象の関数をエクスポートする関数リストに加えるものです（Why do functions in my C/C++ source code vanish when I compile to JavaScript, and/or I get No functions to process? を参照））を使用します。これがどのように動作するか見てみましょう。

1. はじめに、次のコードを `hello3.c` として新しいディレクトリーに保存します。

```cpp
#include <stdio.h>
#include <emscripten/emscripten.h>

int main() {
    printf("Hello World\n");
    return 0;
}

#ifdef \_\_cplusplus
#define EXTERN extern "C"
#else
#define EXTERN
#endif

EXTERN EMSCRIPTEN_KEEPALIVE void myFunction(int argc, char \*\* argv) {
    printf("MyFunction Called\n");
}
```

既定では、 Emscripten が生成したコードは常に `main()` を呼び出し、他のデッドコードは削除されます。関数名の前に `EMSCRIPTEN_KEEPALIVE` を置くことによって、これが起こらなくなります。また、`EMSCRIPTEN_KEEPALIVE` を使用するために `emscripten.h` をインポートする必要があります。

**メモ:** `#ifdef` ブロックを加えたことによって、C++ のコードからこの例をインクルードしようとしても動作するでしょう。 C と C++ の間でのマングリング規則によって、他の場合では壊れることもありますが、ここでは C++ を使用している場合に、外部の C の関数として扱うように設定しています。
2. 便宜上、この新しいディレクトリーに `html_template/shell_minimal.html` （もちろん、このファイルはあなたの実際の開発環境に置きます）を加えます。
3. さて、再びコンパイル手順を実行しましょう。最新のディレクトリーの中（そして、Emscripten コンパイラー環境の入っているターミナルウィンドウの中）で、次のようにして C のコードをコンパイルします。`NO_EXIT_RUNTIME` オプションを付与してコンパイルする必要があることに注意してください。そうしないと、`main()` 関数が存在した場合、ランタイムがシャットダウンされ、コンパイルされたコードが正しく呼び出されません。これは適切に C をエミュレーションするのに、例えば `atexit()` 関数を呼び出せるようにするために必要です。

```bash
emcc -o hello3.html hello3.c --shell-file html_template/shell_minimal.html -s NO\_EXIT\_RUNTIME=1 -s "EXPORTED\_RUNTIME\_METHODS=['ccall']"
```

4. 例をブラウザーで読み込んだら、前と同じものが見られるでしょう。
5. JavaScript から新しい `myFunction()` 関数を呼び出す必要があります。まずは、 hello3.html ファイルをテキストエディターで開いてください。
6. 以下のような `<button>` を最初の `<script type='text/javascript'>` タグの上に加えましょう。

```html
<button id="mybutton">Run myFunction</button>
```

7. そして、 `<script>` 要素内の最後に次のコードを追加します。

```js
document.getElementById("mybutton").addEventListener("click", () => {
  alert("check console");
  const result = Module.ccall(
    "myFunction", // name of C function
    null, // return type
    null, // argument types
    null, // arguments
  );
});
```

これはエクスポートされた関数をどのようにして `ccall()` を使用して呼び出すかを示しています。

関連情報
----

* emscripten.org — Emscripten とそれの多種多様なオプションについての詳細を確認してください。
* Calling compiled C functions from JavaScript using ccall/cwrap
* Why do functions in my C/C++ source code vanish when I compile to JavaScript, and/or I get No functions to process?
* WebAssembly on Mozilla Research
* 既存の C モジュールから WebAssembly へのコンパイル


WebAssembly テキスト形式から Wasm への変換 - WebAssembly

WebAssembly テキスト形式から Wasm への変換
==============================

WebAssembly には S 式ベースのテキスト表現があります。これはテキストエディター、ブラウザーの開発者ツールなどで見せるために設計された中間表現です。この記事では、これがどのように動作するか、テキスト形式のファイルを Wasm 形式に変換するのに利用可能なツールの使用方法について少し説明します。

**メモ:** テキスト形式のファイルは、通常 `.wat` という拡張子で保存されます。過去には `.wast` という拡張子も使用されていましたが、現在は WebAssembly テストスイートで使用されるスクリプト言語のために使用されています。

初めてのテキスト形式
----------

簡単な例を見てみましょう。次のプログラムは `imported_func` という名前の関数を `imports` というモジュールからインポートし、 `exported_func` という名前の関数をエクスポートしています。

```wasm
(module
  (func $i (import "imports" "imported\_func") (param i32))
  (func (export "exported\_func")
    i32.const 42
    call $i
  )
)
```

WebAssembly 関数 `exported_func` は私たちの環境（WebAssembly モジュールを使用しているウェブアプリなど）で使用するためにエクスポートされます。この関数が呼び出されたとき、インポートされた JavaScript 関数 `imported_func` の引数として値 (42) を渡して実行されます。

テキストの .wat ファイルからバイナリーの .wasm ファイルへの変換
--------------------------------------

上の `.wat` テキスト表現の例を `.wasm` アセンブリー形式に変換してみましょう。

1. はじめに、上のコードをテキストファイルにコピーして `simple.wat` という名前のファイルを作成してください。
2. このテキスト表現をブラウザーが実際に読み込んで利用可能なアセンブリー言語にアセンブルする必要があります。このために wabt ツールを使用することができます。これは WebAssembly のテキスト表現から Wasm 変換する、または逆に変換するコンパイラー（加えてもう少し別のツール）が含まれます。https://github.com/webassembly/wabt に行って、そのページの説明に従ってツールの設定をしてください。
3. ツールをビルドしたら、 `/wabt/out/clang/Debug` ディレクトリーをシステムの `PATH` に追加します。
4. 次に、wat2wasm プログラムを実行します。入力ファイルパス、続いて `-o` 引数と、その後に出力ファイルパスを指定します。

```bash
wat2wasm simple.wat -o simple.wasm
```

これで `simple.wasm` という名前のファイルに Wasm が出力されます。これには `.wasm` アセンブリーのコードが含まれます。

**メモ:** wasm2wat を使用して wasm から テキスト表現に戻すことができます。例: `wasm2wat simple.wasm -o text.wat`.

アセンブリーの出力を見る
------------

出力されたファイルはアセンブリーベースなので通常のテキストエディターで表示することができません。ただし、wat2wasm ツールの `-v` オプションを使用して見ることができます。以下を試してみてください。

```bash
wat2wasm simple.wat -v
```

ターミナルには次のように出力されるでしょう。

![複数のバイナリー文字列の横に文字列の説明を表示しています。例：0000008: 01 ; セクションコード ](/ja/docs/WebAssembly/Text_format_to_Wasm/assembly-output.png)

関連情報
----

* WebAssembly テキスト形式を理解する — テキスト形式のシンタックスの詳細説明。
* C/C++ から WebAssembly にコンパイルする — Binaryen/Emscripten のようなツールはソースコードを Wasm にコンパイルし、 JavaScript のコンテキストでモジュールを実行するために必要な API コードを作成します。それらの使用方法の詳細はこちらから探してください。
* WebAssembly JavaScript API の使用 — WebAssembly API コードがどのように機能するかについて詳しく知りたい場合はこちらをお読みください。
* Text format — WebAssembly GitHub リポジトリーのテキスト形式の詳細説明。
* wast-loader — これをすべて処理してくれる webpack のローダーです。


WebAssembly テキスト形式の理解 - WebAssembly

WebAssembly テキスト形式の理解
=====================

WebAssembly を人間が読んだり編集したりできるようにするため、 Wasm バイナリー形式にはテキスト表現が存在します。これはテキストエディター、ブラウザーの開発者ツールなどで見せるために設計された中間表現です。この記事では、テキスト形式のしくみ、生の構文、および元のバイトコードの表現との関係 (と JavaScript で Wasm を表現したラッパーオブジェクト) について説明します。

**メモ:** この記事は、あなたがウェブ開発者で Wasm モジュールをページに読み込んでコード内で使用するだけなら過剰なものかもしれません (WebAssembly JavaScript API の使用を参照)。しかし、例えば、パフォーマンスを最適化するために Wasm モジュールを書きたいときや、あなた自身で WebAssembly コンパイラーを作るときには役に立ちます。

S 式
---

バイナリー、テキスト形式どちらでも、 WebAssembly の基本的なコードの単位はモジュールです。テキスト形式ではモジュールは 1 つの大きな S 式として表現されます。 S 式はツリー構造を表現するための非常に古くてシンプルなテキスト形式で、モジュールをその構造とそのコードを記述するノードツリーとして考えることができます。しかし、プログラミング言語の AST (抽象構文木) とは異なり、　WebAssembly のツリーはかなり平坦で、ほとんどは命令の列で構成されています。

はじめに、 S 式がどういうものか見てみましょう。ツリー内の各ノードは `( ... )` のように 1 組の括弧内に入れられます。 括弧内の最初のラベルは、それがどのノードタイプかを示し、スペースで区切られた属性、または子ノードのリストが続きます。次のコードは WebAssembly の S 式を意味します。

```wasm
(module (memory 1) (func))
```

ルートノード "module" と 2 つの子ノード、 "1" を属性に持つ "memory" ノード、"func" ノードを表します。これらのノードが実際にどういう意味なのかを見ていきましょう。

### 最もシンプルなモジュール

最もシンプルで短い実行可能な Wasm モジュールから始めてみましょう。

```wasm
(module)
```

このモジュールは完全に空ですが、モジュールとしては有効です。

いま、このモジュールをバイナリーに変換すると (WebAssembly テキスト形式から Wasm に変換する を参照) 、 バイナリー形式 で記述された 8 バイトのモジュールヘッダーだけになります。

```wasm
0000000: 0061 736d              ; WASM_BINARY_MAGIC
0000004: 0100 0000              ; WASM_BINARY_VERSION
```

### モジュールに機能を追加する

はい、これは全然面白くないですね。モジュールに実行可能なコードを追加していきましょう。

すべての WebAssembly モジュール内のコードは次の疑似コード構造を持つ関数にグループ化されます:

```wasm
( func <signature> <locals> <body> )
```

* **signature** は関数が何を受け取る（引数）かと何を返す (返値) かを宣言します。
* **locals** は JavaScript でいうと変数のようなものですが、明示的な型が宣言されます。
* **body** は線形の低レベルな命令のリストです。

S 式であるために違って見えますが、これは、他の言語の関数に似ています。

シグネチャと引数
--------

シグネチャは、返値の型宣言のリストが後に続く、引数の型宣言の並びです。ここで注目すべきは次の点です。

* `(result)` がない場合、その関数は何も返さないということです。
* 現在は、最大で 1 つの返値の型を指定することができますが、任意の数に緩和される予定です。

それぞれの引数には、明示的に型を宣言します。Wasm は数値型、参照型、ベクトル型があります。数値型には以下のものがあります。

* `i32`: 32 ビット整数
* `i64`: 64 ビット整数
* `f32`: 32 ビット浮動小数点数
* `f64`: 64 ビット浮動小数点数

単体の引数は `(param i32)` 、返値は `(result i32)` のように記述します。したがって、 2 つの 32 ビット整数を引数にとり、 64 ビット浮動小数点数を返すバイナリー関数は次のように記述します。

```wasm
(func (param i32) (param i32) (result f64) ...)
```

シグネチャのあとに、型付けされたローカル変数のリストが続きます（例: `(local i32)`）。引数は基本的に、呼び出し元から渡された対応する引数の値で初期化される単なるローカル変数です。

ローカル変数と引数を取得/設定する
-----------------

ローカル変数と引数は関数本体から `local.get` と `local.set` 命令を使用して読み書きすることができます。

`local.get`/`local.set` コマンドは数値のインデックスから取得/設定される項目を参照します。最初に引数が宣言順に、その後に、ローカル変数が宣言順に参照されます。次の関数を見てください。

```wasm
(func (param i32) (param f32) (local f64)
  local.get 0
  local.get 1
  local.get 2)
```

命令 `local.get 0` は i32 の引数, `local.get 1` は f32 の引数、そして `local.get 2` は f64 のローカル変数を取得します。

ここで別の問題があります。数値のインデックスを使用して項目を参照すると、混乱したり、困ってしまうことがあります。そこで、テキスト形式では、単純に型宣言の直前に (`$`) を接頭辞として付けた名前を、引数、ローカル変数や他の多くの項目につけることができます。

したがって、上記のシグネチャを次のように書き直すことができます。

```wasm
(func (param $p1 i32) (param $p2 f32) (local $loc f64) …)
```

そして、`local.get 0` の代わりに `local.get $p1` と書くことができるようになります（このテキストがバイナリーに変換されたとき、バイナリーには整数値だけが残されることに注意してください）。

スタックマシン
-------

関数本体を書く前に、もう 1 つ、**スタックマシン**について話をする必要があります。ブラウザーはそれを更に効率的な形にコンパイルしますが、wasm の実行はスタックマシンとして定義されます。スタックマシンの基本的な考え方は、すべての命令がスタックから特定の数の `i32`/`i64`/`f32`/`f64` 値をプッシュ、ポップするようにすることです。

例えば、 `local.get` はローカル変数の値をスタックにプッシュするように定義されます。そして、`i32.add` は2つの `i32` 値 (スタックにプッシュされた前の2つの値を暗黙的に取得します) をポップし、合計を計算して (2^32 の剰余として) 結果の i32 値をプッシュします。

関数が呼び出されたとき、空のスタックから開始され、徐々に積まれてゆき、本体の命令が実行されると空になります。例として、次の関数の実行後について見てみましょう。

```wasm
(func (param $p i32)
  (result i32)
  local.get $p
  local.get $p
  i32.add)
```

スタックには `i32` という値 1 つだけが入っています。これは式 (`$p + $p`) が `i32.add` よって処理された結果です。関数の返値はスタックに残った最後の値になります。

WebAssembly のバリデーションルールはスタックが正確に一致することを保証します。もし、`(result f32)` と宣言した場合、最終的にスタックに1つだけ `f32` 値が積まれている状態である必要があります。結果の型がない場合は、スタックは空でなければなりません。

はじめての関数本体
---------

前述の通り、関数本体は関数が呼び出された後に続く単純な命令列です。 これまでに学んだことと共に、最終的にはシンプルな関数を含むモジュールを定義することができるようになります。

```wasm
(module
  (func (param $lhs i32) (param $rhs i32) (result i32)
    local.get $lhs
    local.get $rhs
    i32.add))
```

この関数は 2 つの引数を受け取って、それらを足して、その結果を返します。

関数本体に置けるものはもっとたくさんありますが、いまはシンプルなもので始めます。進むにつれてもっと多くの例を見ていきます。すべての有効なオペコードのリストについては webassembly.org Semantics reference を調べてみてください。

### 関数の呼び出し

定義した関数は自身では大したことをしません。いまはそれを呼び出す必要があります。どのようにすればよいでしょうか。 ES2015 モジュールのように、Wasm 関数はモジュール内の `export` ステートメントによって明示的にエクスポートしなければなりません。

ローカル変数と同じように、関数も既定ではインデックスで識別されますが、便宜上の関数名を付けることができます。 `func` キーワードの直後にドル記号で始まる名前を付けてみましょう。

```wasm
(func $add …)
```

ここでエクスポート宣言を追加する必要があります。次のようになります。

```wasm
(export "add" (func $add))
```

ここで `add` は JavaScript で認識される関数名であるのに対して、`$add` はモジュール内の、どの WebAssembly 関数をエクスポートするのかを選択します。

（今のところ）最終的なモジュールは次のようになります。

```wasm
(module
  (func $add (param $lhs i32) (param $rhs i32) (result i32)
    local.get $lhs
    local.get $rhs
    i32.add)
  (export "add" (func $add))
)
```

例に従うなら、上のモジュールを `add.wat` という名前で保存して、wabt を使用して（詳細は WebAssembly テキスト形式から Wasm に変換する を参照してください）、`add.wasm` というファイルに変換します。

次に、バイナリーを非同期でインスタンス化し（WebAssembly コードのロードと実行を参照）、JavaScript で `add` 関数を実行しましょう（`add()` はインスタンスの `exports` プロパティから見つけることができます）。

```js
WebAssembly.instantiateStreaming(fetch("add.wasm")).then((obj) => {
  console.log(obj.instance.exports.add(1, 2)); // "3"
});
```

**メモ:** この例は GitHub の add.html（動作例）にあります。関数のインスタンス化についての詳細は `WebAssembly.instantiateStreaming()` も参照してください。

基礎を探る
-----

ここでは実際の基本的な例を取り上げてから、いくつかの高度な機能について見てみましょう。

### 同じモジュールの他の関数から関数を呼び出す

`call` 命令はインデックスか名前を指定して単一の関数を呼び出します。例えば、次のモジュールには 2 つの関数が含まれています。 1 つ目はただ 42 を返すだけ、もう 1 つは 1 つ目のものに 1 を足した値を返します。

```wasm
(module
  (func $getAnswer (result i32)
    i32.const 42)
  (func (export "getAnswerPlus1") (result i32)
    call $getAnswer
    i32.const 1
    i32.add))
```

**メモ:** `i32.const` は 32 ビット整数を定義してスタックにプッシュするだけです。 `i32` 以外の有効な型に変えて、 const の値を好きなものに変えることができます（ここでは `42` に設定しました）。

この例で、 `func` の直後に宣言された `(export "getAnswerPlus1")` セクションに気づくでしょう。これはこの関数をエクスポートするための宣言をして、さらにそれに名前をつけるために使用するショートカットです。

これは、上で行ったように、モジュール内の関数外の別の場所で、関数ステートメントと分けて定義するのと同等の機能です。

```wasm
(export "getAnswerPlus1" (func $functionName))
```

上のモジュールを呼び出す JavaScript コードは次のようになります。

```js
WebAssembly.instantiateStreaming(fetch("call.wasm")).then((obj) => {
  console.log(obj.instance.exports.getAnswerPlus1()); // "43"
});
```

### JavaScript から関数をインポートする

すでに、JavaScript から WebAssembly 関数を呼び出すことについては確認しましたが、WebAssembly から JavaScript 関数を呼び出すことについてはどうでしょうか? WebAssembly は実際に JavaScript のビルトインの情報を持っていませんが、JavaScript か Wasm 関数をインポートするための一般的な方法があります。例を見てみましょう。

```wasm
(module
  (import "console" "log" (func $log (param i32)))
  (func (export "logIt")
    i32.const 13
    call $log))
```

WebAssembly は 2 階層の名前空間のインポート文を持っています。ここでは、`console` モジュールから `log` 関数をインポートすることを要求しています。また、エクスポートされた `logIt` 関数から、上で紹介した `call` 命令を使用して、インポートされた関数を呼ぶ出すことができます。

インポートされた関数は通常の関数と同じようなものです。WebAssembly のバリデーションによって静的にチェックするシグネチャを持ち、インデックスか名前を付けて呼び出すことができます。

JavaScript 関数にはシグネチャの概念がないため、インポート宣言のシグネチャに関係なく、どの JavaScript 関数も渡すことができます。モジュールがインポート宣言をすると、 `WebAssembly.instantiate()` を呼び出す側は、対応したプロパティを持ったインポートオブジェクトを渡す必要があります。

上の場合、 `importObject.console.log` が JavaScript 関数であるようなオブジェクト(`importObject` と呼びましょう) が必要になります。

これは次のようになります。

```js
const importObject = {
  console: {
    log(arg) {
      console.log(arg);
    },
  },
};

WebAssembly.instantiateStreaming(fetch("logger.wasm"), importObject).then(
  (obj) => {
    obj.instance.exports.logIt();
  },
);
```

**メモ:** この例は GitHub の logger.html（動作例）を参照してください。

### WebAssembly でのグローバルの宣言

WebAssembly には、 JavaScript からアクセス可能なグローバル変数インスタンスを作成する機能と、 1 つ以上の `WebAssembly.Module` インスタンスにまたがってインポート/エクスポート可能なグローバル変数インスタンスを作成する機能があります。これは、複数のモジュールを動的にリンクすることができるので、とても便利です。

WebAssembly のテキスト形式では、次のようになります （GitHub のリポジトリーにある global.wat を参照してください。JavaScript の例は global.html も参照してください）。

```wasm
(module
   (global $g (import "js" "global") (mut i32))
   (func (export "getGlobal") (result i32)
        (global.get $g))
   (func (export "incGlobal")
        (global.set $g
            (i32.add (global.get $g) (i32.const 1))))
)
```

これは、キーワード `global` を使用してグローバルな値を指定していることと、値のデータ型と一緒にキーワード `mut` を指定して変更可能にしたい場合に指定していることを除いて、以前に見たものと似ています。

JavaScript を使用して同等の値を作成するには、 `WebAssembly.Global()` コンストラクターを使用してください。

```js
const global = new WebAssembly.Global({ value: "i32", mutable: true }, 0);
```

### WebAssembly メモリー

上の例はとてもひどいロギング関数です。たった 1 つの整数値を表示するだけです。文字列を表示するためにはどうしたらよいでしょうか? 文字列やさらに複雑なデータ型を扱うために WebAssembly は **メモリー** を提供します（WebAssembly のより新しい実装では、参照型もあります）。 WebAssembly では、メモリーは徐々に拡張することのできるただの大きなバイト列です。 WebAssembly は `i32.load` や `i32.store` のような命令を持っており、それで線形メモリーを読み書きします。

JavaScript から見ると、メモリーはすべて 1 つの大きな (リサイズ可能な) `ArrayBuffer` の内部にあるように見えます。それはまさに、asm.js とともに動かさなければならないものすべてです（ただしリサイズは出来ません。asm.js の プログラミングモデル を参照してください）。

したがって、文字列は線形メモリー内部のどこかに存在するただのバイト列です。適切なバイト列の文字列をメモリーに書き込んだとしましょう。その文字列をどのように JavaScript に渡すのでしょうか?

鍵は `WebAssembly.Memory()` インターフェースを使用して JavaScript から WebAssembly の線形メモリーを作成し、関連するインスタンスメソッドを使用して既存の Memory インスタンス（現在は 1 モジュールごとに 1 つだけ持つことができます）にアクセスできることです。Memory インスタンスは `buffer` ゲッターを持ち、これは線形メモリー全体を指し示す ArrayBuffer を返します。

Memory インスタンスは、例えば JavaScript から `Memory.grow()` メソッドを使用して拡張することもできます。拡張したとき、`ArrayBuffer` はサイズを変更することができないため、現在の `ArrayBuffer` は切り離され、新しく作成された、より大きな `ArrayBuffer` を指し示すようになります。これは、JavaScript に文字列を渡すために必要なことは、線形メモリー内での文字列のオフセットと長さを指定する方法を渡すことだけであることを意味します。

文字列自身に文字列の長さの情報をエンコードするさまざまな方法（例えば、 C 言語の文字列）がありますが、簡単にするためにここではオフセットと長さの両方を引数として渡します。

```wasm
(import "console" "log" (func $log (param i32) (param i32)))
```

JavaScript 側では、バイト列を簡単に JavaScript 文字列にデコードするために TextDecoder API を使用することができます (ここでは `utf8` を指定していますが、他の多くのエンコーディングに対応しています) 。

```js
function consoleLogString(offset, length) {
  const bytes = new Uint8Array(memory.buffer, offset, length);
  const string = new TextDecoder("utf8").decode(bytes);
  console.log(string);
}
```

最後のに欠けているのは、 `consoleLogString` が WebAssembly の `memory` にアクセスする場所です。このあたり WebAssembly は柔軟です。JavaScript から `Memory` オブジェクトを作成して WebAssembly モジュールでメモリーをインポートするか、WebAssembly モジュールでメモリーを作成して JavaScript で使用するためにエクスポートすることができます。

簡単にするために、JavaScript で作成したメモリーを WebAssembly にインポートしてみましょう。`import` ステートメントは次のようになります。

```wasm
(import "js" "mem" (memory 1))
```

`1` はインポートされたメモリーに少なくとも 1 ページ分のメモリーが必要であることを示します(WebAssembly では 1 ページを 64KB と定義しています)。

文字列 "Hi" を出力する完全なモジュールを見てみましょう。通常のコンパイルされた C のプログラムでは文字列にメモリーを割り当てる関数を呼び出しますが、ここでは独自のアセンブリーを書くだけで、すべての線形メモリーを所有しているので、 `data` セクションを使用してグローバルメモリーに文字列の内容を書きこむことができます。データセクションではインスタンス化時にオフセットを指定してバイト列の文字列を書きこむことができます。これはネイティブの実行可能形式の `.data` セクションに似ています。

最終的な Wasm モジュールは次のようになります。

```wasm
(module
  (import "console" "log" (func $log (param i32 i32)))
  (import "js" "mem" (memory 1))
  (data (i32.const 0) "Hi")
  (func (export "writeHi")
    i32.const 0 ;; pass offset 0 to log
    i32.const 2 ;; pass length 2 to log
    call $log))
```

**メモ:** 上記の 2 重のセミコロン構文 (`;;`) は WebAssembly ファイル内でコメントを書くためのものです。

ここで、JavaScript から 1 ページ分のサイズを持つ Memory を作成してそれに渡すことができます。結果としてコンソールに "Hi" と出力されます。

```js
const memory = new WebAssembly.Memory({ initial: 1 });

const importObject = {
  console: { log: consoleLogString },
  js: { mem: memory },
};

WebAssembly.instantiateStreaming(fetch("logger2.wasm"), importObject).then(
  (obj) => {
    obj.instance.exports.writeHi();
  },
);
```

**メモ:** 完全なソースは GitHub の logger2.html（動作例）を参照してください。

### WebAssembly テーブル

WebAssembly テキスト形式のツアーを終了するために、 WebAssembly で最も複雑でしばしば混乱する部分 (**テーブル**) を見てみましょう。テーブルは基本的に WebAssembly コードからインデックスでアクセスできるリサイズ可能な参照の配列です。

なぜテーブルが必要なのかを見るために、最初に観察する必要があります。さきほど見た `call` 命令 (同じモジュールの他の関数から関数を呼び出す を参照) は静的な関数インデックスをとり、結果として 1 つの関数しか呼び出せません。しかし、呼び出し先がランタイム値の場合はどうなるでしょうか。

* JavaScript ではこれは常に見えます。関数は第一級の値です。
* C/C++ では関数ポインターで見ることができます。
* C++ では仮想関数で見ることができます。

WebAssembly にはこれを実現するための一種の呼び出し命令が必要だったため、動的な関数をオペランドに受け取る `call_indirect` を与えました。問題は WebAssembly ではオペランドに指定できる型が (現在) `i32`/`i64`/`f32`/`f64` だけであることです。

WebAssembly は `anyfunc` 型 (任意のシグニチャの関数を保持できるため "any") を追加することができましたが、あいにくセキュリティ上の理由から `anyfunc` 型は線形メモリーに格納できませんでした。線形メモリーは格納された値の生の内容をバイト列として公開し、これによって Wasm コンテンツが生の関数ポインターを自由に観察できて破損させることができてしまいます。これはウェブ上では許可できません。

解決方法は関数参照をテーブルに格納し、代わりにテーブルのインデックスを渡すことでした。これは単なる i32 値です。`call_indirect` のオペランドは単純に i32 のインデックス値にすることができます。

#### Wasm でテーブルを定義する

どのようにしてテーブルに Wasm 関数を配置するのでしょうか。 `data` セクションを使用して線形メモリーの領域をバイト列で初期化するのと同じように、`elem` セクションを使用してテーブルの領域を関数の列で初期化することが出来ます:

```wasm
(module
  (table 2 funcref)
  (elem (i32.const 0) $f1 $f2)
  (func $f1 (result i32)
    i32.const 42)
  (func $f2 (result i32)
    i32.const 13)
  ...
)
```

* `(table 2 funcref)` で、2 はテーブルの初期サイズ (2つの参照を格納できることを意味します) で、`funcref` はこれらの参照の要素型がの関数参照であることを宣言します。
* 関数 (`func`) セクションは他の宣言された Wasm 関数と同様です。これらはテーブルで参照する関数です (上の例ではそれぞれは定数を返すだけです) 。セクションが宣言された順序は重要ではないことに注意してください。関数はどこででも宣言できて `elem` セクションから参照することができます。
* `elem` セクションはモジュール内の関数のサブセットをリスト化することができます (任意の順で並べることができ、重複を許容します) 。これは参照された順序でテーブルに参照される関数のリストです。
* `elem` セクション内の `(i32.const 0)` 値はオフセットです。これはセクションの先頭で宣言する必要があります。これはテーブルに関数参照を追加するインデックスの開始位置を指定します。ここでは 0 と テーブルのサイズとして 2 (上記参照) を指定していますので、2つの参照はインデックスが 0 と 1 の部分に書き込まれます。もしオフセットを 1 にして書き込みたければ、 `(i32.const 1)` と記述してテーブルのサイズを 3 にする必要があります。

**メモ:** 初期化されていない要素はデフォルトの throw-on-call 値が与えられます。

JavaScript で同じようなテーブルのインスタンスを作成する場合、次のようになります。

```js
function () {
  // table section
  const tbl = new WebAssembly.Table({initial: 2, element: "anyfunc"});

  // function sections:
  const f1 = ... /\* some imported WebAssembly function \*/
  const f2 = ... /\* some imported WebAssembly function \*/

  // elem section
  tbl.set(0, f1);
  tbl.set(1, f2);
};
```

#### テーブルを使用する

先に進みましょう。いま、何らかの形で使用するために必要なテーブルを定義しました。このコードのセクションで使ってみましょう。

```wasm
(type $return\_i32 (func (result i32))) ;; if this was f32, type checking would fail
(func (export "callByIndex") (param $i i32) (result i32)
  local.get $i
  call\_indirect (type $return\_i32))
```

* `(type $return_i32 (func (result i32)))` ブロックで参照名を持つ型を指定します。この型は後でテーブルの関数参照呼び出しの型チェックを行うときに使用されます。ここでは、参照が1つの `i32` を返す関数である必要があると言っています。
* 次に、`callByIndex` としてエクスポートされる関数を定義します。引数として1つの `i32` をとり、引数名として `$i` が指定されています。
* 関数内部でスタックに値を1つ追加します。値は引数 `$i` のものが渡されます。
* 最後に、テーブルから関数を呼び出すために `call_indirect` を使用します。これは暗黙的に `$i` の値をスタックからポップします。この結果、`callByIndex` 関数はテーブルの `$i` 番目の関数を呼び出します。

`call_indirect` の引数はコマンド呼び出しの前に置く代わりに、次のように明示的に宣言することもできます:

```wasm
(call\_indirect (type $return\_i32) (local.get $i))
```

より高級な、JavaScript のような表現力の高い言語では、関数を含む配列 (あるいはオブジェクトかもしれません) で同じことができることが想像できますよね。擬似コードだとこれは `tbl[i]()` のようになります。

型チェックの話に戻ります。WebAssembly は型チェックされていて、 `funcref` は「任意の関数シグネチャ」を意味するので、呼び出し先の (推定される) シグネチャを指定する必要があります。そのため、 `$return_i32` 型を指定することで、プログラムに関数が `i32` を返すはずだと知らせます。もし呼び出し先のシグネチャが一致しない (代わりに `f32` が返されるような) 場合は `WebAssembly.RuntimeError` 例外が発生します。

さて、呼び出しを行うときにどのようにテーブルに `call_indirect` をリンクさせているのでしょうか? 答えは、現在モジュールインスタンスごとに1つのテーブルしか許容されないため、`call_indirect` はそれを暗黙的に呼び出します。将来的に複数のテーブルを持てるようになったとき、以下の行のように、何らかのテーブル識別子を指定する必要があるでしょう。

```wasm
call\_indirect $my\_spicy\_table (type $i32\_to\_void)
```

完全なモジュールは次のようになります。例は wasm-table.wat を参照してください:

```wasm
(module
  (table 2 funcref)
  (func $f1 (result i32)
    i32.const 42)
  (func $f2 (result i32)
    i32.const 13)
  (elem (i32.const 0) $f1 $f2)
  (type $return\_i32 (func (result i32)))
  (func (export "callByIndex") (param $i i32) (result i32)
    local.get $i
    call\_indirect (type $return\_i32))
)
```

次の JavaScript を使用してウェブページに読み込んでみましょう。

```js
WebAssembly.instantiateStreaming(fetch("wasm-table.wasm")).then((obj) => {
  console.log(obj.instance.exports.callByIndex(0)); // returns 42
  console.log(obj.instance.exports.callByIndex(1)); // returns 13
  console.log(obj.instance.exports.callByIndex(2)); // returns an error, because there is no index position 2 in the table
});
```

**メモ:** 例は GitHub の wasm-table.html (動作例) を参照してください。

**メモ:** Memory と同じように Table も JavaScript から作成すること（`WebAssembly.Table()` を参照）、別の Wasm モジュール間でインポートすることができます。

### テーブルの変更と動的リンク

JavaScript は関数参照にフルアクセスできるため、 Table オブジェクトは JavaScript から `grow()`, `get()`, `set()` メソッドを使用して変更することができます。また、 WebAssembly のコード自体も、参照型の一部として追加された `table.get` や `table.set` などの命令を使ってテーブルを操作することが可能です。

テーブルは変更可能であるため、高度な読み込み時および実行時の動的リンクスキームの実装に使用することができます。プログラムが動的にリンクされたとき、複数のインスタンスで同じメモリーとテーブルを共有することができます。これは複数のコンパイル済み `.dll` が単一のプロセスのアドレス空間を共有するネイティブアプリケーションと対称的です。

この動作を確認するために、Memory オブジェクトと Table オブジェクトを含む単一のインポートオブジェクトを作成し、同じインポートオブジェクトを複数の `instantiate()` の呼び出しで渡してみましょう。

`.wat` ファイルの例は次のようになります。

`shared0.wat`:

```wasm
(module
  (import "js" "memory" (memory 1))
  (import "js" "table" (table 1 funcref))
  (elem (i32.const 0) $shared0func)
  (func $shared0func (result i32)
   i32.const 0
   i32.load)
)
```

`shared1.wat`:

```wasm
(module
  (import "js" "memory" (memory 1))
  (import "js" "table" (table 1 funcref))
  (type $void\_to\_i32 (func (result i32)))
  (func (export "doIt") (result i32)
   i32.const 0
   i32.const 42
   i32.store ;; store 42 at address 0
   i32.const 0
   call\_indirect (type $void\_to\_i32))
)
```

これらは次のように動作します。

1. 関数 `shared0func` は `shared0.wat` で定義され、インポートされたテーブルに格納されます。
2. この関数は定数値 `0` を作成して、次に `i32.load` コマンドを使用して指定したメモリーのインデックスから値をロードします。そのインデックスは `0` になります 。先と同様に、前の値をスタックから暗黙的にポップします。つまり、`shared0func` はメモリーのインデックス `0` の位置に格納された値をロードして返します。
3. `shared1.wat` では、 `doIt` という関数をエクスポートします。この関数は2つの定数値 `0` と `42` を作成して `i32.store` を呼び出して、インポートされたメモリーの指定したインデックスに指定した値を格納します。ここでも、これらの値はスタックから暗黙的にポップされます。したがって、結果的にメモリーのインデックスが `0` の位置に、値として `42` が格納されます。
4. 関数の最後では、定数値 `0` を作成し、テーブルのインデックスが 0 の位置にある関数を呼び出します。これは `shared0func` で、先に `shared0.wat` の `elem` ブロックで格納されたものです。
5. 呼び出されたとき、`shared0func` は `shared1.wat` 内で `i32.store` コマンドを使用してメモリーに格納された 42 をロードします。

**メモ:** 上の式はスタックから値を暗黙的にポップしますが、代わりにコマンド呼び出しの中で明示的に宣言することができます。

```wasm
(i32.store (i32.const 0) (i32.const 42))
(call\_indirect (type $void\_to\_i32) (i32.const 0))
```

アセンブリーに変換した後、次のコードで JavaScript 内で `shared0.wasm` と `shared1.wasm` を使用します:

```js
const importObj = {
  js: {
    memory: new WebAssembly.Memory({ initial: 1 }),
    table: new WebAssembly.Table({ initial: 1, element: "anyfunc" }),
  },
};

Promise.all([
  WebAssembly.instantiateStreaming(fetch("shared0.wasm"), importObj),
  WebAssembly.instantiateStreaming(fetch("shared1.wasm"), importObj),
]).then((results) => {
  console.log(results[1].instance.exports.doIt()); // prints 42
});
```

コンパイルされた各モジュールは同じメモリーとテーブルオブジェクトをインポートし、その結果同じ線形メモリーとテーブルの「アドレス空間」を共有することができます。

**メモ:** 例は GitHub の shared-address-space.html (動作例) を参照してください。

大規模メモリー操作
---------

大規模メモリー操作は、言語へ新しく追加されたものです（例えば Firefox 79）。コピーや初期化などのバルクメモリ操作のために 7 つの新しい組み込み操作が提供されており、 WebAssembly が `memcpy` や `memmove` などのネイティブ関数を、より効率的でパフォーマンスの高い方法でモデル化できるようにします。

新しい操作は次の通りです。

* `data.drop`: データセグメント内のデータを無効にします。
* `elem.drop`: 要素セグメント内のデータを無効にします。
* `memory.copy`: 線形メモリーの一範囲を他へコピーします。
* `memory.fill`: 線形メモリーの一範囲を指定した値で埋めます。
* `memory.init`: データセグメントから範囲をコピーします。
* `table.copy`: テーブルの一範囲から他へコピーします。
* `table.init`: 要素セグメントから範囲をコピーします。

**メモ:** 詳しい情報は Bulk Memory Operations and Conditional Segment Initialization の提案にあります。

型
-

### 数値型

WebAssembly では、現在 4 種類の数値型があります。

* `i32`: 32 ビット整数
* `i64`: 64 ビット整数
* `f32`: 32 ビット浮動小数点数
* `f64`: 64 ビット浮動小数点数
### ベクトル型

* `v128`: 128 ビットのパックされた整数、浮動小数点数データ、または単一の 128 ビット型です。
### 参照型

参照型の提案（Firefox 79 で対応）では、主に 2 つのことを提供しています。

* 新しい型である `externref` は、文字列、DOM 参照、オブジェクトなど、あらゆる JavaScript の値を保持することができます。 WebAssembly の観点からは `externref` は不透明です。Wasm モジュールはこれらの値にアクセスして操作することができず、代わりに値を受け取って送り返すことだけができます。しかし、これは Wasm モジュールが JavaScript の関数や DOM API などを呼び出したり、ホスト環境との相互運用を容易にするために非常に有用です。`externref` は値型とテーブル要素に使用することができます。
* JavaScript API 経由ではなく、Wasm モジュールが直接 WebAssembly テーブルを操作できるようにするための新しい命令がいくつか追加されました。

**メモ:** wasm-bindgen のドキュメントには、 `externref` を Rust で利用する方法について、いくつかの有用な情報が含まれています。

WebAssembly の複数値
----------------

もっと最近になって (例えば Firefox 78) 言語に追加されたものが WebAssembly 複数値です。これは、WebAssembly 関数が複数の値を返すことができるようになり、一連の命令が複数のスタック値を消費して生成することができるようになったことを意味します。

執筆時点 (2020 年 6 月) において、これは初期段階であり、利用可能な多値命令は、それ自体が複数の値を返す関数の呼び出しのみです。例を示します。

```wasm
(module
  (func $get\_two\_numbers (result i32 i32)
    i32.const 1
    i32.const 2
  )
  (func (export "add\_two\_numbers") (result i32)
    call $get\_two\_numbers
    i32.add
  )
)
```

しかし、これはより有用な命令タイプやその他のものへの道を開くことになるでしょう。これまでの進捗状況や、これがどのように動作するかについては、 Nick Fitzgerald の Multi-Value All The Wasm! を参照してください。

WebAssembly スレッド
----------------

WebAssembly スレッド (Firefox 79 以降で対応) は、 WebAssembly Memory オブジェクトを別なウェブワーカー内で動作している複数の WebAssembly インスタンスで共有できるものであり、 JavaScript の `SharedArrayBuffer` と似たような形のものです。これにより、ワーカー間の非常に高速な通信が可能になり、ウェブアプリケーションのパフォーマンスが大幅に向上します。

スレッドの提案は、共有メモリーと不可分メモリーアクセスの 2 つの部分からなります。

### 共有メモリー

上記のように、共有の WebAssembly `Memory` オブジェクトを作成することが可能です。これは、 `postMessage()` を使用してウィンドウとワーカーのコンテキスト間で、 `SharedArrayBuffer` と同じ方法で転送されるものです。

JavaScript API 側では、`WebAssembly.Memory()` コンストラクタの初期化オブジェクトに `shared` プロパティを追加し、 `true` に設定すると共有メモリを作成するようになりました。

```js
const memory = new WebAssembly.Memory({
  initial: 10,
  maximum: 100,
  shared: true,
});
```

メモリーの `buffer` プロパティは `SharedArrayBuffer` を返すようになり、普通の `ArrayBuffer` ではなくなりました。

```js
memory.buffer; // returns SharedArrayBuffer
```

テキスト形式の上では、 `shared` キーワードを使って、次のように共有メモリーを作成することができます。

```wasm
(memory 1 2 shared)
```

共有されていないメモリーと異なり、共有メモリーは JavaScript API のコンストラクターと Wasm のテキスト形式の両方で「最大」サイズを指定する必要があります。

**メモ:** 詳しくは、 WebAssembly のスレッド提案にたくさん載っています。

### 不可分メモリーアクセス

ミューテックスや条件変数など、より高度な機能を実装するために使用できる新しい Wasm 命令が多数追加されました。ここにリストアップされています。これらの命令は、 Firefox 80 の時点で共有でないメモリー上で許可されています。

**メモ:** Emscripten Pthreads support page で、 Emscripten の新機能を利用する方法を紹介しています。

まとめ
---

これで、WebAssembly テキスト形式の主要コンポーネントとそれらが WebAssembly JS API にどのように反映されるのかの高レベルなツアーが完了しました。

関連情報
----

* この記事に含まれなかった主なものは、関数本体で現れるすべての命令の包括的なリストです。各命令の処理は WebAssembly のセマンティックス を参照してください。
* スペックインタプリターによって実装されたテキスト形式の文法も参照してください。


Rust から WebAssembly にコンパイル - WebAssembly

Rust から WebAssembly にコンパイル
==========================

Rust のコードがあれば、それを WebAssembly (Wasm) にコンパイルすることができます。このチュートリアルでは、Rust プロジェクトを WebAssembly にコンパイルし、既存のウェブアプリケーションで使用する方法を示します。

Rust と WebAssembly の用途
----------------------

Rust と WebAssembly には、主に 2 つの用途があります。

* アプリケーション全体を構築する — ウェブアプリ全体を Rust ベースで構築します。
* アプリケーションの一部を構築する — 既存の JavaScript フロントエンドの内部で Rust を使用します。

今のところ、Rust チームは後者のケースに焦点を当てているので、ここではこれについて説明します。前者の場合、`yew` のようなプロジェクトをチェックアウトしてください。

このチュートリアルでは、Rust で npm パッケージを構築するためのツールである `wasm-pack` を使用して npm パッケージを構築します。このパッケージには WebAssembly と JavaScript のコードしか含まれていないため、パッケージのユーザーは Rust をインストールする必要がありません。WebAssembly で書かれていることにすら気づかないかもしれません。

Rust 開発環境のセットアップ
----------------

環境を整えるために必要なすべてのステップを踏んでみましょう。

### Rust のインストール

Install Rust ページに行って指示に従い、Rust をインストールしてください。これによって "rustup" と呼ばれる複数のバージョンの Rust を管理できるようにするツールがインストールされます。既定の設定では、通常の Rust 開発で使いたいであろう最新の安定版 Rust リリースをインストールします。rustup は Rust コンパイラーの `rustc` や Rust のパッケージマネージャーの `cargo` や Rust の標準ライブラリーの `rust-std` やいくつかの助けになるドキュメント — `rust-docs` をインストールします。

**メモ:** インストール後のメモで、cargo の `bin` ディレクトリーをシステムの `PATH` に追加する必要があるという点に注意してください。これは自動的に追加されるはずですが、有効にするためにターミナルを再起動する必要があります。

### wasm-pack

パッケージをビルドするには、`wasm-pack` という追加のツールが必要です。これは `npm` 向けに正しくパッケージングをすることだけでなく、WebAssembly にコードをコンパイルするのにも役立ちます。ダウンロードしてインストールするには、ターミナルに次のコマンドを入力します。

```bash
cargo install wasm-pack
```

WebAssembly パッケージのビルド
---------------------

セットアップは以上です。 Rust で新しいパッケージを作りましょう。個人的なプロジェクトを置いておく場所へ移動して以下を実行してください。

```bash
$ cargo new --lib hello-wasm
     Created library `hello-wasm` project
```

これにより新たなライブラリーが出発に必要なものすべてと一緒に `hello-wasm` という名前のサブディレクトリーに作成されます。
```

├── Cargo.toml
└── src
    └── lib.rs
```

まず `Cargo.toml` があります。これはビルドを設定するためのファイルです。もし `Gemfile` を Bundler から使ったり、`package.json` を npm から使ったりしたことがあるなら、なじみがあるでしょう。cargo は両者と似たような動作をします。

次に、 Cargo はいくつかの Rust コードを `src/lib.rs` に生成してくれています。

```rust
#[cfg(test)]
mod tests {
    #[test]
    fn it\_works() {
        assert\_eq!(2 + 2, 4);
    }
}
```

このチュートリアルでは、このテストコードはまったく使わないので、消してください。

### Rust を書いてみよう

代わりに以下のコードを `src/lib.rs` に書き込みましょう。

```rust
use wasm\_bindgen::prelude::\*;

#[wasm\_bindgen]
extern {
    pub fn alert(s: &str);
}

#[wasm\_bindgen]
pub fn greet(name: &str) {
    alert(&format!("Hello, {}!", name));
}
```

これが Rust プロジェクトの中身です。三つの主要な部分があります。順番に説明しましょう。ここでは高水準な説明を行い、細部は省略します。Rust についてもっと学びたいのであれば、無料のオンラインブック The Rust Programming Language (訳注: 和訳もあります) を確認してください。

#### `wasm-bindgen` を使用して Rust と JavaScript を協調させる

最初の部分は以下のようになっています。

```rust
use wasm\_bindgen::prelude::\*;
```

ライブラリーは Rust では「クレート」と呼ばれます。

理解できましたか？ *Cargo* が*クレート*を取り入れるのです。

3 行目にはコードをライブラリーから自分のコードにインポートする `use` コマンドがあります。この場合、`wasm_bindgen::prelude` モジュールにあるものすべてをインポートしています。これらの機能は次の節で使用します。

次の節に移動する前に、もう少し `wasm-bindgen` について話しておいたほうがいいでしょう。

`wasm-pack` は 別のツールの `wasm-bindgen` を利用して、JavaScript と Rust の型を繋いでいます。`wasm-bindgen` によって JavaScript が文字列に関する Rust API を呼び出すことや Rust の関数が JavaScript の例外をキャッチすることができるようになります。

パッケージ内で `wasm-bindgen` の機能を使うことになるでしょう。実際、次の節で利用します。

#### JavaScript 内の外部関数を Rust から呼び出す

次の部分は以下のようになっています。

```rust
#[wasm\_bindgen]
extern {
    pub fn alert(s: &str);
}
```

`#[ ]` の内側は「属性」と呼ばれ、次に来る文を何らかの形で修飾します。この場合、その文は外部で定義された関数を呼び出したいことを Rust に伝える `extern` です。属性は「wasm-bindgen はこれらの関数を見つける方法を知っている」ということを意味しています。

3 行目は関数の Rust で書かれたシグニチャです。「`alert` 関数は `s` という名前の引数を一つ取る」ということを意味しています。

お察しの通り、これは JavaScript によって提供される `alert` 関数です。次の節でこの関数を呼び出します。

JavaScript 関数を呼び出したい時はいつでも、このファイルに追加すれば、`wasm-bindgen` があらゆるセットアップの世話をしてくれます。まだすべてに対応している訳ではありませんが、作業をしています。何か見つからないものがあればバグを報告してください。

#### JavaScript が呼び出せる Rust 関数の作成

最後の部分は以下のコードです。

```rust
#[wasm\_bindgen]
pub fn greet(name: &str) {
    alert(&format!("Hello, {}!", name));
}
```

再び `#[wasm_bindgen]` 属性が目に入ります。この場合、`extern` ブロックではなく `fn` を改変しています。これは JavaScript がこの Rust 関数を呼び出せるようにしてほしいということを意味します。これは `extern` とは逆です。自分が必要とする関数ではなく、外の世界に渡す関数なのです。

この関数は `greet` という名前で、引数に (`&str` と書かれる) 文字列 `name` を一つ取ります。そしてそれは上の `extern` ブロックで要求した alert 関数を呼び出します。文字列を結合する `format!` マクロに呼び出しを渡します。

`format!` マクロはこの場合フォーマット文字列とそこに挿入する変数の二つの引数を取ります。フォーマット文字列は `"Hello, {}!"` の部分です。それは変数が補完される `{}` を含みます。渡している変数は関数の引数 `name` なので、`greet("Steve")` と呼び出すと `"Hello, Steve!"` が見られるはずです。

これは alert() に渡されるので、この関数を呼び出すと "Hello, Steve!" と書かれたアラートボックスが現れるでしょう。

ライブラリーを書いたので、それをビルドしましょう。

### コードを WebAssembly にコンパイルする

コードを正しくコンパイルするには、はじめに `Cargo.toml` で設定する必要があります。`Cargo.toml` を開き、以下のように中身を変更してください。

```toml
[package]
name = "hello-wasm"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
description = "A sample project with wasm-pack"
license = "MIT/Apache-2.0"
repository = "https://github.com/yourgithubusername/hello-wasm"
edition = "2018"

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

[dependencies]
wasm-bindgen = "0.2"
```

自分自身のリポジトリを記入し、`git` が `authors` フィールドに使用するものと同じ情報を使用してください。

追加する大部分は下にあるものです。最初の部分 — `[lib]` — は Rust にパッケージの cdylib バージョンをビルドするよう伝えます。何を意味するかはこのチュートリアルでは掘り下げません。もっと知るには、Cargo と Rust Linkage のドキュメンテーションを調べてください。

第二の項は `[dependencies]` の項です。ここで Cargo にどのバージョンの `wasm-bindgen` に依存させるかを知らせます。今回の場合、バージョン `0.2.z` のいずれかのものです (`0.3.0` やそれ以上ではありません)。

### パッケージのビルド

すべてのセットアップが完了したので、ビルドしましょう。ターミナルに以下のものを入力してください。

```bash
wasm-pack build --target web
```

このコマンドは多くのことをします (そして時間がかかます。特に初めて `wasm-pack` を実行したときはそうです)。それらについて詳しく学ぶには、Mozilla Hacks のこのブログ投稿を確認してください。手短に説明すると、`wasm-pack build` は次のことをします。

1. Rust コードを WebAssembly にコンパイルする。
2. `wasm-bindgen` をその WebAssembly に対して実行し、WebAssembly ファイルを npm が理解できるモジュールにラップする JavaScript ファイルを生成する。
3. `pkg` ディレクトリーを作成し、その JavaScript ファイルと WebAssembly コードをそこに移動する。
4. `Cargo.toml` を読み、等価な `package.json` を生成する。
5. (もし存在するなら) `README.md` をパッケージにコピーする。

最終的な結果は？ npm パッケージが `pkg` ディレクトリーに生成されます。

#### コードサイズについての余談

生成された WebAssembly のコードサイズについて確認すると、それはおそらく数百キロバイトでしょう。Rust にはサイズの最適化をまったく指示しておらず、最適化すればサイズを大幅に削減できます。これはこのチュートリアルの脱線ですが、もしもっと学習したいなら、Rust WebAssembly Working Group の.wasm のサイズの縮小を確認してください。

パッケージのウェブでの利用
-------------

 さて、コンパイルされた Wasm モジュールが入手できたので、ブラウザーで動かしてみましょう。
 まず `index.html` というファイルをプロジェクトのルートに作成するところから始めましょう。最終的には以下のようなプロジェクト構造になります。
```

├── Cargo.lock
├── Cargo.toml
├── index.html
├── pkg
│   ├── hello_wasm.d.ts
│   ├── hello_wasm.js
│   ├── hello_wasm_bg.wasm
│   ├── hello_wasm_bg.wasm.d.ts
│   └── package.json
├── src
│   └── lib.rs
└── target
    ├── CACHEDIR.TAG
    ├── release
    └── wasm32-unknown-unknown
```

`index.html` ファイルの内容は以下のようなものです。

```html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <title>hello-wasm example</title>
  </head>
  <body>
    <script type="module">
 import init, { greet } from "./pkg/hello\_wasm.js";
 init().then(() => {
 greet("WebAssembly");
 });
 </script>
  </body>
</html>
```

このファイルのスクリプトは、js グルーコードをインポートし、Wasm モジュールを初期化し、rust で書いた `greet` 関数を呼び出します。

プロジェクトのルートディレクトリーに、ローカルのウェブサーバーを用意します（例: `python3 -m http.server`）。やり方がよくわからない場合は、シンプルなローカル HTTP サーバーの実行を参考にしてください。

**メモ:** 必ず `application/wasm` という MIME 型に対応している最新のウェブサーバーを使用してください。古いウェブサーバーでは、まだ対応していないかもしれません。

ウェブサーバーから `index.html` を読み込む （Python3 の例を使用する場合: `http://localhost:8000`）。 画面上にアラートボックスが現れ、 `Hello, WebAssembly!` と表示されます。 JavaScript から Rust へ、そして Rust から JavaScript への呼び出しに成功しました。

npm でパッケージが利用できるようにする
---------------------

WebAssembly モジュールを npm で使用する場合、いくつかの変更が必要です。

まず、Rust を target bundler オプションで再コンパイルすることから始めましょう。

```bash
wasm-pack build --target bundler
```

### Node.js と npm のインストール

npmパッケージを構築しているので、Node.jsと npm をインストールしておく必要があります。

 Node.js と npm を入手するには、 Get npm! ページへ移動して指示に従ってください。
 このチュートリアルでは node 16 をターゲットとしていますので、node のバージョンを切り替えたい場合は、nvm を使用してください。

次に、インストールした他の JavaScript パッケージがこのパッケージを利用できるようにするために、`npm link` を使用しましょう。

```bash
cd pkg
npm link
```

Rust で書かれ、 WebAssembly にコンパイルされた npm パッケージができました。JavaScript から利用する準備ができており、ユーザーが Rust をインストールすることを必要としません。コードに含まれているのは WebAssembly コードであり、Rust のソースではないのです。

### パッケージのウェブでの利用

この新たなパッケージを利用するウェブサイトを構築しましょう。多くの人が様々なバンドラーツールで npm のパッケージを利用していますが、このチュートリアルではそのうちの一つである `webpack` を使用します。これは若干複雑ですが、現実的なユースケースを示します。

`pkg` ディレクトリーの外に戻り、新たなディレクトリー `site` を作成し、そこでこれを試してみましょう。

```bash
cd ..
mkdir site
cd site
npm link hello-wasm
```

新しいファイル `package.json` を作成し、次のコードをそこに書き込んでください。

```json
{
  "scripts": {
    "serve": "webpack-dev-server"
  },
  "dependencies": {
    "hello-wasm": "^0.1.0"
  },
  "devDependencies": {
    "webpack": "^4.25.1",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.10"
  }
}
```

次に、Webpack を設定する必要があります。`webpack.config.js` を作成し、そこに次のことを記入してください。

```js
const path = require("path");
module.exports = {
  entry: "./index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "index.js",
  },
  mode: "development",
};
```

次に、HTML ファイルで参照される `index.js` を作成し、以下の内容を追加してください。

```js
import("./node\_modules/hello-wasm/hello\_wasm.js").then((js) => {
  js.greet("WebAssembly with npm");
});
```

これは新しいモジュールを `node_modules` フォルダーからインポートします。これは最善の方法ではないと思いますが、デモなので、これでいいでしょう。一度そのモジュールが読み込まれると、そこから `greet` 関数を呼び出し、`"WebAssembly"` を文字列として渡します。ここに特別なことはなにもありませんが、Rust コードを呼び出していることに注意してください。JavaScript コードから観察する限り、これはただの普通のモジュールです。

最後に、JavaScript を読み込むための HTML ファイルを追加します。`index.html` ファイルを作成し、以下の内容を追加してください。

```html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <title>hello-wasm example</title>
  </head>
  <body>
    <script src="./index.js"></script>
  </body>
</html>
```

`hello-wasm/site` ディレクトリーは次のようになります。
```

├── index.html
├── index.js
├── node_modules
│   └── hello-wasm -> ../../pkg
├── package.json
└── webpack.config.js
```

ファイルを作りました。これを試してみましょう。

```bash
npm install
npm run serve
```

これでウェブサーバーが起動します。 `http://localhost:8080` を読み込んでください。 `Hello, WebAssembly!` と書かれたアラートボックスが画面に出てくるはずです。JavaScript からの Rust の呼び出しと Rust からの JavaScript の呼び出しに成功しました。

おわりに
----

ここでチュートリアルは終わりです。あなたの役に立ったと思われることを望みます。

この領域にはたくさんの進行中の刺激的な仕事があります。もしそれをもっとよくするのを手伝いたいなら、 the Rust WebAssembly Working Group を確認してください。


WebAssembly JavaScript API の使用 - WebAssembly

WebAssembly JavaScript API の使用
==============================

これまでに Emscripten などのツールを使用して他の言語からモジュールをコンパイルしたり、自分自身のコードを読み込んでして実行したりしました。次のステップは他の WebAssembly JavaScript API の使い方について学ぶことです。この記事では知る必要があることを説明します。

**メモ:** もし、この記事で説明している基本的な概念がよくわからない場合、 WebAssembly の概要を先に読んでからこの記事に戻ってきてください。

シンプルな例
------

WebAssembly JavaScript API の使用方法と、wasm モジュールを読み込んでウェブページ内で使用する方法を、ステップバイステップの例を通して実行してみましょう。

**メモ:** サンプルコードは webassembly-examples GitHub リポジトリーから参照してください。

### 例の準備

1. まずは、 wasm モジュールが必要です! `simple.wasm` をコピーしてローカルマシンの新しいディレクトリーの中に保存してください。
2. 次に、 wasm ファイルと同じディレクトリーに `index.html` という名前でシンプルな HTML ファイルを作成しましょう（簡単に利用できるテンプレートを持っていないのであれば、単純なテンプレートが利用できます）。
3. ここで、何が起こっているのか理解を助けるために、 wasm モジュールのテキスト表現を見てみましょう（WebAssembly 形式から wasm への変換も参照してください）。

```wasm
(module
  (func $i (import "imports" "imported\_func") (param i32))
  (func (export "exported\_func")
    i32.const 42
    call $i))
```

4. 2 行目に 2 階層の名前空間を持つインポートの宣言があります。 — 内部関数 `$i` は `imports.imported_func` からインポートされています。wasm モジュールにインポートするオブジェクトを記述するときに、この 2 階層の名前空間を JavaScript に反映させる必要があります。 `<script></script>` 要素を HTML 内に作成して、次のコードを追加してください。

```js
const importObject = {
  imports: { imported\_func: (arg) => console.log(arg) },
};
```

### WebAssembly モジュールをストリーミングする

Firefox 58 の新機能として、 WebAssembly モジュールを基礎となるソースから直接コンパイルおよびインスタンス化する機能があります。これは `WebAssembly.compileStreaming()` と `WebAssembly.instantiateStreaming()` メソッドを使用して実現します。これらのメソッドは、バイトコードを直接 `Module`/`Instance` インスタンスに変換することができるので、`Response` を `ArrayBuffer` に別途格納する必要がないため、ストリーミングではない対応するメソッドよりも簡単になっています。

この例（GitHub の instantiate-streaming.html デモや、ライブ版も参照してください）では、 `instantiateStreaming()` を使って wasm モジュールを取得し、そこに JavaScript 関数をインポートしてコンパイルしてインスタンス化し、そのエクスポート関数にアクセスするまで、すべて一度に行っています。

スクリプトに以下の 1 ブロックを加えてください。

```js
WebAssembly.instantiateStreaming(fetch("simple.wasm"), importObject).then(
  (obj) => obj.instance.exports.exported\_func(),
);
```

この結果、エクスポートした WebAssembly の `exported_func` 関数を呼び出し、インポートした JavaScript の `imported_func` 関数を呼び出し、WebAssembly インスタンスの中で提供した値 (42) をコンソールに記録することになりました。サンプルのコードを保存して、WebAssembly に対応しているブラウザーで読み込むと、これが実際に動作しているのがわかります。

**メモ:** これは複雑で長い例のほんの一部ですが、ウェブアプリケーション内で WebAssembly をどのように JavaScript と組み合わせて動作させることができるかを説明しています。別の場所でも言及していますが、 WebAssembly は JavaScript の置き換えを目指しているわけではありません。両方が協力して、お互いの強みを活かすことができます。

### ストリーミングせずに wasm モジュールを読み込む

上記のようなストリーミングメソッドを使用できない、または使用したくない場合は、代わりにストリーミングメソッドではない `WebAssembly.compile()` / `WebAssembly.instantiate()` を使用することができます。

これらのメソッドはバイトコードに直接アクセスしないので、 wasm モジュールをコンパイル/インスタンス化する前にレスポンスを `ArrayBuffer` に変換する余分な手順が必要になります。

同等のコードは次のようになります。

```js
fetch("simple.wasm")
  .then((response) => response.arrayBuffer())
  .then((bytes) => WebAssembly.instantiate(bytes, importObject))
  .then((results) => {
    results.instance.exports.exported\_func();
  });
```

### 開発者ツールで wasm を見る

Firefox 54 以降では、開発者ツールのデバッガーパネルでウェブページに含まれる wasm コードのテキスト表現を表示する機能があります。これを表示するためには、デバッガーパネルに移動して、 "wasm://" 項目をクリックしてください。

![](/ja/docs/WebAssembly/Using_the_JavaScript_API/wasm-debug.png)

WebAssembly をテキストとして表示するだけでなく、 WebAssembly のテキスト表現を使用してすぐにデバッグを開始することができます（ブレークポイント、コールスタックの検査、ステップ実行など）。

メモリー
----

WebAssembly の低レベルのメモリーモデルでは、メモリーは線形メモリーと呼ばれる型のない連続したバイト列として表現され、モジュール内のロード、ストア命令を使用して読み書きされます。このメモリーモデルでは、任意のロード、ストア命令は線形メモリー全体の任意のバイトにアクセスすることができます。これはポインターなどの C/C++ の概念を忠実に表現するために必要なものです。

しかし、利用可能なメモリー範囲がプロセス全体に及ぶネイティブの C/C++ プログラムとは異なり、特定の WebAssembly インスタンスがアクセスできるメモリーは、 WebAssembly Memory オブジェクトが含む特定の（潜在的に非常に小さな）範囲に制限されています。これにより、単一のウェブアプリで複数の独立したライブラリー（それぞれが内部で WebAssembly を使用している）を使用し、互いに完全に分離された個別のメモリーを持つことができます。さらに、新しい実装では共有メモリーを作成することもでき、これは `postMessage()` によってウィンドウとワーカーコンテキスト間で転送して複数の場所で使用することが可能です。

JavaScript では、Memory インスタンスはリサイズ可能な `ArrayBuffer` (または共有メモリーの場合は `SharedArrayBuffer`) とみなすことができます。`ArrayBuffer` と同様に、単一のウェブアプリケーションで多くの独立した Memory オブジェクトを作成することができます。Memory オブジェクトは初期サイズと最大サイズ (省略可) を指定して、`WebAssembly.Memory()` コンストラクターから作成することができます。

簡単な例を見ながら、探索を始めましょう。

1. もう 1 つのシンプルな HTML ページを（単純なテンプレートをコピーして）作成し、 `memory.html` という名前を付けてください。このページに `<script></script>` 要素を追加してください。
2. メモリーインスタンスを作成するために、次の行をスクリプトに追加します。

```js
const memory = new WebAssembly.Memory({ initial: 10, maximum: 100 });
```

`initial` と `maximum` の単位は WebAssembly ページです。これらは 64KB に固定されています。上の例では、メモリーインスタンスは初期サイズが 640KB、最大サイズが 6.4MB であることを意味しています。
 WebAssembly メモリーが持つバイト列は ArrayBuffer として buffer ゲッター/セッターから公開されています。例えば、線形メモリーの先頭ワードに直接、 42 を書き込むには次のようにします。

```js
new Uint32Array(memory.buffer)[0] = 42;
```

その後で同じ値を返すことができます。

```js
new Uint32Array(memory.buffer)[0];
```

3. デモで試してみましょう。これまでに追加した内容を保存してブラウザーで読み込んだ後、JavaScript コンソールで上の 2 行を入力してみてください。
### メモリーの拡張

メモリーインスタンスは `Memory.prototype.grow()` を呼び出すことで拡張することができます。引数は WebAssembly ページ単位で指定します。

```js
memory.grow(1);
```

Memory インスタンスの作成時に最大値が指定していて、この最大値を超えて拡張しようとすると `RangeError` 例外が発生します。エンジンは提供された上限を利用してメモリーを事前に確保しておくことで、より効率的なリサイズが可能になります。

注: `ArrayBuffer` の byteLength は変更不可であるため、 `Memory.prototype.grow()` 操作が成功した後、buffer ゲッターは新しい (新しい byteLength で) ArrayBufferを返します。そして、前の ArrayBuffer は「切り離された状態」になるか、メモリーから切り離されます。

関数と同様に、線形メモリーはモジュール内で定義することもインポートすることもできます。同じようにモジュールは任意でメモリーをエクスポートすることも可能です。これは JavaScript が WebAssembly インスタンスに対して新しく作成した `WebAssembly.Memory` をインポートで渡したり、Memory のエクスポートから (`Instance.prototype.exports` を介して) 受け取れることを意味しています。

### より複雑なメモリーの例

より複雑なメモリーの例を見て、上記のことを明確にしましょう。先に定義したメモリーインスタンスをインポートし、それを整数の配列で埋め込んで、それらを合計する WebAssembly モジュールです。これは memory.wasm で見ることができます。

1. `memory.wasm` のローカルコピーを以前と同じディレクトリーに作成します。

**メモ:** モジュールのテキスト表現は memory.wat を参照してください。
2. `memory.html` サンプルファイルに戻って、以前と同じように wasm モジュールを読み取り、コンパイル、インスタンス化します。以下のものをスクリプトの最後に追加してください。

```js
WebAssembly.instantiateStreaming(fetch("memory.wasm"), {
  js: { mem: memory },
}).then((results) => {
  // ここにコードを追加
});
```

3. このモジュールはモジュール内部のメモリーをエクスポートします。instance という名前でモジュールの Instance が取得され、エクスポートされた関数 `accumulate()` を使用してモジュールの線形メモリー (`mem`) に直接入力された配列を合計する事ができます。指定された場所に、次のコードを追加してみましょう。

```js
const i32 = new Uint32Array(memory.buffer);

for (let i = 0; i < 10; i++) {
  i32[i] = i;
}

const sum = results.instance.exports.accumulate(0, 10);
console.log(sum);
```

Memory オブジェクト自体でなく、Memory オブジェクトの buffer (`Memory.prototype.buffer`) から `Uint32Array` ビューを作成していることに注意してください。

メモリーのインポートは関数のインポートと同じように機能します。JavaScript 関数の代わりに Memory オブジェクトを渡すだけです。メモリーのインポートは 2 つの理由で役に立ちます。

* モジュールをコンパイルする前、もしくは並行して、メモリーの初期コンテンツを JavaScript で読み取り、または作成することができます。
* 単一の Memory オブジェクトを複数のモジュールインスタンスにインポートすることができます。これは WebAssembly で動的リンクを実装するための重要な構成要素です。

**メモ:** 完全なデモは memory.html (動作例) を参照してください。

テーブル
----

WebAssembly Table は JavaScript と WebAssembly コードの両方でアクセスできるリサイズ可能な 参照 の型付き配列です。Memory はリサイズ可能な生のバイト列を提供しますが、参照はエンジンに保証された値（このバイト列は安全性、移植性、安定性の理由からコンテンツによって直接読み書きしてはいけない）であるため、参照を格納するために使用することは安全ではありません。

テーブルは要素の型を持ち、テーブルに格納できる参照の型が制限されます。WebAssembly の現バージョンでは WebAssembly コード内で必要な参照の型は関数型の1つだけです。そして、これが唯一の正しい要素の型となります。将来のバージョンでは、さらに多くの要素の型が追加される予定です。

関数参照は関数ポインターを持つ C/C++ のような言語をコンパイルするために必要です。C/C++ のネイティブ実装では、関数ポインターはプロセスの仮想アドレス空間内の関数のコードの生のアドレスで表現されるため、安全性の理由から線形メモリーに直接格納することはできません。代わりに、関数参照はテーブルに格納されます。整数値のインデックスは線形メモリーに格納することができます。

関数ポインターを呼び出すときは、WebAssembly を呼び出す側でインデックスを指定します。インデックスを付けたり、インデックス付けされた関数参照を呼び出す前に安全な境界のチェックをすることができます。したがって、テーブルは現在、安全かつ移植可能に低レベルのプログラミング言語の機能をコンパイルするために使用される、低レベルのプリミティブです。

テーブルは `Table.prototype.set()` を通してテーブル内の値を1つ更新することができます。さらに、`Table.prototype.grow()` でテーブルに格納できる値の数を増やすことができます。時間の経過とともに間接呼び出しされる関数を変更することを許容し、これは 動的リンク技術 のために必要なものです。変化した値に対して JavaScript では `Table.prototype.get()` を通してすぐにアクセスできます。wasm モジュールからも同様です。

### テーブルの例

テーブルのシンプルな例を見てみましょう。紹介する WebAssembly モジュールは2つの要素 (要素0は13、要素1は42を返します) を持つテーブルをエクスポートするものです。モジュールは table.wasm から見つけられます。

1. `table.wasm` をローカルの新しいディレクトリーにコピーします。

**メモ:** このモジュールのテキスト表現は table.wat を参照してください。
2. HTML template を `table.html` という名前で同じディレクトリーにコピーします。
3. 前と同じように、wasm モジュールを読み取り、コンパイル、インスタンス化します。次のコードを HTML の body の末尾の `<script>` 要素に追加してください。

```js
WebAssembly.instantiateStreaming(fetch("table.wasm")).then((results) => {
  // add code here
});
```

4. 今度はテーブル内のデータにアクセスしてみましょう。コードの指定された場所に次の行を追加してください。

```js
const tbl = results.instance.exports.tbl;
console.log(tbl.get(0)()); // 13
console.log(tbl.get(1)()); // 42
```

このコードはテーブルに格納されている各関数参照に順番にアクセスし、内包した値をコンソールに書き出すためにインスタンス化します。 `Table.prototype.get()` で各関数参照を取得した後、関数を実行するためには括弧を追加することに注意してください。

**メモ:** 完全なデモは table.html (動作例) を参照してください。

グローバル値
------

WebAssembly はグローバル変数のインスタンスを作成する機能を持っており、 JavaScript の両方からアクセスでき、1 つ以上の `WebAssembly.Module` インスタンスにわたってインポート/エクスポートが可能です。これにより、複数のモジュールを動的にリンクすることができるので、非常に便利です。

JavaScript の内部から WebAssembly のグローバルインスタンスを作成するには、次のような `WebAssembly.Global()` コンストラクターを使用します。

```js
const global = new WebAssembly.Global({ value: "i32", mutable: true }, 0);
```

これは 2 つの引数を取ることがわかります。

* グローバル変数について記述した 2 つのプロパティを含むオブジェクトです。
    + `value`: データ型は、 WebAssembly モジュールで受け入れられるもの (`i32`, `i64`, `f32`, `f64`) ならばどれでも構いません。
    + `mutable`: 論理値で、値が変更可能かどうかを定義します。
* 変数の実際の値を含む値。これは、指定されたデータ型と一致している限り、どのような値でもよい。

では、これをどう使うのでしょうか。次の例では、値を 0 とする mutable 型の `i32` としてグローバルを定義しています。

次に、グローバル変数の値を変更してみます。最初は `Global.value` を使用して `42` に設定し、それから `global.wasm` モジュールからエクスポートされた `incGlobal()` 関数を使用して 43 にします（この関数は、指定された値に何でも 1 を加算し、新しい値を返します）。

```js
const output = document.getElementById("output");

function assertEq(msg, got, expected) {
  const result =
    got === expected
      ? `SUCCESS! Got: ${got}<br>`
      : `FAIL!<br>Got: ${got}<br>Expected: ${expected}<br>`;
  output.innerHTML += `Testing ${msg}: ${result}`;
}

assertEq("WebAssembly.Global exists", typeof WebAssembly.Global, "function");

const global = new WebAssembly.Global({ value: "i32", mutable: true }, 0);

WebAssembly.instantiateStreaming(fetch("global.wasm"), { js: { global } }).then(
  ({ instance }) => {
    assertEq(
      "getting initial value from wasm",
      instance.exports.getGlobal(),
      0,
    );
    global.value = 42;
    assertEq(
      "getting JS-updated value from wasm",
      instance.exports.getGlobal(),
      42,
    );
    instance.exports.incGlobal();
    assertEq("getting wasm-updated value from JS", global.value, 43);
  },
);
```

**メモ:** GitHub の動作例 を見ることができます。ソースコードも見てください。

多重性
---

ここまで、主な WebAssembly の構成要素のデモを見てきましたが、これは多重性の概念に触れるのによい機会です。これはアーキテクチャ効率の点で多くの進歩がもたらされます:

* 1 つの関数が N 個のクロージャを生成するのと同様に、 1 つのモジュールは N 個のインスタンスを持つことができます。
* 1 つのモジュールインスタンスは 0 から 1 つのメモリーインスタンスを持つことができ、それが「アドレス空間」を提供します。WebAssembly の将来のバージョンでは、 1 つのモジュールが 0 から N 個のメモリーインスタンスを許容する可能性があります (Multiple Memories を参照) 。
* 1 つのモジュールインスタンスは 0 から 1 つのテーブルインスタンスを持つことができます。これはインスタンスの「関数アドレス空間」で、C 言語の関数ポインターを実装するために使用されます。 WebAssembly の将来のバージョンでは 1 つのモジュールにつき 0 から N 個のメモリーインスタンスを許容する可能性があります。
* 1 つのメモリーやテーブルを 0 から N 個のモジュールから使用することができます。複数のインスタンス全てが同じアドレス空間を共有でき、動的リンク が可能です。

多重性については、「WebAssembly テキスト形式を理解」の記事で多重性の働きについてみることができます。その中のテーブルの変更と動的リンクを参照してください。

まとめ
---

この記事では WebAssembly JavaScript API の基本的な使い方について説明しました。WebAssembly モジュールを JavaScript のコンテキストに組み込む方法、その関数を使えるようすること、JavaScript でのメモリーとテーブルの使い方について。さらに、多重性の概念についても触れました。

関連情報
----

* webassembly.org
* WebAssembly の概要
* WebAssembly on Mozilla Research


WebAssembly.Table - WebAssembly

WebAssembly.Table
=================

**`WebAssembly.Table()`** オブジェクトは JavaScript のラッパーオブジェクトであり、関数の参照を格納する WebAssembly Table を表す配列風の構造を持っています。 JavaScript や WebAssembly のコードで作成されたテーブルは、 JavaScript と WebAssembly の両方からアクセスでき、変更もできます。

**メモ:** 現在、テーブルには関数の参照のみが格納できますが、将来的に拡張される予定です。

コンストラクター
--------

`WebAssembly.Table()`

新しい `Table` オブジェクトを生成します。

インスタンスプロパティ
-----------

`Table.prototype.length`

テーブルの長さを返します。すなわち、要素数です。

インスタンスメソッド
----------

`Table.prototype.get()`

アクセサー関数です。指定した位置に格納された要素を取得します。

`Table.prototype.grow()`

Table インスタンスを指定した要素数だけ拡張します。

`Table.prototype.set()`

指定した位置に要素を格納します。

例
-

### 新しい WebAssembly Table インスタンスの生成

次の例では (table2.html と動作例を確認してください)、新しい WebAssembly Table メソッドを初期サイズ 2 要素で生成します。それからそのテーブルの長さと 2 つの位置の内容を (`Table.prototype.get()` を使用して受け取って) 表示し、長さが 2 で両方の要素が `null` であることを示します。

```js
var tbl = new WebAssembly.Table({ initial: 2, element: "anyfunc" });
console.log(tbl.length); // "2"
console.log(tbl.get(0)); // "null"
console.log(tbl.get(1)); // "null"
```

次に、テーブルを含むインポートオブジェクトを生成します。

```js
var importObj = {
  js: {
    tbl: tbl,
  },
};
```

最後に `WebAssembly.instantiateStreaming()` を使用して wasm モジュール (table2.wasm) をロード し、インスタンス化します。table2.wasm モジュールは2の関数を持っていて (1つは42を、もう1つは83を返す) 、インポートされたテーブルの0、1番目に両方の要素が格納されます (text representationを参照) 。そして、インスタンス化された後、テーブルの長さは2のままです。しかし、今はJSから呼び出し可能な エクスポートされたWebAssembly関数 が含まれています。

```js
WebAssembly.instantiateStreaming(fetch('table2.wasm'), importObject)
.then(function(obj) {
  console.log(tbl.length);
  console.log(tbl.get(0)());
  console.log(tbl.get(1)());
});
```

内部の値を表示するためには、参照された関数のアクセサの呼び出しの後に、2つ目の関数呼び出しを含める必要があることに注意して下さい (`get(0)` ではなく `get(0)()`)。

この例では、JavaScript からテーブルを作成してアクセスしていますが、wasm インスタンス内で同じテーブルを参照して呼び出すこともできます。

仕様書
---

| Specification |
| --- |
| WebAssembly JavaScript Interface # tables |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* WebAssembly 概要ページ
* WebAssembly の概念
* WebAssembly JavaScript API の使用


WebAssembly.validate() - WebAssembly

WebAssembly.validate()
======================

**`WebAssembly.validate()`** 関数は WebAssembly バイナリーコードの型付き配列を検証し、そのバイト列が有効な wasm モジュールか (`true`)、そうでないか (`false`) を返します。

構文
--

```js
WebAssembly.validate(bufferSource);
```

### 引数

`bufferSource`

検証する WebAssembly バイナリーコードを含む型付き配列または `ArrayBuffer`。

### 返値

有効な wasm モジュールであるか (`true`)、そうでないか (`false`) を示す論理値です。

### 例外

`bufferSource` が型付き配列または `ArrayBuffer` でない場合、`TypeError` が発生します。

例
-

### validate の使用

以下の例 (`validate.html` のソースコードと動作例 をご確認ください) は .wasm モジュールを読み取って型付き配列に変換します。次に、 `validate()` メソッドを使用してモジュールが有効かどうかをチェックします。

```js
fetch("simple.wasm")
  .then((response) => response.arrayBuffer())
  .then(function (bytes) {
    var valid = WebAssembly.validate(bytes);
    console.log(
      "The given bytes are " + (valid ? "" : "not ") + "a valid wasm module",
    );
  });
```

仕様書
---

| Specification |
| --- |
| WebAssembly JavaScript Interface # dom-webassembly-validate |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* WebAssembly 概要ページ
* WebAssembly の概念
* WebAssembly JavaScript API の使用