Learn · concepts

JVM Bytecode'u Nedir? Java Sınıf Dosyaları Açıklaması

JVM bytecode'u, Java Sanal Makinesi'nin çalıştırdığı kompakt komut kümesidir. .class dosyalarının nasıl çalıştığını, modların bytecode'u neden yeniden yazdığını ve ASM'nin burada nasıl devreye girdiğini öğrenin.

TRtrolPublished 4 min read

JVM Bayt Kodu Nedir?

JVM bayt kodu, Java Sanal Makinesi'nin (JVM) çalıştırdığı komut kümesidir. Java kaynak kodunu derlediğinizde, derleyici CPU'nuz için makine kodu üretmez. Bunun yerine, .class dosyalarında depolanan kompakt ve taşınabilir bir biçim olan bayt kodu üretir. JVM, bu komutları çalışma zamanında okur ve bunları çalışırken yerel koda dönüştürür.

Bu katmanlı yaklaşım—kaynak kodundan bayt koduna ve ardından makine koduna—Java'nın taşınabilir olmasını sağlar. Aynı .class dosyası, uyumlu bir JVM'ye sahip Windows, macOS, Linux veya herhangi bir sistemde çalışır, çünkü JVM yerel makinede komutları yürütmeyi bilen katmandır. Bir kez yazın, her yerde çalıştırın.

Kaynak kodu bayt koduna nasıl dönüşür

Bir .java dosyası, bir kişinin yazdığı metindir. Bir .class dosyası ise, JVM'nin çalıştırdığı derlenmiş çıktıdır. Derleyici kaynak kodunuzu okur, kontrol eder ve her sınıf için bir .class dosyası yazar; her biri bayt kodu komutları, sabit havuz, yöntem tabloları ve diğer meta verileri içerir.

Bayt kodu herhangi bir işlemciye bağlı değildir. Aynı .class dosyası, Java çalışma zamanına sahip Windows, macOS, Linux veya herhangi bir şeyde çalışır, çünkü JVM yerel makinede komutları yürütmeyi bilen katmandır. Bu taşınabilirlik, formatın tamamı işte budur.

Komutlar nasıl görünür

Bayt kodu, yığın tabanlı bir komut kümesidir. Çoğu işlem, değerleri bir operand yığına itip, onlardan geri alıp, bir sonuç iter. Düşünülmesi gereken kayıt ayırma yoktur; model kasıtlı olarak basittir, böylece JVM hızlı bir şekilde doğrulayabilir ve çalıştırabilir.

Birkaç örnek opcode, genel bir fikir verir:

Komut KoduNe Yapar
iloadBir int yerel değişkeni yığına iter
iaddİki int'i yığından çıkarır, toplamlarını iter
invokevirtualBir örnek yöntemi çağırır
getfieldBir örnek alanını okur
returnBir yöntemden döner

Bunları nadiren elle okur veya yazar. Araçlar bunları üretir ve tüketir; bu da ASM gibi bir kütüphanenin devreye girdiği yerdir.

Bayt kodunun modlar için önemi

Bayt kodu, orijinal kaynağı olmadan davranışı değiştirmenizi sağladığı için önemlidir. Bir Minecraft modunun neredeyse hiç zamanı oyunun kaynak kodunu yoktur. Sahip olduğu şey, diskteki derlenmiş oyundur. Bir özellik eklemek veya değiştirmek için bir mod, mevcut bayt kodunu okur, yeniden yazar ve sonuçları sınıf yüklenirken JVM'ye geri iletir.

Bu, yamalama çerçevelerinin sahip olmadığı yöntemlere nasıl yerleştiklerini gösterir. Derlenmiş bir yöntemde doğru yeri bulurlar ve modun koduna bir çağrı eklerler. Bayt kodu düzeyinde çalışmak, bir modun orijinal Java kodunun hiçbir satırını görmese bile oyuna bağlanabileceği anlamına gelir.

Uygulamada, Terminus ve diğer Fabric tabanlı istemciler Minecraft'ı işte böyle değiştiriyor. Minecraft'ın kaynak koduna sahip olmak yerine, derlenmiş .class dosyalarıyla çalışıyor ve modüller, ayar ekranları ve özel oluşturma gibi özellikler eklemek için bayt kodunu yeniden yazıyorlar.

ASM'nin yeri

ASM, bayt kodunu okuma, yazma ve dönüştürme için bir Java kütüphanesidir. Bir .class dosyasını olaylara veya bir ağaca ayrıştırır, kodu talimatları değiştirmesine izin verir ve geçerli bir .class dosyasını geri verir. Küçük, hızlıdır ve ham formata yakın çalışır; bu nedenle daha üst düzey modlama araçları, sınıf dosyalarını kendileri ayrıştırmak yerine ASM üzerine inşa ederler.

Çoğu mod yapımcısı ASM'yi doğrudan çağırmaz. Kodlarını "bu metodun başında benim kodumu çalıştır" demek için daha kullanıcı dostu bir yol sunan, daha üst düzey bir katmanı kullanırlar. Altında, genellikle ASM aracılığıyla bayt kodunu düzenlerler.

Bayt Kodunu Kaynağa Çözme

Fernflower ve CFR gibi derleyiciler, derlenmiş .class dosyalarını alarak bayt kodundan okunabilir Java kodunu yeniden oluştururlar. Bu süreç kusursuz değildir: bazı isimler ve yorumlar kaybolur, bazı yapılar diğerlerinden daha zor kurtarılır ve karartılmış kod okunamaz hale gelir. Ancak sıradan, karartılmamış kod için derleyiciler genellikle orijinaline yeterince yakın bir çıktı üretir, böylece anlaşılabilir ve çalışılabilir.

Bu, oyunun nasıl çalıştığını öğrenmek için faydalıdır, ancak gerçek kaynağa sahip olmanın yerini tutmaz. Çözülmüş kod yine de yorumsuz derlenmiş mantıktır ve yeniden oluşturulmuş değişken adları yanıltıcı olabilir. Bu bir okuma aracıdır, bir yazma aracı değil.

SSS