Fonctionnement de la machine virtuelle ActionScript

Si vous êtes impliqué dans le développement AS3, vous avez peut-être entendu parler d'une machine virtuelle hébergée dans Flash Player ou du pseudo-bytecode dans lequel votre code est transformé. Mais que sont-ils exactement?

Une partie importante de Flash Player est le AVM - la machine virtuelle ActionScript. Lorsque vous compilez votre code AS3, il est transformé en un jeu d'instructions binaires, appelé bytecode, intégré au fichier SWF généré. Lorsqu'un utilisateur charge le fichier SWF dans Flash Player, l’AVM analyse le bytecode et l’exécute pas à pas..

Examinons le processus un peu plus en détail: Examinez la déclaration suivante et imaginons que nous voulons l'exécuter (calculez le résultat et affectez-le à "foo"):

toto = 2 + 3 * 4;

Du point de vue humain, cette ligne signifie "Multipliez 3 par 4, ajoutez 2 au résultat et affectez-le à une variable nommée foo".

D'autre part, si un ordinateur lit cette ligne, il la stockera sous la forme "caractère f, suivi du caractère o, suivi du caractère o, suivi de l'espace des caractères, suivi du caractère égal à, suivi de?" Etc. Dans cet état, ces informations sont plutôt inutiles et des mesures supplémentaires doivent être prises afin de transformer l'instruction en quelque chose qu'une machine peut exécuter. Fondamentalement, nous devons compiler le code source..


Le compilateur

Comme je l'ai déjà noté, la déclaration ci-dessus est un code source brut, une collection de caractères qui ne signifie rien pour un ordinateur. Afin d'obtenir des informations utiles, nous devons exécuter le code à travers quelques procédures. Premièrement, nous devrions transformer le flot de caractères en mots et en second lieu, transformer les mots en phrases.

La première étape de la conversion des caractères en mots est effectuée par un générateur de jetons qui effectue essentiellement une analyse lexicale du code source. Il parcourt les caractères et les regroupe en une série de "jetons" (et détermine également leurs identificateurs de type, opérateurs, constantes?). Une fois que le tokenizer (également appelé lexer BTW) a terminé son travail, nous obtenons un tableau qui peut être illustré comme suit:

[Identifiant foo] [Opérateur égal] [Entier 2] [Opérateur plus] [Entier 3] [Opérateur multiplié] [Entier 4]

C'est une structure de niveau supérieur qui contient des "mots" au lieu des caractères bruts.

Les jetons résultants sont introduits dans un analyseur. Il effectue une analyse sémantique des jetons et les assemble en instructions machine. En termes plus simples, il construit des phrases à partir des mots (jetons) et leur donne un sens (c’est-à-dire compile des instructions). Par exemple, si l'analyseur reçoit une déclaration 2 + 3; i ++; en tant que jetons, l'analyseur doit d'abord séparer les jetons en "phrases" (2 + 3 et i ++), puis les comprendre (le premier est l'opération add et le second est un incrément). Une fois que nous avons compris l’instruction, nous pouvons compiler des instructions à la machine en dehors de l’entrée.

Après l'analyse des jetons de notre chaîne, nous obtenons les instructions suivantes:

pousser 2 pousser 3 pousser 4 multiplier ajouter assigner "foo"

Ce sont des instructions qu'un ordinateur peut exécuter. Compressez-le en un format binaire et vous avez du bytecode. Le bytecode est une liste d'instructions indiquant qu'une machine est très performante en traitement et, lorsqu'elle est traitée dans l'ordre, elle permet d'obtenir les résultats souhaités..


L'interprète

Après avoir compilé le code source en bytecode, nous pouvons l'exécuter avec une machine virtuelle. La VM est un logiciel qui exécute l'instruction bytecode, une instruction à la fois. Voyons donc l'interprétation de notre déclaration:

  1. poussez 2 -- La commande consiste à insérer le nombre 2 dans la pile. La machine virtuelle maintient une pile pendant l'exécution des commandes, c'est-à-dire pour insérer et supprimer des valeurs (http://en.wikipedia.org/wiki/Stack_(data_structure)). Actuellement, la pile ressemble à ceci: [2]
  2. poussez 3 -- poussez un autre entier dans la pile. Maintenant, cela ressemble à [2, 3];
  3. poussez 4 -- poussez encore un autre entier dans la pile. Maintenant, cela ressemble à [2, 3, 4];
  4. multiplier -- cette commande extrait 2 valeurs de la pile, les multiplie et renvoie le résultat dans la pile. Il affiche les valeurs 3 et 4 (qui se trouvent actuellement au sommet de la pile), les multiplie et pousse les 12 résultants dans la pile. Cela affecte la pile de ressembler à [2, 12];
  5. ajouter -- vous l'avez probablement deviné: la commande supprime 12 et 2 de la pile, les ajoute et place les 14 résultants dans la pile. Il ne reste plus que 14 dans la pile.
  6. attribuer "foo" -- Cette commande extrait une valeur de la pile et l'assigne à une variable nommée foo. Alors maintenant, la variable foo contient la valeur 14 et la pile est vide.

C'est tout! Voici un exemple d'instruction extrêmement simple exécutée sur une machine virtuelle extrêmement simple. Examinons un exemple un peu plus compliqué:

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

Cela peut compiler (je dis "peut" car il existe différentes façons de compiler la déclaration):

pousser 12 pousser 4 pousser 2 ajouter diviser pousser 6 pousser 9 soustraire pousser 3 multiplier soustraire assigner "bar"

Cela sera interprété comme:

  1. Les 3 premiers push seront ajoutés à la pile: [12, 4, 2]
  2. ajouter -- fera la somme des 2 valeurs en haut de la pile: [12, 6]
  3. diviser -- 6, puis 12, divisez 12 par 6 et placez le résultat dans la pile: [2]
  4. Les 2 commandes suivantes pousseront des nombres entiers dans la pile: [2, 6, 9]
  5. soustraire -- soustraira les 2 nombres en haut de la pile. Sera pop 9, puis 6, puis soustrayez 6 de 9 et poussez le résultat à la pile: [2, -3]
  6. Un autre entier sera poussé dans la pile: [2, -3, 3]
  7. multiplier -- va apparaître et multiplier les 2 nombres en haut de la pile. -9, soit 3 fois -3, sera repoussé dans la pile: [2, -9]
  8. soustraire -- soustraira -9 de 2 et poussera le résultat dans la pile: [11]
  9. attribuer -- va faire apparaître 11 et l'assigner à une variable nommée "bar". La pile est maintenant vide.

Le résultat est maintenant stocké dans une variable nommée "bar" et elle est 11. Yay!


Conclusion

Il s’agit des informations les plus élémentaires sur une machine virtuelle. C’est peut-être utile lorsque vous commencez à apprendre quelques éléments de Flash Player de bas niveau. La VM dans Flash Player est bien sûr beaucoup plus complexe mais la base est la même que dans l'exemple présenté ci-dessus.

Si vous souhaitez en savoir plus sur la machine virtuelle ActionScript, vous pouvez consulter ce document PDF d'Adobe. Merci d'avoir lu!