Wie führt die Java Virtual Machine in anderen Sprachen geschriebenen Code aus?

12

Seit Java 1.6 kann die JVM eine Vielzahl von Programmiersprachen anstelle von Java ausführen. Ich verstehe konzeptionell, wie Java auf der Java-VM ausgeführt wird, aber nicht, wie auch andere Sprachen darauf ausgeführt werden können. Für mich sieht alles nach schwarzer Magie aus. Haben Sie Artikel, auf die ich verweisen kann, damit ich besser verstehen kann, wie das alles zusammenpasst?

Pomario
quelle
2
Genauso wie Ihr Intel / AMD / Solaris (??) Prozessor "jede Sprache" ausführen kann (obwohl Sie nicht wirklich Sprachen ausführen, sondern nur den Ablauf hier berücksichtigen), die in den systemeigenen Assembly-Code kompiliert werden kann.
Apoorv Khurasia
13
Die Sache ist, dass die JVM kein Java ausführt. Es wird eine andere (obwohl verwandte und für Java-Compiler absichtlich einfach zu erstellende), einfachere Sprache ausgeführt.
Das ist wahr. Die JVM hat jedoch begonnen, andere Sprachen ab Version 6 auszuführen. In Version 1.4.2 konnte (oder konnte niemand) Python oder Groovy darauf ausführen. Warum ist das so? Was hat sich verändert?
Pomario,
@delnan Oder vielmehr "ein Modell der Ausführung auf niedriger Ebene, das das Programm javac aus Java-Code zu erstellen versteht".
Apoorv Khurasia
9
@Pomario Jython gibt es schon eine Weile. Und diese Seite scheint darauf hinzudeuten, dass Jython-Skripte unter 1.4.2 ausgeführt werden könnten.
Apoorv Khurasia

Antworten:

23

Der Schlüssel ist die Muttersprache der JVM: der Java-Bytecode. Jede Sprache kann in Bytecode kompiliert werden, den die JVM versteht. Dazu benötigen Sie lediglich einen Compiler, der Bytecode ausgibt. Von da an gibt es aus Sicht der JVM keinen Unterschied mehr. So sehr, dass Sie eine kompilierte Scala, Clojure, Jython usw. Klassendatei nehmen und dekompilieren (zB mit JAD ) in normal aussehenden Java - Quellcode.

Weitere Details dazu finden Sie in folgenden Artikeln / Threads:

Mir sind keine grundlegenden Änderungen in den Java 5- oder 6-JVMs bekannt, die das Ausführen von (aus) anderen Sprachen kompiliertem Code ermöglicht oder erleichtert hätten. Meines Erachtens war die JVM 1.4 in dieser Hinsicht mehr oder weniger in der Lage als die JVM 6 (es kann jedoch Unterschiede geben; ich bin kein JVM-Experte). Es war nur so, dass die Leute in der ersten Hälfte des Jahrzehnts begannen, andere Sprachen und / oder Bytecode-Compiler zu entwickeln, und die Ergebnisse erschienen (und wurden allgemein bekannt) um 2006, als Java 6 veröffentlicht wurde.

Alle diese JVM-Versionen weisen jedoch einige Einschränkungen auf: Die JVM ist von Natur aus statisch typisiert und unterstützte bis Release 7 keine dynamischen Sprachen. Dies hat sich mit der Einführung invokedynamiceines neuen Bytecode-Befehls geändert , der einen Methodenaufruf unter Verwendung der dynamischen Typprüfung ermöglicht.

Péter Török
quelle
8
Es ist nicht ganz richtig, dass die JVM keine dynamischen Sprachen "unterstützte". Sie mussten nur Problemumgehungen verwenden, die schwerwiegende Nachteile hatten.
Michael Borgwardt
3
@MichaelBorgwardt, können wir uns darauf einigen, dass die JVM-Version vor v7 (in gewissem Maße) dynamische Sprachen toleriert ? :-)
Péter Török
1
Das ist ein guter Weg, um es auszudrücken :)
Michael Borgwardt
3

