Comment la machine virtuelle Java exécute-t-elle le code écrit dans d'autres langages?

12

Depuis Java 1.6, la JVM peut exécuter une myriade de langages de programmation par dessus au lieu de simplement Java. Je comprends conceptuellement comment Java est exécuté sur la machine virtuelle Java, mais pas comment d'autres langages peuvent également s'exécuter dessus. Pour moi, tout cela ressemble à de la magie noire. Avez-vous des articles à me montrer pour que je puisse mieux comprendre comment tout cela s'imbrique?

Pomario
la source
2
De la même manière que votre processeur Intel / AMD / Solaris (??) peut exécuter "n'importe quelle langue" (bien que vous n'exécutiez pas vraiment des langues, mais que vous suiviez simplement le flux ici) qui peuvent être compilées dans son code d'assemblage natif.
Apoorv Khurasia
13
Le fait est que la JVM n'exécute pas Java. Il exécute un langage distinct (bien que lié et intentionnellement facile à créer pour les compilateurs Java), de plus bas niveau.
C'est vrai. Mais la JVM a commencé à exécuter d'autres langues à partir de la version 6; vous ne pouviez pas (ou personne ne l'a fait) exécuter python ou Groovy dessus dans la version 1.4.2. Pourquoi est-ce si? Qu'est ce qui a changé?
Pomario
@delnan Ou plutôt "modèle d'exécution plus bas, que le programme javac sait construire à partir de code Java".
Apoorv Khurasia
9
@Pomario Jython existe depuis un certain temps maintenant. Et cette page semble suggérer que les scripts Jython pourraient s'exécuter sur 1.4.2.
Apoorv Khurasia

Réponses:

23

La clé est le langage natif de la JVM: le bytecode Java. Tout langage peut être compilé en bytecode que la JVM comprend - tout ce dont vous avez besoin pour cela est un compilateur émettant du bytecode. Dès lors, il n'y a plus de différence du point de vue de la JVM. À tel point que vous pouvez prendre un fichier de classe Scala, Clojure, Jython etc. compilé et le décompiler (en utilisant par exemple JAD ) en code source Java d'aspect normal.

Vous pouvez trouver plus de détails à ce sujet dans les articles / discussions suivants:

Je n'ai pas connaissance de changements fondamentaux dans les JVM Java 5 ou 6 qui auraient rendu possible ou plus facile (le code compilé à partir) d'autres langages de s'exécuter dessus. À ma connaissance, la JVM 1.4 était plus ou moins aussi performante à cet égard que la JVM 6 (il peut cependant y avoir des différences; je ne suis pas un expert de la JVM). C'est juste que les gens ont commencé à développer d'autres langages et / ou des compilateurs de bytecode dans la première moitié de la décennie, et les résultats ont commencé à apparaître (et à devenir plus connus) vers 2006 lorsque Java 6 a été publié.

Cependant, toutes ces versions de JVM partagent certaines limitations: la JVM est typée de manière statique par nature et, jusqu'à la version 7, ne supportait pas les langages dynamiques. Cela a changé avec l'introduction de invokedynamic, une nouvelle instruction de bytecode qui permet l'appel de méthode en s'appuyant sur la vérification de type dynamique.

Péter Török
la source
8
Ce n'est pas tout à fait vrai que la JVM ne "supportait" pas les langages dynamiques. Ils devaient simplement utiliser des solutions de contournement qui présentaient de graves inconvénients.
Michael Borgwardt
3
@MichaelBorgwardt, pouvons-nous nous mettre d'accord sur le fait que la JVM pre v7 tolérait les langages dynamiques (dans une certaine mesure)? :-)
Péter Török
1
C'est une bonne façon de le dire :)
Michael Borgwardt
3

Une machine virtuelle, comme la JVM, est un programme qui accepte en entrée, généralement des fichiers, un ensemble d'instructions simples (qui sont généralement faciles à convertir en instructions CPU réelles), et les compile et les exécute en tant qu'instructions CPU natives (généralement en utilisant un compilateur à la demande tel que HotSpot ou JIT).

C'est essentiellement une couche d'abstraction. Il est généralement beaucoup plus facile de porter des implémentations de jeux d'instructions VM vers différentes architectures de processeur, en raison de plusieurs similitudes (telles que la pile). Il est également beaucoup plus facile de porter différents langages de programmation vers des instructions VM, car il est plus orienté vers les langages de programmation modernes que les instructions CPU primitives. De nombreuses machines virtuelles telles que la JVM et le CLR (.NET) contiennent des instructions pour appeler des méthodes virtuelles et créer des instances d'objet.

Prenons donc une langue par exemple. Appelez ça MyLanguage. Puisqu'il s'agit d'un langage de programmation, il se compile finalement en un ensemble de quelques instructions d'architecture CPU. Cela signifie donc que, étant donné un ensemble d'instructions de machine virtuelle flexible et compatible, il est également possible de compiler MyLanguage en un ensemble d'instructions de cette machine virtuelle.

Il y a toujours une question d'efficacité, car vous devrez peut-être pirater des solutions de contournement dans les jeux d'instructions VM que vous n'auriez pas à faire de manière native, mais c'est toujours possible.

Yam Marcovic
la source
3

Une machine virtuelle Java est une machine de calcul complète de Turing (à l'exception de la mémoire limitée), et toute machine complète de Turing (physique ou virtuelle) peut exécuter n'importe quel langage de programmation (à l'exception de la mémoire, des performances et des limitations d'E / S physiques).

hotpaw2
la source
Euh ... pourquoi avons-nous besoin de compilateurs alors? ;-)
Péter Török
Les compilateurs et les interprètes, eux-mêmes, peuvent fonctionner sur des machines de Turing (peut-être lentement). Peut-être que certaines étapes de pré-compilation / traduction peuvent améliorer les performances d'exécution d'un programme donné dans une langue donnée?
hotpaw2
1
Mon point était que votre déclaration "n'importe quelle machine complète de Turing (physique ou virtuelle) peut exécuter n'importe quel langage de programmation" signifie littéralement que le processeur x86 de mon ordinateur portable peut exécuter directement ce joli fichier source Java sur lequel je travaille en ce moment. Ou code machine pour les processeurs PowerPC. Sans compilateurs - les processeurs ne contiennent pas de compilateurs, n'est-ce pas? :-)
Péter Török
Votre "machine" est bien plus que le CPU.
hotpaw2
1
@ PéterTörök Je vois votre point. Il n'a pas développé les VM comme nous. Mais je pense que sa réponse répond encore brièvement à la question du PO. La JVM peut "exécuter" d'autres langages de programmation car elle peut "exécuter" n'importe quel langage de programmation, car elle est Turing complète. Pas élaboré peut-être, mais toujours un point concis et valable. :)
Yam Marcovic
2

Pour un instant, considérez la JVM comme un processeur avec son propre jeu d'instructions comme peut-être le x86. Le processeur peut exécuter, par exemple, du code C qui a été compilé dans son langage machine. En appliquant la même analogie à la JVM, d'autres langues peuvent être exécutées sur la JVM comme sur d'autres processeurs si ces langues sont compilées selon les instructions de la machine de la JVM. La JVM peut ensuite exécuter ces instructions pour la langue X.

cobie
la source
votre analogie est bonne
cobi