169 похожих чатов

Я тут подумал что wasm с пропозалом GC и всякими

mult-value, reference+function types, exception-handling, stack-switching, etc становится все больше и больше похожим на высокоуровневый язык программирования и пришла идея искуственно ограничить функционал чтобы почувствовать все "удовольствие" от написания компилятора и в итоге получился такой список
1) запрет новых расширений (gc, mult-value, reference+function types, exception-handling, etc)
2) запрет на использование глобальных переменных (global.get, global.set) - вместо этого используем память
3) запрет на использование инструкций if-else - вместо этого используем block + br_if
4) запрет на использование инструкций call/call_indirect/return и функций - вместо этого компилируем всю программу в одну большую main-функцию а наши семантические функции компилируем в набор блоков (вложенный список block block block ..) на которые будет прыжок инструкцией br_table (ну и еще дополнительный loop сверху) ну и также вручную ментейним стек в памяти
5) запрещаем использование стека для построения дерева вычислений - то есть используем стек только для выполнения нативных инструкции (то есть размер стека в любой точки программы должен быть 2 или 1 или 3 в зависимости от количества операндов следующей инструкции) а все промежуточные результаты храним в локальных переменных (то есть постоянно загружаем и наоборот сбрасываем туда результат после выполнения каждой wasm-инструкции)
6) ограничиваем количество локальных переменных примерно 16 штуками ну а поскольку у нас будет одна функция на всю программу и будет запрет на использование глобальных переменных - то это максимальное число переменных где мы можем хранить результат промежуточных вычислений а если нужно больше то используем память (и дальше приходим к идее анализа лайфтайма переменных и запись/чтения из памяти как можно реже)
Что думаете?

14 ответов

49 просмотров

Это всё чтобы «получить удовольствие»?)

Богдан- Автор вопроса
Vladimir Gordeev
Это всё чтобы «получить удовольствие»?)

Не только, можно еще сказать что после того как напишешь wasm-компилятор какого-то языка со всеми этими ограничения то дальше добавления в компилятор кодгена для других процессорных архитектур вроде x64 и Arm будет либо тривиальной либо на порядки более простой задачей чем когда wasm-компилятор разрабатывался бы без этих ограничений

может стоит просто начать, получить хотя бы что-то рабочее, а потом уже двигаться в определенном направлении?

Богдан- Автор вопроса

Кароче, я понял зачем это нужно и всерьез планирую написать wasm-компилятор со всеми этими ограничениями. Все эти ограничения мне нужны для реализации одной киллер-фичи (про которую я не слышал ни в одном языке который компилируется в wasm) - дебаг изнутри браузера. Представьте себе типичную песочницу (например codesandbox.io) где юзеры могут набирать в браузерном редакторе код (например todo-app демки) а справа видят iframe с результатом. Так вот, киллер-фича про которую я не слышал ни в одном wasm-языке (и даже в JS экосистеме) - это возможность дебага внутри этого браузерного веб-редактора не открывая девтулзы (то есть возможность поставить брекпоинт и дальше остановиться на нем и инспектировать локальные переменные, результат временных выражений, память, объекты и т.д) И главное - пока выполнение не дошло до строчки где стоит брейкпоинт то этот код должен выполняться со скоростью оптимизированного бинарника (а то иначе можно представить такой дебаг в браузере который будет работать через интерпретацию кода а это слишком медленно)

Богдан
Кароче, я понял зачем это нужно и всерьез планирую...

.NET так делает. Они просто весь свой рантайм в MVP скомпилировали и получили дебаг из коробки

Богдан- Автор вопроса
Ilya Rezvov
.NET так делает. Они просто весь свой рантайм в MV...

а разве там дебаг не через интерпретацию в виртуальной машине работает?

Богдан
а разве там дебаг не через интерпретацию в виртуал...

Ну да. Я же говорю, они рантайм весь тащат вместе с вм

Богдан- Автор вопроса
Ilya Rezvov
Ну да. Я же говорю, они рантайм весь тащат вместе ...

Тогда это не то. У меня есть идея как это может работать без рантайма и без падения производительности. То есть чтобы дебаг-режим (пока выполнение не дошло до строчки с брекпоинтом) работал со скоростью обычного скомпилированного в wasm кода как в языках С++ и Rust но чтобы дебажить этот код можно было изнутри редактора в браузере без открытия браузерных devtools

