Une machine, virtuelle ou non, a besoin d’un modèle de calcul décrivant comment le calcul est effectué. Par définition, dès qu'il calcule, il implémente un modèle de calcul. La question est alors: quel modèle devrions-nous choisir pour notre machine virtuelle? Les machines physiques sont limitées par ce que l’on peut faire de manière efficace dans le matériel. Mais, comme vous le constatez, les machines virtuelles ne sont pas soumises à de telles contraintes. Elles sont définies dans un logiciel utilisant des langages de haut niveau arbitrairement.
En fait, il existe des machines virtuelles de haut niveau, telles que vous les décrivez. Ils s'appellent les langages de programmation . Le standard C, par exemple, consacre l’essentiel de ses pages à la définition d’un modèle pour la "machine abstraite en C", qui décrit le comportement des programmes C et, par extension, la manière dont un compilateur C conforme (ou un interpréteur) se conforme. Devrait se comporter.
Bien sûr, nous n’appelons généralement pas cela une machine virtuelle. Une machine virtuelle signifie généralement quelque chose de niveau inférieur, plus proche du matériel, non destiné à être programmé directement, conçu pour être exécuté efficacement. Ce biais de sélection signifie que quelque chose qui accepte du code composable de haut niveau (comme ce que vous décrivez) ne serait pas considéré comme une machine virtuelle, car il exécute du code de haut niveau.
Mais pour aller droit au but, voici quelques raisons de créer une machine virtuelle (comme dans quelque chose ciblé par un compilateur de code-octet) basée sur des registres ou similaire. Les machines à empiler et à enregistrer sont extrêmement simples. Il y a une séquence d'instructions, un certain état et une sémantique pour chaque instruction (une fonction State -> State). Pas de réduction d'arbres complexes, pas de priorité des opérateurs. Son analyse, son analyse et son exécution sont très simples, car il s'agit d'un langage minimal (le sucre syntaxique est compilé) et conçu pour être lu par une machine plutôt que par un humain.
En revanche, analyser même les langages de type C les plus simples est assez difficile et son exécution nécessite des analyses non locales telles que la vérification et la propagation de types, la résolution des surcharges, la maintenance d'une table de symboles, la résolution des identificateurs de chaîne , la transformation de texte linéaire en AST , etc. Il s’appuie sur des concepts naturels pour l’homme, mais doit être minutieusement mis au point par des machines.
Le bytecode de la machine virtuelle Java, par exemple, est émis par javac
. Il n’a pratiquement jamais besoin d’être lu ou écrit par des humains, il est donc naturel de l’orienter vers la consommation par des machines. Si vous optimized pour l' homme, la machine virtuelle Java serait juste à chaque démarrage lire le code, l' analyser, analyser est, puis le convertir en une représentation intermédiaire ressemblant à un tel modèle simplifié de la machine de toute façon . Pourrait aussi bien couper l'homme du milieu.