Я рассчитываю создать виртуальную машину как независимый от платформы способ запуска некоторого игрового кода (по сути, скриптов).
Виртуальные машины, о которых я знаю в играх, довольно старые: Z-Machine от Infocom , SCUMM от LucasArts , Quake 3 от id Software . Как разработчик .net, я знаком с CLR и изучил инструкции CIL, чтобы получить представление о том, что вы на самом деле реализуете на уровне виртуальной машины (по сравнению с языковым уровнем). В прошлом году я также немного поиграл в 6502 Ассемблере .
Дело в том, что теперь, когда я хочу… реализовать это, мне нужно копнуть немного глубже. Я знаю, что существуют виртуальные машины на основе стеков и регистров, но я не знаю, какая из них лучше в чем, и есть ли более или гибридные подходы. Мне нужно разобраться с управлением памятью, решить, какие типы низкого уровня являются частью ВМ, и мне нужно понять, почему такие вещи, как ldstr, работают так, как работают .
Мой единственный справочник (кроме материала по Z-Machine) - это Аннотированный стандарт CLI , но мне интересно, есть ли лучшая, более общая / фундаментальная лекция для виртуальных машин? В основном что-то вроде Книги Дракона , но для ВМ? Мне известно об искусстве компьютерного программирования Дональда Кнута, в котором используется виртуальная машина на основе регистров, но я не уверен, насколько эта серия применима, тем более что она еще не закончена?
Пояснение: цель заключается в создании специализированной виртуальной машины. Например, Z-Machine Infocom содержит коды операций для установки цвета фона или воспроизведения звука. Поэтому мне нужно выяснить, сколько идет на виртуальную машину в виде OpCodes по сравнению с компилятором, который берет скрипт (язык TBD) и генерирует из него байт-код, но для этого мне нужно понять, что я действительно делаю.
¹ Я знаю, что современные технологии позволили бы мне просто интерпретировать язык сценариев высокого уровня на лету. Но где в этом веселье? :) Гуглить тоже немного сложно, потому что виртуальные машины в наше время часто ассоциируются с виртуализацией ОС типа VMWare ...
источник
do { switch(opcode) {case OP1: ... case OP2: ...} while (nextop);
затем, может быть, компилятор ... и тогда начинается самое интересное - оптимизация, чтобы заставить его работать на самом делеQuake 3
виртуальная машина?Ответы:
Я бы начал с проверки Луа . И как пример реализации, и как очень полезная виртуальная машина / язык из коробки, если вы наконец решите не использовать свой собственный.
Исходный код очень удобочитаемый, и есть также аннотированный исходный код . И некоторые конструкторские документы написаны главным автором, Роберто Иерусалимским.
Наконец, если вы решите использовать его вместо своего собственного, вы обнаружите, что он долгое время был любимым среди разработчиков игр, и есть реализация JIT с очень высокой производительностью .
Что касается стеков против регистров, я думаю, что стековые виртуальные машины проще проектировать, но компилятор может быть более сложным. Как отмечает Iesualimschy, Lua была одной из первых языковых виртуальных машин на основе регистров, но впоследствии появилось несколько других, в частности LLVM, Dalvik и некоторые современные виртуальные машины JavaScript.
источник
У меня нет конкретных ресурсов, чтобы связать вас с вами в данный момент, но я исследовал похожую тему в прошлом и обнаружил, что Smalltalk VM также является хорошим учебным пособием. Есть много научных статей и статей, написанных о байт-кодах, используемых Smalltalk, а также о написании интерпретаторов и виртуальных машин для использования этого байт-кода. Поиск в Google
smalltalk vm implementation
илиsmalltalk bytecode interpreter
должен дать много материалов для чтения.Если вы хотите увидеть некоторый исходный код или попробовать реализацию, я рекомендую либо версии Squeak, либо Pharo.
Родственный язык / VM Self также может вас заинтересовать, поскольку Self - это, в основном, Smalltalk с объектами на основе прототипов (аналогично JavaScript).
источник
Я бы начал с анализа того, как исходный код [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 ++].
Другими словами, попробуйте сначала определить типичный вариант использования, и вам будет легче предложить, что читать для вас.
источник