Come funziona la macchina virtuale ActionScript

Se sei coinvolto nello sviluppo di AS3 potresti aver sentito parlare di una macchina virtuale che vive all'interno di Flash Player o del cosiddetto bytecode in cui viene trasformato il tuo codice. Ma cosa sono esattamente?

Una parte significativa di Flash Player è il AVM - la macchina virtuale ActionScript. Quando si compila il codice AS3 viene trasformato in un set di istruzioni binarie, chiamato bytecode, che è incorporato nel file SWF prodotto. Quando un utente carica il file SWF in Flash Player, AVM analizza il bytecode e lo esegue passo dopo passo.

Esaminiamo il processo in modo un po 'più dettagliato: dai un'occhiata alla seguente dichiarazione e immagina di voler eseguirla (calcola il risultato e assegnalo a "foo"):

foo = 2 + 3 * 4;

Dal punto di vista di un umano questa linea significa "Moltiplicare 3 per 4, aggiungere 2 al risultato e assegnarlo a una variabile denominata foo".

D'altra parte, se un computer legge questa riga, la memorizzerebbe come "carattere f, seguito dal carattere o, seguito dal carattere o, seguito dallo spazio del carattere, seguito dal carattere uguale, seguito da". E così via. In questo stato questa informazione è piuttosto inutile e devono essere fatti ulteriori passi per trasformare l'affermazione in qualcosa che una macchina può eseguire. Fondamentalmente quello che dobbiamo fare è compilare il codice sorgente.


Il compilatore

Come ho notato prima, la dichiarazione di cui sopra è un codice sorgente grezzo, una raccolta di caratteri che non significa nulla per un computer. Per ottenere informazioni utili dobbiamo eseguire il codice attraverso alcune procedure. Innanzitutto, dovremmo trasformare il flusso di caratteri in parole e in secondo luogo, trasformare le parole in frasi.

Il primo passo per trasformare i caratteri in parole è fatto da un tokenizer che fondamentalmente esegue un'analisi lessicale del codice sorgente. Funziona sui personaggi e li raggruppa in serie di "token" (e determina anche il loro tipo - identificatori, operatori, costanti?). Dopo che il tokenizer (chiamato anche lesser BTW) termina il suo lavoro, otteniamo un array che può essere illustrato in questo modo:

[Identificatore foo] [Operatore equals] [Intero 2] [Operatore più] [Intero 3] [Operatore multiplo] [Intero 4]

Questa è una struttura di livello superiore che contiene "parole" invece dei caratteri non elaborati.

I token risultanti vengono inseriti in un parser. Esegue l'analisi semantica dei token e li assembla in istruzioni macchina. In parole più semplici, costruisce frasi dalle parole (token) e ha senso da esse (ad esempio, compila le istruzioni al di fuori di esse). Ad esempio se al parser viene data una dichiarazione 2 + 3; i ++; come token, il parser deve prima separare i token in "frasi" (2 + 3 e i ++) e quindi effettivamente capirli (il primo è un'operazione add e il secondo è un incremento). Dopo aver compreso le istruzioni, possiamo effettivamente compilare le istruzioni alla macchina con l'input.

Dopo aver analizzato i token della nostra stringa otteniamo le seguenti istruzioni:

spingere 2 spingere 3 spingere 4 moltiplicare aggiungere assegnare "pippo"

Queste sono istruzioni che un computer può eseguire. Comprimilo in un formato binario e hai il bytecode. Bytecode è un elenco di istruzioni che una macchina è molto brava a elaborare e una volta processata in ordine produce i risultati desiderati.


L'interprete

Dopo aver compilato il codice sorgente in bytecode, possiamo eseguirlo con una macchina virtuale. La VM è un software che esegue il bytecode un'istruzione alla volta, quindi passiamo all'analisi della nostra affermazione:

  1. spingere 2 -- Il comando è di inserire il numero 2 nella pila. La VM mantiene uno stack durante l'esecuzione su cui i comandi possono operare, cioè per inserire e inserire valori (http://en.wikipedia.org/wiki/Stack_(data_structure)). Attualmente la pila assomiglia a questa: [2]
  2. spingere 3 -- spingere un altro intero nello stack. Ora sembra [2, 3];
  3. spingere 4 -- spingere ancora un altro numero intero nello stack. Ora sembra [2, 3, 4];
  4. moltiplicare -- questo comando espelle 2 valori dalla pila, li moltiplica e riporta il risultato in pila. Espone i valori 3 e 4 (che sono attualmente in cima alla pila), li moltiplica e spinge il risultato 12 allo stack. Influisce sulla pila in modo che assomigli a [2, 12];
  5. Inserisci -- probabilmente lo avete indovinato: il comando pop 12 e 2 fuori dallo stack, li aggiunge e inserisce i 14 risultanti nello stack. Ora solo 14 rimangono all'interno della pila.
  6. assegnare "foo" -- Questo comando mostra un valore fuori dallo stack e lo assegna a una variabile denominata foo. Così ora la variabile foo contiene il valore di 14 e lo stack è vuoto.

Questo è tutto! Questo è un esempio di una dichiarazione estremamente semplice eseguita su una macchina virtuale estremamente semplice. Esaminiamo un esempio leggermente più complicato:

bar = 12 / (4 + 2) - (6 - 9) * 3

Questo può essere compilato (dico "può" perché ci sono diversi modi per compilare la dichiarazione):

spingere 12 premere 4 premere 2 aggiungere dividere premere 6 premere 9 sottrarre premere 3 moltiplicare sottrarre assegnare "bar"

Questo sarà interpretato come:

  1. Le prime 3 spinte saranno aggiunte allo stack: [12, 4, 2]
  2. Inserisci -- sommerà i 2 valori in cima allo stack: [12, 6]
  3. dividere -- pop 6, quindi pop 12, divide 12 per 6 e spinge il risultato in pila: [2]
  4. I prossimi 2 comandi inseriranno interi nello stack: [2, 6, 9]
  5. sottrarre -- sottrae i 2 numeri in cima alla pila. Will pop 9, quindi 6, quindi sottrarre 6 da 9 e spingere il risultato in pila: [2, -3]
  6. Un altro intero verrà spinto in pila: [2, -3, 3]
  7. moltiplicare -- pop e moltiplicherà i 2 numeri in cima alla pila. -9, che è 3 volte -3, verrà reimpostato nello stack: [2, -9]
  8. sottrarre -- sottrarrà -9 da 2 e spingerà il risultato in pila: [11]
  9. assegnare -- pop 11 e assegnarlo a una variabile denominata "bar". Lo stack ora è vuoto.

Il risultato è ora memorizzato all'interno di una variabile denominata "bar" ed è 11. Yay!


Conclusione

Queste sono le informazioni di base su una VM, potrebbe rivelarsi utile quando inizierai ad imparare alcune cose di basso livello su Flash Player. La VM all'interno di Flash Player è ovviamente molto più complessa ma la base è la stessa dell'esempio presentato sopra.

Se vuoi saperne di più sulla macchina virtuale ActionScript puoi dare un'occhiata a questo documento PDF di Adobe. Grazie per aver letto!