Я хочу создать виртуальную машину, есть ли хорошие ссылки? [закрыто]

22

Я рассчитываю создать виртуальную машину как независимый от платформы способ запуска некоторого игрового кода (по сути, скриптов).

Виртуальные машины, о которых я знаю в играх, довольно старые: Z-Machine от Infocom , SCUMM от LucasArts , Quake 3 от id Software . Как разработчик .net, я знаком с CLR и изучил инструкции CIL, чтобы получить представление о том, что вы на самом деле реализуете на уровне виртуальной машины (по сравнению с языковым уровнем). В прошлом году я также немного поиграл в 6502 Ассемблере .

Дело в том, что теперь, когда я хочу… реализовать это, мне нужно копнуть немного глубже. Я знаю, что существуют виртуальные машины на основе стеков и регистров, но я не знаю, какая из них лучше в чем, и есть ли более или гибридные подходы. Мне нужно разобраться с управлением памятью, решить, какие типы низкого уровня являются частью ВМ, и мне нужно понять, почему такие вещи, как ldstr, работают так, как работают .

Мой единственный справочник (кроме материала по Z-Machine) - это Аннотированный стандарт CLI , но мне интересно, есть ли лучшая, более общая / фундаментальная лекция для виртуальных машин? В основном что-то вроде Книги Дракона , но для ВМ? Мне известно об искусстве компьютерного программирования Дональда Кнута, в котором используется виртуальная машина на основе регистров, но я не уверен, насколько эта серия применима, тем более что она еще не закончена?

Пояснение: цель заключается в создании специализированной виртуальной машины. Например, Z-Machine Infocom содержит коды операций для установки цвета фона или воспроизведения звука. Поэтому мне нужно выяснить, сколько идет на виртуальную машину в виде OpCodes по сравнению с компилятором, который берет скрипт (язык TBD) и генерирует из него байт-код, но для этого мне нужно понять, что я действительно делаю.


¹ Я знаю, что современные технологии позволили бы мне просто интерпретировать язык сценариев высокого уровня на лету. Но где в этом веселье? :) Гуглить тоже немного сложно, потому что виртуальные машины в наше время часто ассоциируются с виртуализацией ОС типа VMWare ...

