Çoğunuzun goto
Java dilinde ayrılmış bir anahtar kelime olduğunu , ancak aslında kullanılmadığını bildiğinizi düşünüyorum . Ve muhtemelen goto
bunun bir Java Sanal Makinesi (JVM) opcode olduğunu da biliyorsunuz . Ben, JVM düzeyinde, bazı kombinasyonu kullanılarak uygulanan tüm Java, Scala ve KOTLIN sofistike kontrol akış yapıları hesaba katmak goto
ve ifeq
, ifle
, iflt
vb
JVM spesifikasyonlarına bakarak https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.goto_w Bir de goto_w
opcode olduğunu görüyorum . Oysa goto
ofset 2 baytlık dalı alır, goto_w
ofset bir 4 baytlık dalı alır. Spec diyor ki
Goto_w komutu 4 baytlık bir şube ofseti alsa da , diğer faktörler bir yöntemin boyutunu 65535 bayt ile sınırlar (§4.11). Bu sınır, Java Sanal Makinesi'nin gelecekteki bir sürümünde yükseltilebilir.
Bana goto_w
gelecekteki kanıtlar gibi geliyor , tıpkı diğer *_w
opcodlar gibi. Ama aynı zamanda bana göre goto_w
, daha önemli iki bayt sıfırlanmış ve daha az önemli iki bayt, goto
gerektiği gibi ayarlamalar ile kullanılabilir.
Örneğin, bu Java Switch-Case (veya Scala Match-Case) göz önüne alındığında:
12: lookupswitch {
112785: 48 // case "red"
3027034: 76 // case "green"
98619139: 62 // case "blue"
default: 87
}
48: aload_2
49: ldc #17 // String red
51: invokevirtual #18
// Method java/lang/String.equals:(Ljava/lang/Object;)Z
54: ifeq 87
57: iconst_0
58: istore_3
59: goto 87
62: aload_2
63: ldc #19 // String green
65: invokevirtual #18
// Method java/lang/String.equals:(Ljava/lang/Object;)Z
68: ifeq 87
71: iconst_1
72: istore_3
73: goto 87
76: aload_2
77: ldc #20 // String blue
79: invokevirtual #18
// etc.
olarak yeniden yazabiliriz
12: lookupswitch {
112785: 48
3027034: 78
98619139: 64
default: 91
}
48: aload_2
49: ldc #17 // String red
51: invokevirtual #18
// Method java/lang/String.equals:(Ljava/lang/Object;)Z
54: ifeq 91 // 00 5B
57: iconst_0
58: istore_3
59: goto_w 91 // 00 00 00 5B
64: aload_2
65: ldc #19 // String green
67: invokevirtual #18
// Method java/lang/String.equals:(Ljava/lang/Object;)Z
70: ifeq 91
73: iconst_1
74: istore_3
75: goto_w 91
79: aload_2
81: ldc #20 // String blue
83: invokevirtual #18
// etc.
Aslında s denemek için "satır numaraları" değiştirerek bir hata yaptım çünkü ben gerçekten denemedim goto_w
. Ancak spesifikasyonda olduğundan, bunu yapmak mümkün olmalıdır.
Benim sorum derleyici veya başka bir bayt kodu oluşturucunun goto_w
yapılabileceğini göstermek dışında geçerli 65535 sınırı ile kullanmak için bir nedeni olup olmadığını ?
// ... repeat 10K times ...
Bu derler mi? Tek bir kaynak sınıfının boyutu için bir sınır olduğunu biliyorum ... ama tam olarak ne olduğunu bilmiyorum (kod üretimi bir şey gerçekten vurmak gördüm tek zamandır).