Saya ingin membangun Mesin Virtual, apakah ada referensi yang bagus? [Tutup]

22

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 ...

Michael Stum
sumber
6
Perhatikan bahwa untuk mesin berbasis stack untuk menyelesaikan-turing itu membutuhkan memori di luar tumpukan kalau tidak itu hanya PDA
ratchet freak
1
Pertanyaan pertama adalah: seberapa jauh Anda ingin melangkah? Saya tidak pernah melihat SCUMM / SCUMMVM tetapi menganggap itu cukup tinggi mengetahui tentang hal-hal grafis bergerak dll. Sedangkan CIL adalah ... jadi Anda harus mendefinisikan model memori Anda (berbasis register stackbased, campuran, mess, ..) dan opcodes ( yaitu instruksi assembler) dan kemudian versi pertama dari VM adalah loop do { switch(opcode) {case OP1: ... case OP2: ...} while (nextop);kemudian mungkin kompiler ... dan kemudian kesenangan dimulai - optimasi untuk membuatnya benar-benar berfungsi
johannes
3
Coba mulai dengan menerapkan runtime Forth sederhana.
SK-logic
1
Bagaimana tepatnya Quake 3mesin virtual?
Ramhound
3
@Ramhound mesin id tech telah lama menggunakan beberapa bentuk virtualisasi internal, artikel ini , atau info Wikipedia mungkin menjelaskan lebih baik.
Daniel B

Jawaban:

18

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.

Javier
sumber
2
Tentang mesin stack vs register: Saya ingat kutipan dari Parrot / Perl6 devs: "membangun mesin berbasis register lebih sulit, tapi kami mendapat manfaat dari banyak penelitian yang sudah ada untuk sisi kompiler kami" (tidak secara literal)
johannes
+1 Lua memiliki implementasi bytecode yang sangat baik dan desain yang sangat bersih untuk belajar tentang VM dari. Selain itu, Anda akan menemukan bahwa banyak orang telah menyesuaikan Lua untuk kebutuhan mereka sendiri, menunjukkannya cukup fleksibel jika Anda tidak ingin memulai dari awal.
CodexArcanum
Masih melalui ini. Dokumen hebat lainnya dari pengembang tentang VM: inf.puc-rio.br/~roberto/talks/lua-ll3.pdf
Michael Stum
2

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 implementationatau smalltalk bytecode interpreterharus 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).

CodexArcanum
sumber
0

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.

c-senyum
sumber
1
Kompiler JavaScript modern cukup rumit, dan pertanyaannya ada berapa banyak optimasi kode yang Anda masukkan.
johannes
Masalah kinerja eksekusi Javascript. Bukan untuk skrip kecil, tetapi untuk situs JS-besar yang lebih besar, yang baik atau buruk menjadi bagian penting dari situs yang lebih populer. Ada alasan mengapa mesin JS menggunakan kompiler JIT (V8 bahkan tidak memiliki juru bahasa, langsung ke kode mesin).
@delnan: Kasus penggunaan JS sangat berbeda dari, katakanlah, Python. Dalam Python ketika Anda membutuhkan sesuatu seperti implementasi algoritma ray-tracing Anda akan melakukan pustaka asli dan memanggilnya dari skrip. Ini selalu lebih cepat (atau setidaknya tidak lebih lambat) daripada solusi JIT. Di ranah JS Anda tidak memiliki kemewahan seperti kode asli sehingga satu-satunya pilihan bagi Anda adalah mencoba membuat JS VM Anda secepat mungkin. Tapi sekali lagi, dengan harganya. Evaluasi "dosomethingnative ()" dalam HTML "<button onclick =" dosomethingnative () "> dalam bahasa penerjemah sederhana dapat lebih cepat daripada di V8
c-smile
@ c-tersenyumlah, maksudku tepatnya.
@delnan: tapi maksud saya sangat berbeda: menganalisis kasus penggunaan umum dan hanya kemudian Anda dapat memutuskan jenis arsitektur VM, sintaks bahasa, dll. Anda akan perlu.
c-smile