Eine virtuelle Maschine wie die JVM ist ein Programm, das als Eingabe in der Regel Dateien, einen Satz einfacher Anweisungen (die in der Regel leicht in echte CPU-Anweisungen zu konvertieren sind) akzeptiert und diese tatsächlich als native CPU-Anweisungen kompiliert und ausführt (in der Regel unter Verwendung von) ein On-Demand-Compiler wie HotSpot oder JIT).

Es ist im Wesentlichen eine Abstraktionsebene. Es ist normalerweise viel einfacher, VM-Befehlssatzimplementierungen auf unterschiedliche Prozessorarchitekturen zu portieren, da mehrere Ähnlichkeiten bestehen (z. B. Stack-basiert). Es ist auch viel einfacher, verschiedene Programmiersprachen auf VM-Anweisungen zu portieren, da sie sich mehr an modernen Programmiersprachen als an primitiven CPU-Anweisungen orientieren. Viele virtuelle Maschinen wie die JVM und die CLR (.NET) enthalten Anweisungen zum Aufrufen virtueller Methoden und zum Erstellen von Objektinstanzen.

Nehmen wir zum Beispiel eine Sprache. Nennen Sie es MyLanguage. Da es sich um eine Programmiersprache handelt, werden letztendlich einige Anweisungen zur CPU-Architektur kompiliert. Dies bedeutet, dass es bei einem kompatiblen, flexiblen Befehlssatz für virtuelle Maschinen auch möglich ist, MyLanguage auf einen Satz der Befehle dieser VM zu kompilieren.

Es gibt immer Fragen der Effizienz, da Sie möglicherweise einige Problemumgehungen in VM-Befehlssätzen hacken müssen, die Sie von Haus aus nicht ausführen müssten, aber es ist immer noch möglich.

Yam Marcovic
quelle
3

Eine JVM ist eine Turing-vollständige Rechenmaschine (mit Ausnahme von begrenztem Speicher), und jede Turing-vollständige Maschine (physisch oder virtuell) kann eine beliebige Programmiersprache ausführen (mit Ausnahme von Speicher-, Leistungs- und physischen E / A-Einschränkungen).

hotpaw2
quelle
Ähm ... warum brauchen wir dann Compiler? ;-)
Péter Török
Compiler und Interpreter können selbst auf Turing-Maschinen laufen (möglicherweise langsam). Vielleicht können einige Vorkompilierungs- / Übersetzungsschritte die Leistung beim Ausführen eines bestimmten Programms in einer bestimmten Sprache verbessern?
hotpaw2
1
Mein Punkt war, dass Ihre Aussage "jede Turing-komplette Maschine (physisch oder virtuell) kann jede Programmiersprache ausführen" wörtlich bedeutet, dass die x86-CPU meines Laptops diese nette Java-Quelldatei, an der ich gerade arbeite, direkt ausführen kann. Oder Maschinencode für PowerPC-Prozessoren. Ohne Compiler - CPUs enthalten doch keine Compiler, oder? :-)
Péter Török
Ihre "Maschine" ist mehr als nur die CPU.
hotpaw2
1
@ PéterTörök Ich verstehe deinen Standpunkt. Er hat sich nicht mit VMs befasst wie wir. Aber ich denke, seine Antwort beantwortet noch kurz die Frage des OP. Die JVM kann andere Programmiersprachen "ausführen", weil sie jede Programmiersprache "ausführen" kann, weil sie vollständig ist. Vielleicht nicht ausführlich, aber dennoch ein prägnanter und gültiger Punkt. :)
Yam Marcovic
2

Stellen Sie sich die JVM für einen Moment als Prozessor mit einem eigenen Befehlssatz vor, wie z. B. x86. Der Prozessor kann beispielsweise C-Code ausführen, der in seine Maschinensprache kompiliert wurde. Analog zur JVM können andere Sprachen auf der JVM ausgeführt werden, genau wie auf anderen Prozessoren, wenn diese Sprachen bis auf die Maschinenanweisungen der JVM kompiliert wurden. Die JVM kann diese Anweisungen dann für die Sprache X ausführen.

Cobie
quelle
Ihre Analogie ist eine schöne
cobi