Богдан
Тогда это не то. У меня есть идея как это может ра...

Если бы ещё "switch в цикле" работал без падения произволительности, ага... 😏

а как ты собираешься остановить выполнение кода когда он встретит брейкпоинт?

Богдан- Автор вопроса
Alexander Chichigin
Если бы ещё "switch в цикле" работал без падения п...

И насколько это медленее? Есть ли где-то замеры? По сути вместо вызова функции там будет установка константы в локальную переменную и после этого прыжок (например br 123) на заголовок цикл где будет br_table(get_local(0)) и предполагаю что после инлайна этого заголовка и прогона оптимизаций ассемблерный выхлоп в том же x64 сведется к одной и той же инструкции индирект джапа. То есть это медленнее конечно чем прямой джамп но по идее должен быть паритет с инструкцией call_indirect. Более того мне я слышал что есть какие-то оптимизации (вроде jump threading) которые вообще могут проанализировать зависимость пути выполнения по значению из локальной переменной (которое устанавливается в другом блоке) и в итоге раскрутить и заменить косвенный джамп на прямой. В любом случае других альтернатив этому подходу нет - если мы хотим дебажить код изнутри веб-страницы (не открывая девтулзы) то так или иначе придется заменить встроенный wasm-стек на собственный

Богдан
И насколько это медленее? Есть ли где-то замеры? П...

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

Богдан- Автор вопроса
cevek
а как ты собираешься остановить выполнение кода ко...

Там будет прыжок на блок который дампит локальные переменные память а после этого делает unreachable или return. Куда более интересный вопрос - как устанавливать брекпоинты и как потом продолжить выполнение

Богдан- Автор вопроса
Alexander Chichigin
На достаточно медленнее чтобы авторы интерпретатор...

Но ведь у меня не интерпретатор. У меня будет обычный wasm код просто со списком этих ограничений - https://t.me/WebAssembly_ru/52284 Там не будет switch-а с каждой строчкой/выражением/оператора как в интерпретаторах. Весь локальный код внутри функции будет выполняться как обычный скомпилировванный в wasm-код а switch-прыжки будут только в случае вызова других функции (но и то есть подозрения что после инлайна хедера цикла и прогона jump-threading оптимизации оверхед от этих прыжков будет минимальным)

Похожие вопросы

Обсуждают сегодня

Ребят в СИ можно реализовать ООП?
Николай
33
~ 2m21s  nix shell github:nixos/nixpkgs#stack ~  stack ghc -- --version error: … while calling the 'derivationStrict' builtin at /builtin/derivation.nix:...
Rebuild your mind.
6
Добрый вечер, Пока не совсем понимаю как наладить общение между телеграм ботом и ПО для работы с сим боксом. По самому боту так понял: - Нужен некий баланс, который можно поп...
Magic
6
Всем доброго вечера. Разрабатываю 32 раз. приложение в Delphi. Столкнулся с тем, что стандартный  TFilestream  не работает с большим файлом > 2 ГБайт (после вызова функции see...
Vadim Gl
16
Всем привет! Имеется функция: function IsValidChar(ch: UTF8Char): Boolean; var i: Integer; ValidChars: AnsiString; begin ValidChars := 'abcdefghijklmnopqrstuvwxyzABCDE...
Евгений
44
добрый день. Подскажите, есть сайт на 1.4.7 и я хочу обновиться, особо ничего не меняя. мне выбирать версию 1.4.35 или третью ветку? и можно ли обновлять "как есть", или нужно...
Digital Cat
12
Кто кодит под Лазарем на винде, у вас аналогично VCL переопределяются CreateWnd и CreateParams для конкретных классов контролов и все заданные флаги влияют?
А Андрей
11
У меня задача: написать брокер сообщений. Очереди и потребители. Очереди поддерживают приоритеты. Очередь отдает сообщения, только обработчикам с соответствующими характеристи...
Aleksandr Filippov
2
народ, плиз хелп, всю голову сломал себе уже... разве может быть так, что GetProcAddress( GetModuleHandle( "kernel32.dll" ), "SetThreadDescription" ) вернёт ненулевое значение...
Iluha Companets
12
А, ты про текущую реализацию? Нет конечно, я бы сделал правильно - сейчас там гавнокод
Александр (Rouse_) Багель
6
Карта сайта