From 841aae260382e2bf5ebb44d765d8c7301d27caab Mon Sep 17 00:00:00 2001 From: Alexey Istomin Date: Sat, 20 Mar 2021 18:37:44 +0300 Subject: Restore "ё" letter in Russian translation (#239) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs(ru): restore ё letter * docs(ru): resolve conflicts * refactor(idea): remove ide folder --- files/ru/webassembly/c_to_wasm/index.html | 20 ++++----- files/ru/webassembly/concepts/index.html | 22 ++++----- files/ru/webassembly/exported_functions/index.html | 12 ++--- files/ru/webassembly/index.html | 12 ++--- .../ru/webassembly/loading_and_running/index.html | 2 +- files/ru/webassembly/rust_to_wasm/index.html | 34 +++++++------- .../understanding_the_text_format/index.html | 52 +++++++++++----------- .../using_the_javascript_api/index.html | 28 ++++++------ 8 files changed, 91 insertions(+), 91 deletions(-) (limited to 'files/ru/webassembly') diff --git a/files/ru/webassembly/c_to_wasm/index.html b/files/ru/webassembly/c_to_wasm/index.html index 7f47e01433..06a835effe 100644 --- a/files/ru/webassembly/c_to_wasm/index.html +++ b/files/ru/webassembly/c_to_wasm/index.html @@ -47,7 +47,7 @@ int main(int argc, char ** argv) {

Рассмотрим параметры, которые мы передали компилятору:

@@ -61,9 +61,9 @@ int main(int argc, char ** argv) {

Запуск вашего примера

-

Теперь, все что нужно чтобы запустить полученный  hello.html в браузере, это поддержка WebAssembly. Он включен по умолчанию в Firefox 52+, Chrome 57+ и последних версиях Opera. Также вы можете использовать модули WebAssembly в Firefox 47+, включив флаг javascript.options.wasm в about:config, или в Chrome 51+ и Opera 38+ перейдя в chrome://flags и включив флаг Experimental WebAssembly.

+

Теперь, все что нужно чтобы запустить полученный  hello.html в браузере, это поддержка WebAssembly. Он включён по умолчанию в Firefox 52+, Chrome 57+ и последних версиях Opera. Также вы можете использовать модули WebAssembly в Firefox 47+, включив флаг javascript.options.wasm в about:config, или в Chrome 51+ и Opera 38+ перейдя в chrome://flags и включив флаг Experimental WebAssembly.

-

Если все работает как планировалось, вы должны увидеть надпись "Hello world" на открывшейся веб-странице и в JavaScript консоли вашего браузера. Поздравляем, вы только что скомпилировали программу на Си в WebAssembly и запустили ее в своем браузере!

+

Если все работает как планировалось, вы должны увидеть надпись "Hello world" на открывшейся веб-странице и в JavaScript консоли вашего браузера. Поздравляем, вы только что скомпилировали программу на Си в WebAssembly и запустили её в своём браузере!

Примечание: На самом деле, если просто открыть полученный hello.html, то ничего работать не будет. Подразумевается что все файлы находятся на веб-сервере и вы запускаете страницу через localhost/hello.html. Для этих целей можно использовать отладочный веб-сервер Emscripten. Чтобы его запустить, откройте терминал, перейдите в каталог, в котором находятся ваши файлы и выполните команду emrun hello.html

@@ -100,7 +100,7 @@ int main(int argc, char ** argv) {
  • -

    Теперь давайте запустим этот пример. Команда, указанная выше, сгенерирует файл hello2.html, который будет иметь тоже содержание что и шаблон, но с некоторым кодом, добавленным в процесс загрузки сгенерированного wasm, запускающим его и т.д. Откройте его в своем браузере, и вы увидите тот же результат, что и прошлом примере.

    +

    Теперь давайте запустим этот пример. Команда, указанная выше, сгенерирует файл hello2.html, который будет иметь тоже содержание что и шаблон, но с некоторым кодом, добавленным в процесс загрузки сгенерированного wasm, запускающим его и т.д. Откройте его в своём браузере, и вы увидите тот же результат, что и прошлом примере.

  • @@ -108,9 +108,9 @@ int main(int argc, char ** argv) {

    Примечание: Вы можете указать компилятору создавать только JavaScript кода, без HTML, используя внутри флага -o, .js вместо .html для формата выходного файла, например emcc -o hello2.js hello2.c -O3 -s WASM=1. После этого вы должны создать свой собственный HTML файл с нуля. Однако так делать не рекомендуется — Emscripten требуется большое количество связывающего кода для обработки операций выделения памяти, утечек памяти и других проблем, которые уже включены в предоставляемый шаблон. Намного легче использовать уже готовое решение, чем создавать свои собственные версии самому.

    -

    Вызов пользовательской функции, определенной в Си

    +

    Вызов пользовательской функции, определённой в Си

    -

    Если у вас есть функция определенная в коде на Си, которую вы хотите по необходимости вызывать из JavaScript, то вы можете использовать для этого функцию  ccall() из Emscripten, и объявление EMSCRIPTEN_KEEPALIVE которое добавит вашу функцию в список экспортируемых функций (см. Почему функции в моем коде исчезают после компиляции и/или я получаю сообщение «Нет функций для обработки»). Давайте посмотрим, как это работает.

    +

    Если у вас есть функция определённая в коде на Си, которую вы хотите по необходимости вызывать из JavaScript, то вы можете использовать для этого функцию  ccall() из Emscripten, и объявление EMSCRIPTEN_KEEPALIVE которое добавит вашу функцию в список экспортируемых функций (см. Почему функции в моем коде исчезают после компиляции и/или я получаю сообщение «Нет функций для обработки»). Давайте посмотрим, как это работает.

    1. @@ -138,19 +138,19 @@ void EMSCRIPTEN_KEEPALIVE myFunction(int argc, char ** argv) {

      По умолчанию, код созданный Emscripten, всегда просто вызывает функцию  main() , а остальные неиспользуемые функции удаляются. Добавьте определение EMSCRIPTEN_KEEPALIVE перед именем функции чтобы этого не происходило. Также вы должны подключить библиотеку emscripten.h для использования EMSCRIPTEN_KEEPALIVE.

      -

      Примечание: Мы используем блоки #ifdef чтобы, пример оставался рабочим если вы попытаетесь использовать C++ код. Из за различия в правилах преобразования имен между Си и Си++, этот код может сломаться, но мы написали его так, что функция будет рассматриваться как функция Си даже если вы будете использовать Си++.

      +

      Примечание: Мы используем блоки #ifdef чтобы, пример оставался рабочим если вы попытаетесь использовать C++ код. Из за различия в правилах преобразования имён между Си и Си++, этот код может сломаться, но мы написали его так, что функция будет рассматриваться как функция Си даже если вы будете использовать Си++.

    2. -

      Теперь добавьте html_template/shell_minimal.html в ваш новый каталог, просто для удобства. В настоящем проекте стоит размещать его в специально определенный каталог.

      +

      Теперь добавьте html_template/shell_minimal.html в ваш новый каталог, просто для удобства. В настоящем проекте стоит размещать его в специально определённый каталог.

    3. -

      Теперь снова займемся этапом компиляции. Внутри вашего последнего каталога, используя терминал, скомпилируйте ваш Си код следующей командой. (Обратите внимание что при компиляции обязательно нужно использовать опцию NO_EXIT_RUNTIME, иначе после выполнения функции main(), рабочий цикл будет завершен. Это приведет, например, к вызову функции atexits и дальше будет невозможно использовать наш скомпилированный код. Другими словами это необходимо для правильной эмуляции Си.)

      +

      Теперь снова займёмся этапом компиляции. Внутри вашего последнего каталога, используя терминал, скомпилируйте ваш Си код следующей командой. (Обратите внимание что при компиляции обязательно нужно использовать опцию NO_EXIT_RUNTIME, иначе после выполнения функции main(), рабочий цикл будет завершён. Это приведёт, например, к вызову функции atexits и дальше будет невозможно использовать наш скомпилированный код. Другими словами это необходимо для правильной эмуляции Си.)

      emcc -o hello3.html hello3.c -O3 -s WASM=1 --shell-file html_template/shell_minimal.html -s NO_EXIT_RUNTIME=1  -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall"]'
    4. -

      Если вы снова запустите пример в своем браузере, вы увидите тоже самое что и до этого!

      +

      Если вы снова запустите пример в своём браузере, вы увидите тоже самое что и до этого!

    5. Теперь нам нужно вызвать нашу новую функцию myFunction() из JavaScript. Прежде всего, добавьте {{htmlelement("button")}} как показано ниже, чуть выше первого открывающего тега <script type='text/javascript'>.

      diff --git a/files/ru/webassembly/concepts/index.html b/files/ru/webassembly/concepts/index.html index dde3fc40a4..2f1caad232 100644 --- a/files/ru/webassembly/concepts/index.html +++ b/files/ru/webassembly/concepts/index.html @@ -5,7 +5,7 @@ translation_of: WebAssembly/Concepts ---
      {{WebAssemblySidebar}}
      -

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

      +

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

      Что такое WebAssembly?

      @@ -17,11 +17,11 @@ translation_of: WebAssembly/Concepts

      Цели WebAssembly

      -

      Технология WebAssembly создается как открытый стандарт внутри W3C WebAssembly Community Group со следующими целями:

      +

      Технология WebAssembly создаётся как открытый стандарт внутри W3C WebAssembly Community Group со следующими целями:

      • Быть быстрым, эффективным и переносимым - код WebAssembly может выполняться практически на естественной скорости на разных платформах, используя преимущества аппаратных возможностей.
      • -
      • Быть читаемым и отлаживаемым - WebAssembly - это низкоуровневый ассемблерный язык, но он имеет читабельный текстовый формат (спецификация для которого еще дорабатывается), который позволяет писать, просматривать и отлаживать код вручную.   
      • +
      • Быть читаемым и отлаживаемым - WebAssembly - это низкоуровневый ассемблерный язык, но он имеет читабельный текстовый формат (спецификация для которого ещё дорабатывается), который позволяет писать, просматривать и отлаживать код вручную.   
      • Поддерживать безопасность - код WebAssembly предназначен для запуска в безопасной, изолированной среде выполнения. Как и другой веб-код, он будет соблюдать политики безопасности браузера.
      • Не разрушать текущий веб - технология WebAssembly разработана так, что она прекрасно сочетается с другими веб-технологиями и поддерживает обратную совместимость.
      @@ -41,7 +41,7 @@ translation_of: WebAssembly/Concepts

      Исторически ВМ могла загружать только JavaScript. Раньше нас это вполне устраивало, поскольку JavaScript достаточно мощный, чтобы решать большинство проблем, с которыми мы сталкивались в интернете. Однако мы столкнулись с проблемами производительности, когда попытались использовать JavaScript для более нагруженных сценариев использования, таких как 3D-игры, виртуальная и дополненная реальность, компьютерное зрение, редактирование изображений / видео и в ряде других применений, которые требуют повышенной производительности (см. варианты использования WebAssembly где описано больше идей).

      -

      Кроме того, длительность загрузки, анализа и компиляции очень больших приложений JavaScript может быть непомерно высокой. Мобильные и другие ограниченные в ресурсах платформы могут еще более понизить  производительность.

      +

      Кроме того, длительность загрузки, анализа и компиляции очень больших приложений JavaScript может быть непомерно высокой. Мобильные и другие ограниченные в ресурсах платформы могут ещё более понизить  производительность.

      Язык WebAssembly отличается от языка JavaScript, но он не предназначен для его замены. Он предназначен для дополнения и работы вместе с JavaScript, что позволяет веб-разработчикам использовать преимущества обоих языков:

      @@ -59,19 +59,19 @@ translation_of: WebAssembly/Concepts

      Есть несколько ключевых понятий, необходимых для понимания того, как WebAssembly работает в браузере. Все эти понятия отражены 1:1 в WebAssembly JavaScript API.

        -
      • Модуль: Представляет двоичный файл WebAssembly, который был скомпилирован браузером в исполняемый машинный код. Модуль не имеет состояния и, таким образом, как Blob, может быть явным образом разделен между windows и workers (через postMessage()). В модуле есть объявление импорта и экспорта точно такое же, как и в модуле ES2015.
      • +
      • Модуль: Представляет двоичный файл WebAssembly, который был скомпилирован браузером в исполняемый машинный код. Модуль не имеет состояния и, таким образом, как Blob, может быть явным образом разделён между windows и workers (через postMessage()). В модуле есть объявление импорта и экспорта точно такое же, как и в модуле ES2015.
      • Память: Массив ArrayBuffer изменяемого размера, который содержит линейный массив байтов, считываемых и записываемых инструкциями низкоуровневого доступа к памяти в WebAssembly. 
      • Таблица: Типизированный массив ссылок изменяемого размера (например, для функций), которые не могут быть размещены в памяти в виде байтов (по соображениям безопасности и переносимости).
      • -
      • Экземпляр: Модуль в паре со своим состоянием, которое он использует во время выполнения, включая память, таблицу и набор импортируемых значений. Экземпляр  модуля похож на модуль ES2015, который был загружен в определенную глобальную переменную с определенным набором импортов.
      • +
      • Экземпляр: Модуль в паре со своим состоянием, которое он использует во время выполнения, включая память, таблицу и набор импортируемых значений. Экземпляр  модуля похож на модуль ES2015, который был загружен в определённую глобальную переменную с определённым набором импортов.
      -

      JavaScript API предоставляет разработчикам возможность создавать модули, объекты памяти, таблицы и экземпляры модулей. Получив экземпляр модуля WebAssembly, код JavaScript может синхронно вызывать его экспорты, которые представляются как обычные функции JavaScript. Любые функции JavaScript также могут синхронно вызываться кодом WebAssembly путем передачи этих функций в качестве импорта в экземпляр модуля WebAssembly.

      +

      JavaScript API предоставляет разработчикам возможность создавать модули, объекты памяти, таблицы и экземпляры модулей. Получив экземпляр модуля WebAssembly, код JavaScript может синхронно вызывать его экспорты, которые представляются как обычные функции JavaScript. Любые функции JavaScript также могут синхронно вызываться кодом WebAssembly путём передачи этих функций в качестве импорта в экземпляр модуля WebAssembly.

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

      В будущем модули WebAssembly будут загружаться так же, как и модули ES2015 (с использованием <script type='module'>), что означает, что JavaScript сможет извлекать, компилировать и импортировать модуль WebAssembly так же легко, как модуль ES2015.

      -

      Как я могу использовать WebAssembly в своем приложении?

      +

      Как я могу использовать WebAssembly в своём приложении?

      Выше мы говорили о низкоуровневых примитивах, которые WebAssembly добавляет к веб-платформе: двоичный формат для кода и API для его загрузки и запуска. Теперь давайте поговорим о том, как мы можем использовать эти примитивы на практике.

      @@ -87,7 +87,7 @@ translation_of: WebAssembly/Concepts

      Портирование из C/C++

      -

      Из множества вариантов создания кода WASM есть два наиболее популярных - это онлайн-сборщик wasm или Emscripten. Существует еще несколько вариантов сборки WASM, таких как:

      +

      Из множества вариантов создания кода WASM есть два наиболее популярных - это онлайн-сборщик wasm или Emscripten. Существует ещё несколько вариантов сборки WASM, таких как:

      • WasmFiddle
      • @@ -104,9 +104,9 @@ translation_of: WebAssembly/Concepts

        В двух словах, процесс работает следующим образом:

          -
        1. Сначала Emscripten передает код C/C++ в clang + LLVM - набор инструментов компилятора C/C++ с открытым исходным кодом, который поставляется, например, как часть XCode для OSX.
        2. +
        3. Сначала Emscripten передаёт код C/C++ в clang + LLVM - набор инструментов компилятора C/C++ с открытым исходным кодом, который поставляется, например, как часть XCode для OSX.
        4. Emscripten преобразует скомпилированный результат clang + LLVM в двоичный файл .wasm.   
        5. -
        6. Сам по себе код WebAssembly в настоящее время не может напрямую обращаться к DOM; он может вызывать только JavaScript, передавая целочисленные и числа с плавающей точкой примитивные типы данных. Таким образом, чтобы получить доступ к любому Web-API, WebAssembly модуль должен обращаться к JavaScript, который затем вызывает Web-API. Поэтому Emscripten создает необходимый для этого связующий код HTML и JavaScript.
        7. +
        8. Сам по себе код WebAssembly в настоящее время не может напрямую обращаться к DOM; он может вызывать только JavaScript, передавая целочисленные и числа с плавающей точкой примитивные типы данных. Таким образом, чтобы получить доступ к любому Web-API, WebAssembly модуль должен обращаться к JavaScript, который затем вызывает Web-API. Поэтому Emscripten создаёт необходимый для этого связующий код HTML и JavaScript.
        diff --git a/files/ru/webassembly/exported_functions/index.html b/files/ru/webassembly/exported_functions/index.html index c586422de3..d46ae2ad53 100644 --- a/files/ru/webassembly/exported_functions/index.html +++ b/files/ru/webassembly/exported_functions/index.html @@ -14,7 +14,7 @@ translation_of: WebAssembly/Exported_functions

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

        -

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

        +

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

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

        @@ -23,11 +23,11 @@ translation_of: WebAssembly/Exported_functions
      • Через Instance.exports существующего экземпляра модуля.
      -

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

      +

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

      Пример

      -

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

      +

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

      var otherTable = new WebAssembly.Table({ element: "anyfunc", initial: 2 });
       
      @@ -42,7 +42,7 @@ WebAssembly.instantiateStreaming(fetch('table.wasm'))
         console.log(otherTable.get(1)());
       });
      -

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

      +

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

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

      @@ -52,7 +52,7 @@ WebAssembly.instantiateStreaming(fetch('table.wasm'))

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

      -

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

      +

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

      var testFunc = otherTable.get(0);
       typeof testFunc;
      @@ -70,5 +70,5 @@ typeof testFunc;
      • Их свойство length это количество аргументов указанных в сигнатуре wasm функции.
      • Их свойство name является результатом вызова toString() индекса функции в модуле wasm.
      • -
      • Если вы попытаетесь вызвать экспортированную функцию wasm, которая принимает или возвращает значение типа i64, то это приведет к ошибке, поскольку в настоящее время JavaScript не имеет точного способа представления i64. Однако в дальнейшем это может измениться - новый тип int64 рассматривается для будущих стандартов, который затем может использоваться wasm.
      • +
      • Если вы попытаетесь вызвать экспортированную функцию wasm, которая принимает или возвращает значение типа i64, то это приведёт к ошибке, поскольку в настоящее время JavaScript не имеет точного способа представления i64. Однако в дальнейшем это может измениться - новый тип int64 рассматривается для будущих стандартов, который затем может использоваться wasm.
      diff --git a/files/ru/webassembly/index.html b/files/ru/webassembly/index.html index 84e0c56b57..0d5c9c5d30 100644 --- a/files/ru/webassembly/index.html +++ b/files/ru/webassembly/index.html @@ -13,7 +13,7 @@ translation_of: WebAssembly

      WebAssembly разработан для дополнения JavaScript – используя WebAssembly JavaScript API вы можете загружать модули WebAssembly в приложения JavaScript и обеспечивать взаимодействие между ними, используя общие функции. Такой подход позволяет вам получить производительность и мощность WebAssembly, а также выразительность и гибкость JavaScript в ваших приложениях, даже если вы не знаете как писать код WebAssembly, а используете готовые модули.

      -

      И что еще лучше, так это то, что WebAssembly разрабатывается как веб-стандарт W3C WebAssembly Working Group и Community Group при активном участии основных производителей браузеров.

      +

      И что ещё лучше, так это то, что WebAssembly разрабатывается как веб-стандарт W3C WebAssembly Working Group и Community Group при активном участии основных производителей браузеров.

      @@ -46,7 +46,7 @@ translation_of: WebAssembly
      {{jsxref("Global_objects/WebAssembly", "WebAssembly")}}
      -
      Этот объект является пространством имен для всех функций, связанных с WebAssembly.
      +
      Этот объект является пространством имён для всех функций, связанных с WebAssembly.
      {{jsxref("Global_objects/WebAssembly/Module", "WebAssembly.Module()")}}
      Объект WebAssembly.Module содержит не контролируемый WebAssembly код, который уже скомпилирован браузером и может эффективно использоваться совместно с Workers, кешироваться в IndexedDB, и иметь несколько экземпляров.
      {{jsxref("Global_objects/WebAssembly/Instance", "WebAssembly.Instance()")}}
      @@ -58,11 +58,11 @@ translation_of: WebAssembly
      {{jsxref("Global_objects/WebAssembly/Table", "WebAssembly.Table()")}}
      WebAssembly.Table объект является изменяемым типизированным массивом значений, таких как ссылки на функции, которые доступны Instance.
      {{jsxref("WebAssembly.CompileError()")}}
      -
      Создает новый WebAssembly CompileError объект.
      +
      Создаёт новый WebAssembly CompileError объект.
      {{jsxref("WebAssembly.LinkError()")}}
      -
      Создает новый WebAssembly LinkError объект.
      +
      Создаёт новый WebAssembly LinkError объект.
      {{jsxref("WebAssembly.RuntimeError()")}}
      -
      Создает новый WebAssembly RuntimeError объект.
      +
      Создаёт новый WebAssembly RuntimeError объект.
      @@ -96,7 +96,7 @@ translation_of: WebAssembly

      Совместимость с браузерами

      - +

      {{Compat("javascript.builtins.WebAssembly")}}

      diff --git a/files/ru/webassembly/loading_and_running/index.html b/files/ru/webassembly/loading_and_running/index.html index a796cc7a30..20460d2e40 100644 --- a/files/ru/webassembly/loading_and_running/index.html +++ b/files/ru/webassembly/loading_and_running/index.html @@ -15,7 +15,7 @@ translation_of: WebAssembly/Loading_and_running

      Какие есть варианты?

      -

      WebAssembly еще не интегрирована с <script type='module'> или ES2015 оператором import, поэтому не существует пути, позволяющего использовать модули загрузки браузера для использования импорта.

      +

      WebAssembly ещё не интегрирована с <script type='module'> или ES2015 оператором import, поэтому не существует пути, позволяющего использовать модули загрузки браузера для использования импорта.

      Старые методы {{jsxref("WebAssembly.compile")}}/{{jsxref("WebAssembly.instantiate")}} требуют создания {{domxref("ArrayBuffer")}}, содержащего двоичный файл модуля WebAssembly после загрузки необработанных байтов, а затем скомпилировать/создать его экземпляр. Это аналог new Function(string), за исключением того, что мы заменяем строку символов (исходный код JavaScript) буфером байтов массива (исходный код WebAssembly).

      diff --git a/files/ru/webassembly/rust_to_wasm/index.html b/files/ru/webassembly/rust_to_wasm/index.html index 629987ff09..381d424bf0 100644 --- a/files/ru/webassembly/rust_to_wasm/index.html +++ b/files/ru/webassembly/rust_to_wasm/index.html @@ -22,7 +22,7 @@ translation_of: WebAssembly/Rust_to_wasm

      Настройка окружения Rust

      -

      Давайте пройдемся по всем пунктам, необходимым для настройки нашего окружения.

      +

      Давайте пройдёмся по всем пунктам, необходимым для настройки нашего окружения.

      Установка Rust

      @@ -55,12 +55,12 @@ Password: Email: (this IS public) you@example.com -

      Вам понадобится ввести свое пользовательское имя, пароль и email. Если все получится, вы увидите:

      +

      Вам понадобится ввести своё пользовательское имя, пароль и email. Если все получится, вы увидите:

      Logged in as yournpmusername on https://registry.npmjs.org/.
       
      -

      Если что-то пойдет не так, свяжитесь с командой npm, чтобы разобраться.

      +

      Если что-то пойдёт не так, свяжитесь с командой npm, чтобы разобраться.

      Создание WebAssembly npm-пакета

      @@ -111,7 +111,7 @@ pub fn greet(name: &str) { } -

      Это содержимое нашего проекта на Rust. У него есть три основные части, давайте пройдемся по ним по очереди. Мы дадим здесь обобщенное пояснение и поясним некоторые детали; чтобы узнать больше о Rust, пожалуйста, просмотрите бесплатную online-книгу The Rust Programming Language.

      +

      Это содержимое нашего проекта на Rust. У него есть три основные части, давайте пройдёмся по ним по очереди. Мы дадим здесь обобщённое пояснение и поясним некоторые детали; чтобы узнать больше о Rust, пожалуйста, просмотрите бесплатную online-книгу The Rust Programming Language.

      Использование wasm-bindgen для коммуникации между Rust и JavaScript

      @@ -144,13 +144,13 @@ extern { } -

      Частичка внутри #[] называется "атрибутом", и она кое-как модифицирует следующее за ней утверждение. В нашем случае, это утверждение extern, которое говорит Rust-у, что мы хотим вызвать некоторую функцию, определенную во внешнем пространстве. Атрибут говорит: "wasm-bindgen знает, как найти эти функции".

      +

      Частичка внутри #[] называется "атрибутом", и она кое-как модифицирует следующее за ней утверждение. В нашем случае, это утверждение extern, которое говорит Rust-у, что мы хотим вызвать некоторую функцию, определённую во внешнем пространстве. Атрибут говорит: "wasm-bindgen знает, как найти эти функции".

      Третья строка это имя функции, написанной на Rust. Она говорит: "функция alert  принимает один аргумент, строку с именем s."

      У вас, возможно, есть предположение, что это за функция, и, возможно, ваше предположение верное: это функция alert, предоставляемая JavaScript! Мы будем вызывать эту функцию в следующей секции.

      -

      Когда бы вы не захотели вызвать новую функцию JavaScript, вы можете написать ее здесь, и wasm-bindgen позаботится о том, чтобы настроить все для вас. Пока еще поддерживается не все, но мы работаем над этим! Пожалуйста, сообщайте о проблемах, если что-то было упущено.

      +

      Когда бы вы не захотели вызвать новую функцию JavaScript, вы можете написать её здесь, и wasm-bindgen позаботится о том, чтобы настроить все для вас. Пока ещё поддерживается не все, но мы работаем над этим! Пожалуйста, сообщайте о проблемах, если что-то было упущено.

      Создание функций Rust, который может вызывать JavaScript

      @@ -162,15 +162,15 @@ pub fn greet(name: &str) { } -

      Еще раз, мы видим #[wasm_bindgen] атрибут. В этом случае, он модифицирует не блок extern, а fn; это значит, что мы хотим, чтобы эта функция на Rust была доступна для JavaScript. Прямо противоположно extern: это не те функции, которые нам нужны, а те, что мы предоставляем миру!

      +

      Ещё раз, мы видим #[wasm_bindgen] атрибут. В этом случае, он модифицирует не блок extern, а fn; это значит, что мы хотим, чтобы эта функция на Rust была доступна для JavaScript. Прямо противоположно extern: это не те функции, которые нам нужны, а те, что мы предоставляем миру!

      -

      Наша функция называется greet, и она принимает один аргумент, строку (пишется &str), name. Затем она вызывает функцию alert, которую мы запросили в блоке extern выше. Она передает вызов макросу format!, который позволяет нам соединить строки.

      +

      Наша функция называется greet, и она принимает один аргумент, строку (пишется &str), name. Затем она вызывает функцию alert, которую мы запросили в блоке extern выше. Она передаёт вызов макросу format!, который позволяет нам соединить строки.

      -

      format! принимает два аргумента в нашем случае: форматируемую строку и переменную, которую должен в нее поместить. Форматируемая строка это "Hello, {}!" часть. Она содержит {}, куда будет вставлена переменная. Переменная, которую мы передаем, это name, аргумент функции, так что если мы вызовем greet("Steve"), то увидим "Hello, Steve!".

      +

      format! принимает два аргумента в нашем случае: форматируемую строку и переменную, которую должен в неё поместить. Форматируемая строка это "Hello, {}!" часть. Она содержит {}, куда будет вставлена переменная. Переменная, которую мы передаём, это name, аргумент функции, так что если мы вызовем greet("Steve"), то увидим "Hello, Steve!".

      -

      Все это передается в alert(), так что когда мы вызовем функцию, мы увидим алерт с "Hello, Steve!" внутри него!

      +

      Все это передаётся в alert(), так что когда мы вызовем функцию, мы увидим алерт с "Hello, Steve!" внутри него!

      -

      Теперь, когда наша библиотека написана, давайте соберем ее.

      +

      Теперь, когда наша библиотека написана, давайте соберём ее.

      Компиляция кода в WebAssembly

      @@ -199,7 +199,7 @@ wasm-bindgen = "0.2"

      Сборка пакета

      -

      Теперь, когда мы все установили, давайте соберем проект! Введите это в терминале:

      +

      Теперь, когда мы все установили, давайте соберём проект! Введите это в терминале:

      $ wasm-pack build --scope mynpmusername
       
      @@ -209,8 +209,8 @@ wasm-bindgen = "0.2"
      1. Компилирует ваш Rust-код в WebAssembly.
      2. Запускает wasm-bindgen с этим WebAssembly, генерируя JavaScript файл, который оборачивает WebAssembly файл в модуль. который может понять npm.
      3. -
      4. Создает папку pkg, куда перемещает этот JavaScript файл и ваш код WebAssembly.
      5. -
      6. Читает ваш Cargo.toml и создает эквивалентный package.json.
      7. +
      8. Создаёт папку pkg, куда перемещает этот JavaScript файл и ваш код WebAssembly.
      9. +
      10. Читает ваш Cargo.toml и создаёт эквивалентный package.json.
      11. Копирует ваш README.md (если есть) в пакет.
      @@ -232,7 +232,7 @@ $ npm publish --access=public

      Использование пакета в web

      -

      Давайте создадим сайт, который будет использовать наш пакет! Многие пользуются пакетами npm с помощью разных сборщиков, и мы будем использовать один из них, webpack, в этом руководстве. Он только немного более усложненный, но описывает более реалистичный вариант использования.

      +

      Давайте создадим сайт, который будет использовать наш пакет! Многие пользуются пакетами npm с помощью разных сборщиков, и мы будем использовать один из них, webpack, в этом руководстве. Он только немного более усложнённый, но описывает более реалистичный вариант использования.

      Давайте выйдем из нашей папки pkg и создадим новую, site, чтобы попробовать в ней следующее:

      @@ -258,7 +258,7 @@ $ cd site } -

      Заметьте, что вам нужно ввести свое пользовательское имя после @ в секции зависимостей.

      +

      Заметьте, что вам нужно ввести своё пользовательское имя после @ в секции зависимостей.

      Дальше нам нужно сконфигурировать Webpack. Создайте webpack.config.js и введите следующее:

      @@ -297,7 +297,7 @@ js.then(js => {

      Заметьте, что вам нужно будет снова ввести ваше имя для npm.

      -

      Так мы импортируем наш модуль из папки node_modules. Это не считается лучшей практикой, но это пример, так что пока сойдет. Как только файл загрузится, он вызовет функцию greet из этого модуля, передав "WebAssembly", как строку. Обратите внимание, что здесь нет ничего особенного, и все же мы вызываем код на Rust! Насколько JavaScript код может судить, это просто обычный модуль.

      +

      Так мы импортируем наш модуль из папки node_modules. Это не считается лучшей практикой, но это пример, так что пока сойдёт. Как только файл загрузится, он вызовет функцию greet из этого модуля, передав "WebAssembly", как строку. Обратите внимание, что здесь нет ничего особенного, и все же мы вызываем код на Rust! Насколько JavaScript код может судить, это просто обычный модуль.

      Мы закончили! Давайте попробуем:

      diff --git a/files/ru/webassembly/understanding_the_text_format/index.html b/files/ru/webassembly/understanding_the_text_format/index.html index 38934e21f2..226a873888 100644 --- a/files/ru/webassembly/understanding_the_text_format/index.html +++ b/files/ru/webassembly/understanding_the_text_format/index.html @@ -8,14 +8,14 @@ translation_of: WebAssembly/Understanding_the_text_format

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

      -

      Примечание: Ознакомление с данной статьей может оказаться излишним, если вы веб-разработчик, который просто хочет загрузить модуль wasm на страницу и использовать его в своем коде (см. Использование WebAssembly JavaScript API). Эта статья будет наиболее полезной, если вы хотите написать несколько модулей wasm для оптимизации производительности вашей библиотеки JavaScript или создать свой собственный компилятор WebAssembly.

      +

      Примечание: Ознакомление с данной статьёй может оказаться излишним, если вы веб-разработчик, который просто хочет загрузить модуль wasm на страницу и использовать его в своём коде (см. Использование WebAssembly JavaScript API). Эта статья будет наиболее полезной, если вы хотите написать несколько модулей wasm для оптимизации производительности вашей библиотеки JavaScript или создать свой собственный компилятор WebAssembly.

      S-выражения

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

      -

      Во-первых, давайте посмотрим, как выглядит S-выражение. Каждый узел дерева входит в пару круглых скобок - ( ... ). Первая метка в скобках сообщает вам, какой это тип узла, за ним следует разделенный пробелами список атрибутов или дочерних узлов. Давайте рассмотрим, что  означает следующее S-выражение WebAssembly:

      +

      Во-первых, давайте посмотрим, как выглядит S-выражение. Каждый узел дерева входит в пару круглых скобок - ( ... ). Первая метка в скобках сообщает вам, какой это тип узла, за ним следует разделённый пробелами список атрибутов или дочерних узлов. Давайте рассмотрим, что  означает следующее S-выражение WebAssembly:

      (module (memory 1) (func))
      @@ -23,7 +23,7 @@ translation_of: WebAssembly/Understanding_the_text_format

      Самый простой модуль

      -

      Давайте начнем с самого простого модуля wasm.

      +

      Давайте начнём с самого простого модуля wasm.

      (module)
      @@ -44,7 +44,7 @@ translation_of: WebAssembly/Understanding_the_text_format
      • signature объявляет, что функция принимает (параметры) и возвращает (возвращаемые значения).
      • -
      • locals похожи на переменные в JavaScript, но с определенными явными типами.
      • +
      • locals похожи на переменные в JavaScript, но с определёнными явными типами.
      • body - это просто линейный список низкоуровневых инструкций.
      @@ -101,11 +101,11 @@ translation_of: WebAssembly/Understanding_the_text_format

      Стековые машины

      -

      Прежде чем мы сможем написать тело функции, мы должны поговорить еще о стековых машинах. Хотя браузер компилирует wasm-код во что-то более эффективное, выполнение его определяется в терминах стековой машины, где основная идея заключается в том, что каждый тип инструкции получает или помещает определенное количество значений i32 / i64 / f32 / f64 в стек или из стека.

      +

      Прежде чем мы сможем написать тело функции, мы должны поговорить ещё о стековых машинах. Хотя браузер компилирует wasm-код во что-то более эффективное, выполнение его определяется в терминах стековой машины, где основная идея заключается в том, что каждый тип инструкции получает или помещает определённое количество значений i32 / i64 / f32 / f64 в стек или из стека.

      -

      Например, инструкция get_local предназначена для помещения значения локальной переменной, которое она считала, в стек. А инструкция i32.add получает два значения i32 (неявно получает два предыдущих значения, помещенных в стек), вычисляет их сумму и помещает назад в стек результат вычисления i32.

      +

      Например, инструкция get_local предназначена для помещения значения локальной переменной, которое она считала, в стек. А инструкция i32.add получает два значения i32 (неявно получает два предыдущих значения, помещённых в стек), вычисляет их сумму и помещает назад в стек результат вычисления i32.

      -

      Когда вызывается функция, для нее выделяется пустой стек, который постепенно заполняется и очищается при выполнении инструкций в теле функции. Так, например, после выполнения следующей функции:

      +

      Когда вызывается функция, для неё выделяется пустой стек, который постепенно заполняется и очищается при выполнении инструкций в теле функции. Так, например, после выполнения следующей функции:

      (func (param $p i32)
         get_local $p
      @@ -128,7 +128,7 @@ translation_of: WebAssembly/Understanding_the_text_format
       
       

      Эта функция получает два параметра, складывает их вместе и возвращает результат.

      -

      Есть еще много инструкций, которые можно поместить в тело функции. Сейчас мы начнем с простых, а далее вы увидите гораздо больше примеров по мере продвижения. Полный список доступных инструкций смотрите в справочнике по семантике webassembly.org.

      +

      Есть ещё много инструкций, которые можно поместить в тело функции. Сейчас мы начнём с простых, а далее вы увидите гораздо больше примеров по мере продвижения. Полный список доступных инструкций смотрите в справочнике по семантике webassembly.org.

      Вызов функции

      @@ -169,7 +169,7 @@ translation_of: WebAssembly/Understanding_the_text_format

      Изучение основ

      -

      Теперь, когда мы рассмотрели простейшие примеры, давайте перейдем к рассмотрению некоторых более сложных возможностей.

      +

      Теперь, когда мы рассмотрели простейшие примеры, давайте перейдём к рассмотрению некоторых более сложных возможностей.

      Вызов функций из других функций в том же модуле

      @@ -184,10 +184,10 @@ translation_of: WebAssembly/Understanding_the_text_format i32.add))
      -

      Примечание: Инструкция i32.const создает 32-разрядное целое число и помещает его в стек. Вы можете поменять i32 на любой другой доступный тип данных и изменить значение на любое другое (здесь мы установили значение 42).

      +

      Примечание: Инструкция i32.const создаёт 32-разрядное целое число и помещает его в стек. Вы можете поменять i32 на любой другой доступный тип данных и изменить значение на любое другое (здесь мы установили значение 42).

      -

      В этом примере обратите внимание на секцию объявления экспорта (export “getAnswerPlus1”), которая находится сразу после объявления второй функции func. Это сокращенный способ объявления, совмещенный с именем функции, которую мы хотим экспортировать.

      +

      В этом примере обратите внимание на секцию объявления экспорта (export “getAnswerPlus1”), которая находится сразу после объявления второй функции func. Это сокращённый способ объявления, совмещённый с именем функции, которую мы хотим экспортировать.

      Функционально это эквивалентно включению отдельного объявления экспорта функции без функции, в любом месте модуля, например:

      @@ -201,12 +201,12 @@ translation_of: WebAssembly/Understanding_the_text_format });
      -

      Примечание: Вы можете найти этот пример на GitHub как call.html (смотрите также вживую). Еще посмотрите wasm-utils.js для метода fetchAndInstantiate().

      +

      Примечание: Вы можете найти этот пример на GitHub как call.html (смотрите также вживую). Ещё посмотрите wasm-utils.js для метода fetchAndInstantiate().

      Импорт функций из JavaScript

      -

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

      +

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

      (module
         (import "console" "log" (func $log (param i32)))
      @@ -214,13 +214,13 @@ translation_of: WebAssembly/Understanding_the_text_format
           i32.const 13
           call $log))
      -

      В инструкции импорта в модуль WebAssembly определено двухуровневое пространство имен, в котором мы указали импортировать функцию log из модуля console. Вы также можете видеть, что экспортируемая функция logIt вызывает импортированную функцию, используя инструкцию call, о которой мы говорили ранее.

      +

      В инструкции импорта в модуль WebAssembly определено двухуровневое пространство имён, в котором мы указали импортировать функцию log из модуля console. Вы также можете видеть, что экспортируемая функция logIt вызывает импортированную функцию, используя инструкцию call, о которой мы говорили ранее.

      Импортируемые функции аналогичны обычным функциям: они имеют сигнатуру, которую WebAssembly проверяет статически, им присваивается индекс (в место которого можно  присвоить имя) и их можно вызвать обычным способом.

      Функции JavaScript не имеют понятия сигнатуры, поэтому любую функцию JavaScript можно передать независимо от объявленной сигнатуры импорта. Если модуль объявляет импорт, вызывающая сторона (например метод {{jsxref("WebAssembly.instantiate()")}}) должна передать объект импорта, который должен иметь соответствующее свойство.

      -

      Для иллюстрации вышесказанного нам нужен объект (назовем его importObject), в котором  конечное свойство importObject.console.log должно содержать функцию JavaScript.

      +

      Для иллюстрации вышесказанного нам нужен объект (назовём его importObject), в котором  конечное свойство importObject.console.log должно содержать функцию JavaScript.

      Код будет выглядеть следующим образом:

      @@ -264,16 +264,16 @@ WebAssembly.instantiateStreaming(fetch('logger.wasm'), importObject)

      Память WebAssembly

      -

      Приведенный выше пример - довольно ужасная функция ведения журнала: она печатает только одно целое число! Что если мы хотим записать текстовую строку? Для работы со строками и другими более сложными типами данных WebAssembly предоставляет линейную память. Согласно технологии WebAssembly, линейная память - это просто большой массив байтов, который со временем может увеличиваться. WebAssembly код содержит ряд инструкций, наподобие i32.load и i32.store для чтения и записи значений из линейной памяти.

      +

      Приведённый выше пример - довольно ужасная функция ведения журнала: она печатает только одно целое число! Что если мы хотим записать текстовую строку? Для работы со строками и другими более сложными типами данных WebAssembly предоставляет линейную память. Согласно технологии WebAssembly, линейная память - это просто большой массив байтов, который со временем может увеличиваться. WebAssembly код содержит ряд инструкций, наподобие i32.load и i32.store для чтения и записи значений из линейной памяти.

      Со стороны JavaScript, линейная память как будто находится внутри одного большого (расширяющегося) объекта {{domxref("ArrayBuffer")}}.

      Таким образом, строка - это просто последовательность байтов где-то внутри этой линейной памяти. Давайте предположим, что мы записали нужную строку байтов в память; как мы передадим эту строку в JavaScript?
      Ключевым моментом является то, что JavaScript может создавать экземпляры(объекты) линейной памяти WebAssembly через конструктор {{jsxref("WebAssembly.Memory()")}} и получать доступ к существующему экземпляру памяти (в настоящее время вы можете иметь только один экземпляр памяти на экземпляр модуля), используя соответствующие методы экземпляра модуля. Экземпляр памяти имеет свойство buffer, которое возвращает объект ArrayBuffer, предоставляя всю линейную память модуля.

      -

      Объекты памяти могут расширятся с помощью метода Memory.grow() из JavaScript. Когда происходит расширение, текущий объект ArrayBuffer не может изменить размер и он отсоединяется. Вместо него создается новый объект ArrayBuffer, указывающий на новую, увеличенную память. Пользуясь этими возможностями можно передать строку в  JavaScript, её начальный индекс и её длину в линейной памяти.

      +

      Объекты памяти могут расширятся с помощью метода Memory.grow() из JavaScript. Когда происходит расширение, текущий объект ArrayBuffer не может изменить размер и он отсоединяется. Вместо него создаётся новый объект ArrayBuffer, указывающий на новую, увеличенную память. Пользуясь этими возможностями можно передать строку в  JavaScript, её начальный индекс и её длину в линейной памяти.

      -

      Хотя есть много разных способов кодировать длину строки в самой строке (например, как в строках в C); для простоты здесь мы просто передаем смещение и длину в качестве параметров:

      +

      Хотя есть много разных способов кодировать длину строки в самой строке (например, как в строках в C); для простоты здесь мы просто передаём смещение и длину в качестве параметров:

      (import "console" "log" (func $log (param i32) (param i32)))
      @@ -285,7 +285,7 @@ WebAssembly.instantiateStreaming(fetch('logger.wasm'), importObject) console.log(string); } -

      Последний недостающий фрагмент головоломки - это место, где функция consoleLogString получает доступ к памяти (memory) WebAssembly. WebAssembly дает нам здесь много гибкости: либо мы можем создать объект Memory в коде JavaScript и импортировать его в модуль WebAssembly, или мы можем создать его в модуле WebAssembly и затем экспортировать в  JavaScript.

      +

      Последний недостающий фрагмент головоломки - это место, где функция consoleLogString получает доступ к памяти (memory) WebAssembly. WebAssembly даёт нам здесь много гибкости: либо мы можем создать объект Memory в коде JavaScript и импортировать его в модуль WebAssembly, или мы можем создать его в модуле WebAssembly и затем экспортировать в  JavaScript.

      Для простоты, давайте создадим объект памяти в JavaScript и импортируем его в  WebAssembly модуль. Напишем следующее объявление импорта (import):

      @@ -329,7 +329,7 @@ WebAssembly.instantiateStreaming(fetch('logger2.wasm'), importObject)

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

      -

      Чтобы понять, зачем нужны таблицы, нам нужно сначала обратить внимание, что инструкция call, которую мы видели ранее (см. {{anch("Вызов функций из других функций в том же модуле")}}), принимает статический индекс функции и может вызывать только определенную функцию. Но что, если вызываемый элемент будет значением, установленным во время выполнения?

      +

      Чтобы понять, зачем нужны таблицы, нам нужно сначала обратить внимание, что инструкция call, которую мы видели ранее (см. {{anch("Вызов функций из других функций в том же модуле")}}), принимает статический индекс функции и может вызывать только определённую функцию. Но что, если вызываемый элемент будет значением, установленным во время выполнения?

      •     В JavaScript это делается постоянно: функции являются ссылочными значениями.
      • @@ -339,7 +339,7 @@ WebAssembly.instantiateStreaming(fetch('logger2.wasm'), importObject)

        Для того чтобы сделать это в WebAssembly нужен был отдельный тип инструкции вызова.  Поэтому мы создали инструкцию call_indirect, которая принимает операнд динамической функции. Проблема в том, что типы данных, которые мы должны использовать в операндах в WebAssembly, в настоящее время такие: i32 / i64 / f32 / f64.

        -

        Для WebAssembly можно было бы создать тип инструкции вызова  anyfunc («любой», потому что эта инструкция смогла вызвать функции любой сигнатуры), но, к сожалению, операнд этого типа не может быть сохранен в линейной памяти по соображениям безопасности. Линейная память представляет содержимое хранимых значений в виде незащищенных байтов, и это позволяет содержимому wasm произвольно читать и изменять незащищенные адреса функций, что недопустимо для веб.

        +

        Для WebAssembly можно было бы создать тип инструкции вызова  anyfunc («любой», потому что эта инструкция смогла вызвать функции любой сигнатуры), но, к сожалению, операнд этого типа не может быть сохранён в линейной памяти по соображениям безопасности. Линейная память представляет содержимое хранимых значений в виде незащищённых байтов, и это позволяет содержимому wasm произвольно читать и изменять незащищённые адреса функций, что недопустимо для веб.

        Решением стало следующее. Хранить ссылки на функции в таблице и передавать вместо них индексы таблицы, которые являются просто значениями i32. Поэтому операндом инструкции call_indirect может выступить простое значение индекса i32.

        @@ -413,7 +413,7 @@ WebAssembly.instantiateStreaming(fetch('logger2.wasm'), importObject)

        На языке высокого уровня, таком как JavaScript эти же действия вы можете представить в виде манипуляций с массивом (или, скорее, с объектом), содержащим функции. Псевдокод будет выглядеть примерно так: tbl[i]().

        -

        Итак, вернемся к проверке типов. Так как в коде WebAssembly проверяются типы, а атрибут anyfunc означает “сигнатура любой функции", мы должны предоставить предполагаемую сигнатуру в месте вызова, поэтому мы включаем тип с именем $return_i32, чтобы сообщить программе, что ожидается функция, возвращающая значение с типом i32. Если вызываемая функция не имеет соответствующей сигнатуры (скажем, вместо нее возвращается f32), выбросится исключение {{jsxref("WebAssembly.RuntimeError")}}.

        +

        Итак, вернёмся к проверке типов. Так как в коде WebAssembly проверяются типы, а атрибут anyfunc означает “сигнатура любой функции", мы должны предоставить предполагаемую сигнатуру в месте вызова, поэтому мы включаем тип с именем $return_i32, чтобы сообщить программе, что ожидается функция, возвращающая значение с типом i32. Если вызываемая функция не имеет соответствующей сигнатуры (скажем, вместо неё возвращается f32), выбросится исключение {{jsxref("WebAssembly.RuntimeError")}}.

        Так как инструкция call_indirect связывается с таблицей, с которой мы вызываем функцию? Ответ заключается в том, что на данный момент для каждого экземпляра модуля разрешена только одна таблица. Поэтому инструкция call_indirect выполняет неявный вызов именно из этой таблицы. В будущем, когда будет разрешено использование нескольких таблиц, нам нужно будет указать идентификатор таблицы, например так:

        @@ -453,7 +453,7 @@ WebAssembly.instantiateStreaming(fetch('logger2.wasm'), importObject)

        Изменяющиеся таблицы и динамическое связывание

        -

        Поскольку JavaScript имеет полный доступ к ссылкам на функции, объект таблицы может быть изменен из кода JavaScript с помощью методов grow(), get() и set(). Когда WebAssembly получит ссылочные типы, код WebAssembly сможет изменять таблицы самостоятельно с помощью инструкций get_elem / set_elem.

        +

        Поскольку JavaScript имеет полный доступ к ссылкам на функции, объект таблицы может быть изменён из кода JavaScript с помощью методов grow(), get() и set(). Когда WebAssembly получит ссылочные типы, код WebAssembly сможет изменять таблицы самостоятельно с помощью инструкций get_elem / set_elem.

        Поскольку таблицы являются изменяемыми, их можно использовать для реализации сложных схем динамического связывания во время загрузки и во время выполнения. Когда программа динамически связана, несколько экземпляров могут совместно использовать линейную память и таблицу ссылок. Это похоже на поведение в обычном приложении где несколько скомпилированных .dll совместно используют адресное пространство одного процесса.

        @@ -490,14 +490,14 @@ WebAssembly.instantiateStreaming(fetch('logger2.wasm'), importObject)
        1. Функция shared0func определена в shared0.wat и сохраняется в нашей импортированной таблице.
        2. -
        3. Эта функция создает константу, содержащую значение 0, затем инструкция i32.load получает значение из импортированной памяти по предоставленному константой индексу. Предоставленный  индекс равен 0. Как и другие подобные инструкции, i32.load неявно получает предоставленное значение из стека. Итак, shared0func загружает и возвращает значение, хранящееся в индексе памяти 0.
        4. +
        5. Эта функция создаёт константу, содержащую значение 0, затем инструкция i32.load получает значение из импортированной памяти по предоставленному константой индексу. Предоставленный  индекс равен 0. Как и другие подобные инструкции, i32.load неявно получает предоставленное значение из стека. Итак, shared0func загружает и возвращает значение, хранящееся в индексе памяти 0.
        6. В shared1.wat мы экспортируем функцию с именем doIt - эта функция размещает в стеке  две константы, содержащие значения 0 и 42. Затем она вызывает инструкцию i32.store для сохранения предоставленного значения по предоставленному индексу в импортированной памяти. Опять же, инструкция неявно получает эти значения из стека. Поэтому в результате doIt сохраняет значение 42 в индексе памяти 0.
        7. -
        8. В последней части функции создается константа со значением 0, затем вызывается  функция с этим индексом (0) из таблицы. Это будет функция shared0func модуля shared0.wat, которая ранее была размещена там с помощью секции elem.
        9. +
        10. В последней части функции создаётся константа со значением 0, затем вызывается  функция с этим индексом (0) из таблицы. Это будет функция shared0func модуля shared0.wat, которая ранее была размещена там с помощью секции elem.
        11. При вызове shared0func загружает число 42, которые мы сохранили в памяти, с помощью ранее указанной инструкции i32.store в модуле shared1.wat.
        -

        Примечание: Вышеприведенные выражения неявно извлекают значения из стека, но вместо этого вы можете объявить их явно в вызовах инструкций, например:

        +

        Примечание: Вышеприведённые выражения неявно извлекают значения из стека, но вместо этого вы можете объявить их явно в вызовах инструкций, например:

        (i32.store (i32.const 0) (i32.const 42))
         (call_indirect (type $void_to_i32) (i32.const 0))
        diff --git a/files/ru/webassembly/using_the_javascript_api/index.html b/files/ru/webassembly/using_the_javascript_api/index.html index 21a38cbbc4..ecc973376c 100644 --- a/files/ru/webassembly/using_the_javascript_api/index.html +++ b/files/ru/webassembly/using_the_javascript_api/index.html @@ -9,7 +9,7 @@ translation_of: WebAssembly/Using_the_JavaScript_API ---
        {{WebAssemblySidebar}}
        -

        Если вы уже компилировали модуль из другого языка, используя такие инструменты как Emscripten, или загружали и запускали код, то следующим шагом будет углубленное изучение возможностей WebAssembly JavaScript API. Эта статья даст необходимые знания по этому вопросу.

        +

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

        Примечание: Если вы незнакомы с фундаментальными понятиями, упомянутыми в этой статье, и вам нужны дополнительные объяснения, то вам нужно сначала прочитать про Основы WebAssembly.

        @@ -26,8 +26,8 @@ translation_of: WebAssembly/Using_the_JavaScript_API

        Подготовка примера

          -
        1. Для начала нам нужен wasm-модуль! Возьмите наш файл simple.wasm и сохраните копию в новой директории на своем локальном компьютере.
        2. -
        3. Далее, давайте создадим в той же директории что и wasm-модуль простой HTML-файл и назовем его index.html (можно использовать HTML шаблон если вы этого еще не сделали).
        4. +
        5. Для начала нам нужен wasm-модуль! Возьмите наш файл simple.wasm и сохраните копию в новой директории на своём локальном компьютере.
        6. +
        7. Далее, давайте создадим в той же директории что и wasm-модуль простой HTML-файл и назовём его index.html (можно использовать HTML шаблон если вы этого ещё не сделали).
        8. Теперь, для того чтобы понять что происходит в коде модуля, давайте взглянем на его текстовое представление (которое мы также встречали в Перевод из текстового формата WebAssembly в wasm):
          (module
             (func $i (import "imports" "imported_func") (param i32))
          @@ -35,7 +35,7 @@ translation_of: WebAssembly/Using_the_JavaScript_API
               i32.const 42
               call $i))
        9. -
        10. Во второй строчке вы видите что import имеет двухуровневое пространство имен - внутренняя функция $i импортирована из imports.imported_func. Нам нужно создать это двухуровневое пространство имен в JavaScript-объекте, который будет импортирован в wasm-модуль. Создайте <script></script> элемент в своем HTML-файле, и добавьте следующий код: +
        11. Во второй строчке вы видите что import имеет двухуровневое пространство имён - внутренняя функция $i импортирована из imports.imported_func. Нам нужно создать это двухуровневое пространство имён в JavaScript-объекте, который будет импортирован в wasm-модуль. Создайте <script></script> элемент в своём HTML-файле, и добавьте следующий код:
          var importObject = {
             imports: { imported_func: arg => console.log(arg) }
           };
          @@ -77,7 +77,7 @@ translation_of: WebAssembly/Using_the_JavaScript_API

          Просмотр wasm в инструментах разработчика

          -

          В Firefox 54+, в отладочной панели инструментов разработчика имеется возможность отображения текстового представления любого wasm-кода, включенного в веб-страницу. Для того чтобы просмотреть его, вы можете перейти на отладочную панель и нажать на пункт "wasm://".

          +

          В Firefox 54+, в отладочной панели инструментов разработчика имеется возможность отображения текстового представления любого wasm-кода, включённого в веб-страницу. Для того чтобы просмотреть его, вы можете перейти на отладочную панель и нажать на пункт "wasm://".

          @@ -93,7 +93,7 @@ translation_of: WebAssembly/Using_the_JavaScript_API

          Давайте исследуем эту возможность рассмотрев небольшой пример.

          -

          Создайте еще одну простую HTML страницу (скопируйте HTML шаблон) и назовите её memory.html. Добавьте <script></script> элемент на страницу.

          +

          Создайте ещё одну простую HTML страницу (скопируйте HTML шаблон) и назовите её memory.html. Добавьте <script></script> элемент на страницу.

          1. @@ -125,7 +125,7 @@ translation_of: WebAssembly/Using_the_JavaScript_API

            При превышении максимального значения, указанного при создании объекта памяти, будет выброшено исключение {{jsxref("WebAssembly.RangeError")}}. Движок использует предоставленные верхние границы для резервирования памяти заранее, что делает расширение памяти более эффективным.

            -

            Примечание: Так как размер объекта {{domxref("ArrayBuffer")}} неизменен, после успешного вызова метода {{jsxref("Memory.prototype.grow()")}} свойство buffer объекта памяти будет возвращать уже новый объект {{domxref("ArrayBuffer")}} (с новым размером в свойстве byteLength) и любые предыдущие объекты ArrayBuffer станут в некотором роде “отсоединенными”, или отключенными от низкоуровневой памяти, к которой они ранее относились.

            +

            Примечание: Так как размер объекта {{domxref("ArrayBuffer")}} неизменен, после успешного вызова метода {{jsxref("Memory.prototype.grow()")}} свойство buffer объекта памяти будет возвращать уже новый объект {{domxref("ArrayBuffer")}} (с новым размером в свойстве byteLength) и любые предыдущие объекты ArrayBuffer станут в некотором роде “отсоединёнными”, или отключёнными от низкоуровневой памяти, к которой они ранее относились.

            Подобно функциям, диапазоны линейной памяти могут быть импортированы или определены внутри модуля. Также, модуль имеет возможность экспортировать свою память. Это означает, что JavaScript-код может получить доступ к объекту памяти WebAssembly либо c помощью создания нового объекта через конструктор WebAssembly.Memory и передачи его в импортируемый объект, либо с помощью получения объекта памяти через экспортируемый объект (через Instance.prototype.exports).

            @@ -151,7 +151,7 @@ translation_of: WebAssembly/Using_the_JavaScript_API });
          2. -

            Так как модуль экспортирует свою память, которая была передана экземпляру этого модуля при его создании, мы можем наполнить ранее импортированный массив прямо в линейной памяти экземпляра модуля (mem), и вызвать экспортированную функцию accumulate() для расчета суммы значений. Добавьте следующий код, в обозначенном месте: 

            +

            Так как модуль экспортирует свою память, которая была передана экземпляру этого модуля при его создании, мы можем наполнить ранее импортированный массив прямо в линейной памяти экземпляра модуля (mem), и вызвать экспортированную функцию accumulate() для расчёта суммы значений. Добавьте следующий код, в обозначенном месте: 

            var i32 = new Uint32Array(memory.buffer);
             
            @@ -164,7 +164,7 @@ console.log(sum);
          -

          Обратите внимание на то, что мы создаем представление данных {{domxref("Uint32Array")}} с помощью свойства buffer объекта памяти (Memory.prototype.buffer), а не самого объекта памяти.

          +

          Обратите внимание на то, что мы создаём представление данных {{domxref("Uint32Array")}} с помощью свойства buffer объекта памяти (Memory.prototype.buffer), а не самого объекта памяти.

          Импорт памяти почти такой же как импорт функций, только вместо JavaScript функций передаются объекты памяти. Импорт памяти полезен по двум причинам:

          @@ -174,14 +174,14 @@ console.log(sum);
      -

      Примечание: Вы можете найти полную демонстрацию в файле memory.html (см. ее также вживую) — эта версия использует функцию fetchAndInstantiate().

      +

      Примечание: Вы можете найти полную демонстрацию в файле memory.html (см. её также вживую) — эта версия использует функцию fetchAndInstantiate().

      Таблицы

      -

      Таблица WebAssembly - это расширяемый типизированный массив ссылок, доступ к которому может быть получен из JavaScript и WebAssembly кода. Так как линейная память предоставляет расширяемый массив незащищенных байт, слишком небезопасно размещать там ссылки, так как для движка ссылка является доверенным значением, чьи байты не должны быть прочитаны или записаны кодом напрямую по причинам безопасности, переносимости и стабильности.

      +

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

      -

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

      +

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

      Ссылки на функции необходимы для компиляции в таких языках как C/C++, которые имеют указатели на функции. В родной реализации C/C++, указатель на функцию представлен прямым адресом на код функции в виртуальном адресном пространстве процесса, и потому для ранее упомянутой безопасности, они не могут быть размещены прямо в линейной памяти. Вместо этого ссылки на функции размещаются в таблице, а её индексы, которые являются целыми числами могут быть размещены в линейной памяти и переданы куда угодно.

      @@ -191,7 +191,7 @@ console.log(sum);

      Пример таблицы

      -

      Давайте взглянем на простой пример таблицы - модуль WebAssembly, который создает и экспортирует таблицу с двумя элементами: элемент под индексом 0 возвращает 13, а элемент под индексом 1 возвращает 42.

      +

      Давайте взглянем на простой пример таблицы - модуль WebAssembly, который создаёт и экспортирует таблицу с двумя элементами: элемент под индексом 0 возвращает 13, а элемент под индексом 1 возвращает 42.

      1. @@ -224,7 +224,7 @@ console.log(tbl.get(1)());  // 42

        Этот код получает доступ к каждой ссылке на функцию, которая размещена в таблице, после чего вызывает её и выводит хранимое значение в консоль. Обратите внимание, что каждая ссылка на функцию получена с помощью вызова метода Table.prototype.get(), после чего мы добавили пару круглых скобок для вызова самой функции.

        -

        Примечание: Вы можете найти нашу полную демонстрацию в файле table.html (см. ее также вживую) — эта версия использует функцию fetchAndInstantiate().

        +

        Примечание: Вы можете найти нашу полную демонстрацию в файле table.html (см. её также вживую) — эта версия использует функцию fetchAndInstantiate().

        Глобальные переменные

        -- cgit v1.2.3-54-g00ecf