Saya ingin membangun Mesin Virtual sebagai cara mandiri platform untuk menjalankan beberapa kode game (pada dasarnya skrip).
Mesin Virtual yang saya sadari dalam game agak lama: Infocom's Z-Machine , LucasArts ' SCUMM , id Software's Quake 3 . Sebagai Pengembang .net, aku akrab dengan CLR dan melihat ke dalam Instruksi CIL untuk mendapatkan gambaran tentang apa yang sebenarnya Anda menerapkan pada Tingkat VM (vs tingkat bahasa). Saya juga mencoba-coba sedikit di 6502 Assembler selama tahun lalu.
Masalahnya adalah, sekarang saya ingin¹ menerapkannya, saya perlu menggali sedikit lebih dalam. Saya tahu bahwa ada VM berbasis stack dan register, tapi saya tidak benar-benar tahu mana yang lebih baik dalam hal apa dan jika ada lebih banyak atau pendekatan hybrid. Saya perlu berurusan dengan manajemen memori, memutuskan jenis level rendah mana yang merupakan bagian dari VM dan perlu memahami mengapa hal-hal seperti ldstr bekerja seperti itu.
Satu-satunya buku referensi saya (terlepas dari hal-hal Z-Machine) adalah CLI Annotated Standard , tapi saya ingin tahu apakah ada kuliah yang lebih baik, lebih umum / mendasar untuk VM? Pada dasarnya sesuatu seperti Buku Naga , tetapi untuk VM? Saya mengetahui Seni Pemrograman Komputer Donald Knuth yang menggunakan VM berbasis register, tapi saya tidak yakin seberapa berlaku seri itu, terutama karena masih belum selesai?
Klarifikasi: Tujuannya adalah untuk membangun VM khusus. Sebagai contoh, Mesin Z Infocom berisi Opcode untuk mengatur Warna Latar Belakang atau memainkan suara. Jadi saya perlu mencari tahu berapa banyak masuk ke VM sebagai OpCodes vs kompiler yang mengambil skrip (bahasa TBD) dan menghasilkan bytecode dari itu, tetapi untuk itu saya perlu memahami apa yang sebenarnya saya lakukan.
¹ Saya tahu, teknologi modern akan memungkinkan saya untuk hanya menafsirkan bahasa scripting tingkat tinggi dengan cepat. Tapi di mana kesenangannya? :) Ini juga agak sulit untuk google karena Mesin Virtual saat ini sering dikaitkan dengan VMWare-type OS Virtualization ...
sumber
do { switch(opcode) {case OP1: ... case OP2: ...} while (nextop);
kemudian mungkin kompiler ... dan kemudian kesenangan dimulai - optimasi untuk membuatnya benar-benar berfungsiQuake 3
mesin virtual?Jawaban:
Saya akan mulai dengan memeriksa Lua . Baik sebagai implementasi sampel, dan sebagai VM / bahasa yang sangat berguna di luar kotak jika Anda akhirnya memutuskan untuk tidak meluncurkan sendiri.
Kode sumber sangat mudah dibaca, dan ada juga kode sumber Beranotasi . Dan beberapa dokumen Desain ditulis oleh penulis utama, Roberto Ierusalimschy.
Akhirnya, jika Anda memilih untuk menggunakannya daripada milik Anda sendiri, Anda akan menemukan bahwa itu sudah lama menjadi favorit di antara para pengembang game, dan ada implementasi JIT berkinerja sangat tinggi .
Tentang stack-vs register-based, saya pikir VM berbasis stack lebih mudah untuk dirancang, tetapi kompilernya bisa lebih kompleks. Seperti yang dicatat oleh makalah Iesualimschy, Lua adalah salah satu VM bahasa berbasis register pertama, tetapi setelah itu beberapa yang lain telah tumbuh, terutama LLVM, Dalvik, dan beberapa VM JavaScript modern.
sumber
Saya tidak memiliki sumber daya khusus untuk menghubungkan Anda saat ini, tetapi saya telah meneliti topik yang sama di masa lalu dan menemukan Smalltalk VM sebagai alat bantu belajar yang baik juga. Ada banyak makalah akademik dan artikel yang ditulis tentang kode byte yang digunakan oleh Smalltalk, serta menulis interpreter dan VM untuk menggunakan bytecode itu. Pencarian Google untuk
smalltalk vm implementation
atausmalltalk bytecode interpreter
harus menghasilkan banyak bahan bacaan.Jika Anda ingin melihat beberapa kode sumber atau mencoba implementasi, saya sarankan versi Squeak atau Pharo.
Bahasa terkait / VM Self mungkin juga menarik bagi Anda, karena Self pada dasarnya Smalltalk dengan objek berbasis prototipe (mirip dengan JavaScript).
sumber
Saya akan mulai dari menganalisis bagaimana kode sumber [skrip] masuk ke mesin atau lingkungan runtime Anda.
Jika Anda memiliki sesuatu seperti dalam dokumen HTML
<a onclick="dosomething();">
maka Anda akan memerlukan kompiler yang sangat cepat, kecepatan eksekusi bytecode tidak terlalu penting dalam hal ini. Jika kasus penggunaan Anda lebih dekat ke Java / .NET di mana Anda dapat melakukan kompilasi penuh sesak nafas maka arsitektur VM dan struktur bytecode akan menjadi Java bytecodes atau IL yang lebih dekat.Kriteria lain adalah apa yang saya namakan "lem". Awalnya skrip dikembangkan sebagai bahasa lem - skrip hanya mendefinisikan cara bagaimana menghubungkan berbagai fungsi asli bersama-sama (Perl, Python, Ruby, JS). Dalam hal itu efektivitas VM dan bytecode jauh lebih penting daripada dalam kasus Java / .NET ketika sebagian besar kode Anda adalah fungsi yang ditulis dalam bahasa itu sendiri.
Dan kriteria utama terakhir yang akan saya gunakan adalah ekstensibilitas bahasa Anda. Jika Anda memiliki rencana untuk menambahkan kepada Anda runtime bahasa banyak objek / fungsi asli diimplementasikan dalam, katakanlah, C ++ maka arsitektur VM Anda harus "nyaman" untuk integrasi dengan C ++. Sebagai contoh: jika Anda berencana untuk mengekspos objek skrip C ++ karena mereka maka satu-satunya pilihan bagi Anda adalah penghitungan referensi sebagai manajemen tumpukan (seperti Python, lihat boost :: python sebagai contoh integrasi). Jika Anda berencana menggunakan moving / compacting heap / GC maka itu akan menjadi cerita yang berbeda. Cara Lua untuk menambahkan barang-barang asli ke dalam runtime agak sulit [untuk pengembang C ++].
Dengan kata lain, cobalah untuk mendefinisikan terlebih dahulu kasus penggunaan tipikal Anda dan akan lebih mudah untuk menyarankan apa yang harus dibaca untuk Anda.
sumber