Voglio costruire una macchina virtuale, ci sono dei buoni riferimenti? [chiuso]

19

Sto cercando di costruire una macchina virtuale come un modo indipendente dalla piattaforma per eseguire alcuni codici di gioco (essenzialmente script).

Le macchine virtuali di cui sono a conoscenza nei giochi sono piuttosto vecchie: Infocom's Z-Machine , LucasArts ' SCUMM , id Software Quake 3 . Come sviluppatore .net, ho familiarità con CLR e ho esaminato Istruzioni CIL per avere una panoramica di ciò che effettivamente implementa su un VM Level (rispetto al livello di lingua). Ho anche dilettato un po 'in 6502 Assembler durante l'ultimo anno.

Il fatto è che ora voglio implementarlo uno, ho bisogno di scavare un po 'più a fondo. So che esistono macchine virtuali basate su stack e basate su registri, ma non so in realtà quale sia il migliore su cosa e se ci sono approcci più o ibridi. Devo occuparmi della gestione della memoria, decidere quali tipi di basso livello fanno parte della VM e devono capire perché cose come ldstr funziona come fa.

Il mio unico libro di riferimento (a parte il materiale di Z-Machine) è lo standard annotato dalla CLI , ma io chiedo se c'è una lezione migliore, più generale / fondamentale per VM? Fondamentalmente qualcosa come Dragon Book , ma per le VM? Sono a conoscenza di Art of Computer Programming di Donald Knuth che utilizza una macchina virtuale basata su registro, ma non sono sicuro di come applicabile quella serie è ancora, soprattutto dal momento che è ancora incompiuta?

Chiarimento: l'obiettivo è costruire una VM specializzata. Ad esempio, la Z-Machine di Infocom contiene OpCodes per l'impostazione del colore di sfondo o la riproduzione di un suono. Quindi ho bisogno di capire quanto vada nella VM come OpCodes rispetto al compilatore che accetta uno script (linguaggio TBD) e ne genera il bytecode, ma per quello ho bisogno di capire cosa sto facendo veramente.

¹ Lo so, la tecnologia moderna mi permetterebbe di interpretare al volo un linguaggio di scripting di alto livello. Ma dov'è il divertimento in questo? :) È anche un po 'difficile da google perché Virtual Machines è oggi spesso associato alla virtualizzazione del SO tipo VMWare ...

    
posta Michael Stum 04.12.2012 - 10:36
fonte

3 risposte

17

Vorrei iniziare controllando Lua . Sia come un'implementazione di esempio, sia come una VM / lingua molto utilizzabile, se decidi di non eseguire il rollover.

Il codice sorgente è molto leggibile, e c'è anche il codice sorgente annotato . E alcuni documenti di progettazione scritti dall'autore principale, Roberto Ierusalimschy.

Infine, se scegli di usarlo al posto tuo, scoprirai che è stato a lungo uno dei preferiti tra gli sviluppatori di giochi, e c'è un molto ad alte prestazioni implementazione JIT .

A proposito di stack- vs register-based, penso che le VM basate su stack siano più facili da progettare, ma il compilatore può essere più complesso. Come fa notare il documento Iesualimschy, Lua è stata una delle prime macchine virtuali basate su registri, ma in seguito ne sono spuntati molti altri, in particolare LLVM, Dalvik e alcune moderne VM JavaScript.

    
risposta data 04.12.2012 - 13:19
fonte
2

Non ho risorse specifiche per collegarti al momento, ma ho cercato un argomento simile in passato e ho trovato che la Smalltalk VM è un valido aiuto per l'apprendimento . Ci sono molti articoli e articoli accademici scritti sui codici byte usati da Smalltalk, oltre a scrivere interpreti e macchine virtuali per usare quel bytecode. Una ricerca su Google per smalltalk vm implementation o smalltalk bytecode interpreter dovrebbe fornire molto materiale di lettura.

Se desideri vedere qualche codice sorgente o provare un'implementazione, ti consiglio le versioni Squeak o Pharo.

La lingua correlata / VM Self potrebbe interessarti anche tu, dato che Self è fondamentalmente Smalltalk con oggetti basati su prototipi (simile a JavaScript).

    
risposta data 04.12.2012 - 17:34
fonte
0

Vorrei iniziare analizzando il modo in cui il codice sorgente [script] entra nella macchina o nell'ambiente di runtime.

Se hai qualcosa di simile nei documenti HTML <a onclick="dosomething();"> allora avrai bisogno di un compilatore molto veloce, la velocità di esecuzione del bytecode in questo caso non è molto importante. Se i tuoi casi d'uso sono più vicini a Java / .NET dove puoi permetterti una compilazione completa, l'architettura VM e la struttura bytecode saranno più vicini bytecode o IL.

di Java

Un altro criterio è quello che chiamo "glueness". Originariamente gli script sono stati sviluppati come linguaggi di colla: gli script definiscono semplicemente il modo di connettere insieme varie funzioni native (Perl, Python, Ruby, JS). In tal caso, l'efficacia di VM e bytecode è molto meno critica rispetto a Java / .NET quando la maggior parte del codice sono funzioni scritte nella lingua stessa.

E l'ultimo criterio importante che userei è l'estensibilità della tua lingua. Se hai intenzione di aggiungere al tuo linguaggio runtime molti oggetti / funzioni nativi implementati, ad esempio, in C ++, la tua architettura VM dovrebbe essere "conveniente" per l'integrazione con C ++. Ad esempio: se si prevede di esporre a script oggetti C ++ così come sono, l'unica opzione per voi sarà il conteggio dei riferimenti come gestione dell'heap (come Python, vedere boost :: python come esempio di integrazione). Se prevedi di utilizzare lo heap in movimento / compressione / GC, sarà una storia diversa. Il modo in cui Lua aggiunge roba nativa in runtime è un po 'complicato [per gli sviluppatori C ++].

In altre parole, prova a definire prima il tuo tipico caso d'uso e sarà più facile suggerire cosa leggere per te.

    
risposta data 04.12.2012 - 18:14
fonte

Leggi altre domande sui tag