Bagaimana Java Virtual Machine menjalankan kode yang ditulis dalam bahasa lain?

12

Sejak Java 1.6, JVM dapat menjalankan berbagai bahasa pemrograman di atas, bukan hanya Java. Saya secara konseptual memahami bagaimana Java dijalankan pada Java VM, tetapi tidak bagaimana bahasa lain dapat berjalan di sana juga. Bagi saya, itu semua tampak seperti ilmu hitam. Apakah Anda memiliki artikel yang ingin saya tunjukkan agar saya dapat lebih memahami bagaimana semua ini cocok?

Pomario
sumber
2
Cara yang sama seperti prosesor Intel / AMD / Solaris (??) Anda dapat mengeksekusi "bahasa apa pun" (meskipun Anda tidak benar-benar menjalankan bahasa, tetapi hanya mengikuti arus di sini) yang dapat dikompilasi ke dalam kode perakitan aslinya.
Apoorv Khurasia
13
Masalahnya, JVM tidak menjalankan Java. Ini menjalankan yang berbeda (meskipun terkait, dan sengaja mudah untuk kompiler Java untuk membuat), lebih banyak bahasa tingkat rendah.
Itu benar. Tetapi JVM mulai menjalankan bahasa lain dari versi 6; Anda tidak bisa (atau tidak ada yang) menjalankan python atau Groovy di dalam versi 1.4.2. Kenapa begitu? Apa yang berubah?
Pomario
@delnan Atau lebih tepatnya "model eksekusi yang lebih rendah, bahwa program javac tahu cara membuat kode Java".
Apoorv Khurasia
9
@ Tomario Jython telah ada untuk sementara waktu sekarang. Dan halaman ini tampaknya menunjukkan bahwa skrip Jython dapat berjalan pada 1.4.2.
Apoorv Khurasia

Jawaban:

23

Kuncinya adalah bahasa asli JVM: bytecode Java. Bahasa apa pun dapat dikompilasi menjadi bytecode yang dipahami JVM - semua yang Anda butuhkan untuk ini adalah bytecode yang memancarkan kompiler. Sejak saat itu, tidak ada perbedaan dari sudut pandang JVM. Sedemikian rupa sehingga Anda dapat mengambil file kelas Scala, Clojure, Jython dll yang telah dikompilasi dan mendekompilasi (menggunakan misalnya JAD ) menjadi kode sumber Java yang terlihat normal.

Anda dapat menemukan detail lebih lanjut tentang ini di artikel / utas berikut:

Saya tidak mengetahui adanya perubahan mendasar pada Java 5 atau 6 JVM yang akan membuatnya mungkin atau lebih mudah untuk (kode dikompilasi dari) bahasa lain untuk dijalankan di dalamnya. Dalam pemahaman saya, JVM 1.4 lebih atau kurang mampu dalam hal itu seperti JVM 6 (mungkin ada perbedaan; Saya bukan ahli JVM). Hanya saja orang mulai mengembangkan bahasa lain dan / atau kompiler bytecode pada paruh pertama dekade ini, dan hasilnya mulai muncul (dan menjadi lebih dikenal) sekitar 2006 ketika Java 6 diterbitkan.

Namun, semua versi JVM ini berbagi beberapa keterbatasan: JVM secara statis diketik berdasarkan sifatnya, dan hingga rilis 7, tidak mendukung bahasa dinamis. Ini telah berubah dengan diperkenalkannya invokedynamic, instruksi bytecode baru yang memungkinkan pemanggilan metode bergantung pada pemeriksaan tipe dinamis.

Péter Török
sumber
8
Tidak sepenuhnya benar bahwa JVM tidak "mendukung" bahasa dinamis. Mereka hanya harus menggunakan solusi yang memiliki kelemahan parah.
Michael Borgwardt
3
@MichaelBorgwardt, dapatkah kita sepakat bahwa JVM pre v7 mentolerir bahasa dinamis (sampai batas tertentu)? :-)
Péter Török
1
Itu cara yang bagus untuk menjelaskannya :)
Michael Borgwardt
3

