Экспортируемые функции WebAssembly
==================================

Экспортированные функции WebAssembly - это функции вашего модуля доступные в JavaScript. В этой статье более подробно описывается, что они из себя представляют.

Экспортированные… что?
----------------------

Экспортированные функции это просто JavaScript обёртки, которые вызывают функции модуля WebAssembly. При их использовании происходит неявное преобразование типов аргументов функции в типы, с которыми может работать WebAssembly (например, преобразование number в int32). Дальше эти аргументы передаются функции вашего модуля и она вызывается. Результат также преобразовывается и возвращается в JavaScript.

Вы можете получить список экспортированных функций двумя способами:

* Вызовите `Table.prototype.get()` (en-US) у существующей таблице;
* Через `Instance.exports` (en-US) существующего экземпляра модуля.

В любом случае вы получаете одну и туже обёртку функции вашего модуля. С точки зрения JavaScript, все экспортированные функции wasm являются функциями JavaScript, но они инкапсулированы экземпляром модуля wasm, и имеют только ограниченный способ доступа к ним.

Пример
------

Давайте посмотрим на пример, чтобы прояснить ситуацию (вы можете найти его на GitHub как table-set.html или запустить в своём браузере, и посмотреть текстовое представление модуля wasm):


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

WebAssembly.instantiateStreaming(fetch("table.wasm")).then((obj) => {
  var 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)());
});
```


Здесь мы создаём таблицу (`otherTable`) из JavaScript используя конструктор `WebAssembly.Table`, после этого мы загружаем модуль `table.wasm` при помощи функции `WebAssembly.instantiateStreaming()` (en-US).

Затем мы получаем объект содержащий все функции, экспортированные из экземпляра модуля. Извлекаем ссылки на эти функции через `tbl.get(),` вызываем их и выводим результат работы в консоль. Затем мы используем `set()` чтобы таблица `otherTable` содержала ссылки на те же функции, что и таблица `tbl`.

Чтобы доказать это, мы получаем ссылки на функции из таблицы `otherTable` и вызываем их. При выводе в консоль они дают такие же результаты.

Они являются настоящими функциями
---------------------------------

В предыдущем примере возвращаемое значение каждого вызова `Table.prototype.get()` (en-US) является экспортированной функцией WebAssembly — это именно то, о чем мы говорили.

Стоит заметить что помимо того что они являются обёртками для функций WebAssembly, это обычные функции JavaScript. Если вы загрузите приведённый выше пример в браузере с поддержкой WebAssembly, и запустите следующие строки в консоли:


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


результатом выполнения будет `function`. Вы можете сделать с ней все тоже самое что и с другими функциями в JavaScript — `call()`, `bind()` и т.д. Вызов `testFunc.toString()` возвращает интересный результат:


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


Это наводит на мысль о том что эта функция является обёрткой.

Дополнительные сведения которые нужно знать при работе с экспортированными функциями:

* Их свойство length это количество аргументов указанных в сигнатуре wasm функции.
* Их свойство name является результатом вызова `toString()` индекса функции в модуле wasm.
* Если вы попытаетесь вызвать экспортированную функцию wasm, которая принимает или возвращает значение типа i64, то это приведёт к ошибке, поскольку в настоящее время JavaScript не имеет точного способа представления i64. Однако в дальнейшем это может измениться - новый тип int64 рассматривается для будущих стандартов, который затем может использоваться wasm.