Майкл Стум
источник
6
обратите внимание, что для машины, основанной на стеке, для завершения тьюринга ей нужна память вне стека, в противном случае это просто КПК
трещотка
1
Первый вопрос: как далеко вы хотите пойти? Я никогда не смотрел на SCUMM / SCUMMVM, но предполагаю, что это достаточно высокий уровень знаний о графических вещах, движущихся вокруг и т. Д. В то время как CIL ... так что вы должны определить свою модель памяти (основанную на стеке на основе регистров, смесь, беспорядок, ...) и коды операций ( то есть инструкции ассемблера), а затем первая версия виртуальной машины - это цикл, do { switch(opcode) {case OP1: ... case OP2: ...} while (nextop);затем, может быть, компилятор ... и тогда начинается самое интересное - оптимизация, чтобы заставить его работать на самом деле
Johannes
3
Попробуйте начать с реализации простой среды выполнения Forth.
SK-logic
1
Как именно Quake 3виртуальная машина?
Ramhound
3
@ Разыщите движки id tech уже давно используют некоторую форму внутренней виртуализации, эта статья или информация из Википедии могут объяснить лучше.
Даниэль Б

Ответы:

18

Я бы начал с проверки Луа . И как пример реализации, и как очень полезная виртуальная машина / язык из коробки, если вы наконец решите не использовать свой собственный.

Исходный код очень удобочитаемый, и есть также аннотированный исходный код . И некоторые конструкторские документы написаны главным автором, Роберто Иерусалимским.

Наконец, если вы решите использовать его вместо своего собственного, вы обнаружите, что он долгое время был любимым среди разработчиков игр, и есть реализация JIT с очень высокой производительностью .

Что касается стеков против регистров, я думаю, что стековые виртуальные машины проще проектировать, но компилятор может быть более сложным. Как отмечает Iesualimschy, Lua была одной из первых языковых виртуальных машин на основе регистров, но впоследствии появилось несколько других, в частности LLVM, Dalvik и некоторые современные виртуальные машины JavaScript.

Хавьер
источник
2
О стеках против машин с регистрами: я помню цитату из разработчиков Parrot / Perl6: «Построить машину на основе регистров сложнее, но мы получаем пользу от множества существующих исследований для нашей стороны компилятора» (не буквально)
Йоханнес
+1 Lua имеет отличную реализацию байт-кода и очень чистый дизайн для изучения виртуальных машин. Кроме того, вы обнаружите, что многие люди настроили Lua для своих нужд, демонстрируя, что он может быть достаточно расширяемым, если вы не хотите начинать с нуля.
CodexArcanum
Все еще переживаю это. Еще один замечательный документ от разработчика о виртуальной машине
Майкл
2

У меня нет конкретных ресурсов, чтобы связать вас с вами в данный момент, но я исследовал похожую тему в прошлом и обнаружил, что Smalltalk VM также является хорошим учебным пособием. Есть много научных статей и статей, написанных о байт-кодах, используемых Smalltalk, а также о написании интерпретаторов и виртуальных машин для использования этого байт-кода. Поиск в Google smalltalk vm implementationили smalltalk bytecode interpreterдолжен дать много материалов для чтения.

Если вы хотите увидеть некоторый исходный код или попробовать реализацию, я рекомендую либо версии Squeak, либо Pharo.

Родственный язык / VM Self также может вас заинтересовать, поскольку Self - это, в основном, Smalltalk с объектами на основе прототипов (аналогично JavaScript).

CodexArcanum
источник
0

Я бы начал с анализа того, как исходный код [script] попадает в вашу машину или среду выполнения.

Если у вас есть что-то похожее на HTML-документы, <a onclick="dosomething();">вам понадобится очень быстрый компилятор, скорость выполнения байт-кода в данном случае не имеет большого значения. Если ваши варианты использования ближе к Java / .NET, где вы можете позволить себе полноценную компиляцию, тогда архитектура VM и структура байт-кода будут ближе к байт-кодам Java или IL.

Другим критерием является то, что я называю «клейкостью». Первоначально сценарии разрабатывались как склеенные языки - сценарии просто определяют способ соединения различных нативных функций (Perl, Python, Ruby, JS). В этом случае эффективность ВМ и байт-кода гораздо менее критична, чем в случае Java / .NET, когда большая часть вашего кода является функциями, написанными на самом языке.

И последний важный критерий, который я бы использовал, - это расширяемость вашего языка. Если вы планируете добавить в среду выполнения много собственных объектов / функций, реализованных, например, в C ++, тогда ваша архитектура виртуальной машины должна быть «удобной» для интеграции с C ++. Например: если вы планируете выставлять в сценарии объекты C ++ такими, какие они есть, то единственной возможностью для вас будет подсчет ссылок в качестве управления кучей (например, Python, см. Boost :: python в качестве примера интеграции). Если вы планируете использовать перемещение / сжатие кучи / GC, то это будет другая история. Способ Lua по добавлению нативных вещей в среду выполнения немного сложен [для разработчиков на C ++].

Другими словами, попробуйте сначала определить типичный вариант использования, и вам будет легче предложить, что читать для вас.

с-улыбка
источник
1
Современные JavaScript-компиляторы довольно сложны, и вопрос всегда в том, сколько оптимизации вы вложили в сгенерированный код.
Johannes
Производительность исполнения Javascript имеет значение. Не для маленьких скриптов, а для больших JS-сайтов, которые, к лучшему или худшему, составляют значительную часть более популярных сайтов. Есть причина, по которой движки JS используют JIT-компиляторы (у V8 даже нет интерпретатора, он идет прямо к машинному коду).
@delnan: сценарий использования JS сильно отличается от, скажем, Python. В Python, когда вам нужно что-то вроде реализации алгоритма трассировки лучей, вы создадите нативную библиотеку и вызовете ее из скрипта. Это всегда будет быстрее (или, по крайней мере, не медленнее), чем любое решение JIT. В JS-сфере у вас нет такой роскоши, как нативный код, поэтому единственный вариант для вас - попытаться сделать вашу JS-VM максимально быстрой. Но опять же, с ценой. Оценка "dosomethingnative ()" в HTML "<button onclick =" dosomethingnative () "> в простом интерпретаторе может быть на порядки быстрее, чем в V8.
c-smile
@ c-smile Моя точка зрения точно.
@delnan: но моя точка зрения совершенно иная: проанализируйте общие случаи использования, и только тогда вы сможете решить, какая архитектура ВМ, синтаксис языка и т. д. вам понадобится.
c-smile