Mesin virtual, seperti JVM, adalah program yang menerima sebagai input, biasanya file, seperangkat instruksi sederhana (yang biasanya mudah dikonversi menjadi instruksi CPU nyata), dan sebenarnya mengkompilasi dan menjalankannya sebagai instruksi CPU asli (biasanya menggunakan kompiler sesuai permintaan seperti HotSpot atau JIT).

Ini pada dasarnya adalah lapisan abstraksi. Biasanya lebih mudah untuk menempatkan implementasi set instruksi VM ke arsitektur prosesor yang berbeda, karena beberapa kesamaan (seperti berbasis stack). Ini juga jauh lebih mudah untuk port bahasa pemrograman yang berbeda untuk instruksi VM, karena itu lebih berorientasi pada bahasa pemrograman modern daripada instruksi CPU primitif. Banyak Mesin Virtual seperti JVM dan CLR (.NET) berisi instruksi untuk memanggil metode virtual, dan membuat instance objek.

Jadi mari kita ambil sebuah bahasa sebagai contoh. Sebut saja MyLanguage. Karena ini adalah bahasa pemrograman, akhirnya dikompilasi hingga ke beberapa instruksi arsitektur CPU. Jadi itu berarti bahwa, mengingat set instruksi Mesin Virtual yang kompatibel dan fleksibel, juga memungkinkan untuk mengkompilasi MyLanguage ke set instruksi VM itu.

Selalu ada pertanyaan tentang efisiensi, karena Anda mungkin perlu meretas beberapa solusi dalam set instruksi VM yang tidak harus Anda lakukan secara native, tetapi itu masih mungkin.

Yam Marcovic
sumber
3

JVM adalah mesin komputasi Turing-complete (kecuali untuk memori terbatas), dan mesin Turing-complete (fisik atau virtual) apa pun dapat mengeksekusi bahasa pemrograman apa pun (kecuali untuk memori, kinerja, dan keterbatasan IO fisik).

hotpaw2
sumber
Erm .... kenapa kita perlu kompiler? ;-)
Péter Török
Kompiler dan interpreter, sendiri, dapat berjalan pada mesin Turing (mungkin lambat). Mungkin beberapa langkah pra-kompilasi / terjemahan dapat meningkatkan kinerja menjalankan beberapa program tertentu dalam beberapa bahasa tertentu?
hotpaw2
1
Maksud saya adalah pernyataan Anda "semua mesin Turing-lengkap (fisik atau virtual) dapat mengeksekusi bahasa pemrograman" secara harfiah berarti bahwa CPU x86 laptop saya dapat langsung menjalankan file sumber Java yang bagus yang sedang saya kerjakan saat ini. Atau kode mesin untuk prosesor PowerPC. Tanpa kompiler - CPU tidak mengandung kompiler kan? :-)
Péter Török
"Mesin" Anda lebih dari sekadar CPU.
hotpaw2
1
@ PéterTörök, saya mengerti maksud Anda. Dia tidak menguraikan VM seperti yang kami lakukan. Tapi saya pikir jawabannya masih menjawab pertanyaan OP secara singkat. JVM dapat "menjalankan" bahasa pemrograman lain karena dapat "menjalankan" bahasa pemrograman apa pun, karena Turing lengkap. Mungkin tidak terlalu rumit, tapi masih ringkas dan valid. :)
Yam Marcovic
2

Untuk sesaat pikirkan saja JVM sebagai prosesor dengan set instruksi sendiri seperti mungkin x86. Prosesor dapat mengeksekusi kode say C yang telah dikompilasi ke dalam bahasa mesinnya. Menerapkan analogi yang sama dengan JVM, Bahasa lain dapat dieksekusi di JVM seperti pada prosesor lain jika bahasa-bahasa tersebut dikompilasi ke instruksi mesin JVM. JVM kemudian dapat menjalankan instruksi ini untuk bahasa X.

cobie
sumber
analogi Anda bagus
cobi