Immagino che la maggior parte di voi sappia che goto
è una parola chiave riservata nel linguaggio Java ma non viene effettivamente utilizzata. E probabilmente saprai anche che goto
è un codice operativo JVM (Java Virtual Machine). Mi sa che tutte le sofisticate strutture di controllo del flusso di Java, Scala e Kotlin sono, a livello di JVM, implementato utilizzando una combinazione di goto
e ifeq
, ifle
, iflt
, etc.
Osservando le specifiche JVM https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.goto_w vedo che c'è anche un goto_w
codice operativo. Considerando che goto
assume un offset di ramo a 2 byte, goto_w
accetta un offset di ramo a 4 byte. Le specifiche lo affermano
Sebbene l' istruzione goto_w abbia un offset di ramo di 4 byte, altri fattori limitano la dimensione di un metodo a 65535 byte (§4.11). Questo limite potrebbe essere aumentato in una versione futura di Java Virtual Machine.
Mi sembra che goto_w
sia a prova di futuro, come alcuni degli altri *_w
codici operativi. Ma mi viene anche in mente che forse goto_w
potrebbe essere usato con i due byte più significativi azzerati e i due byte meno significativi gli stessi di per goto
, con le regolazioni necessarie.
Ad esempio, dato questo caso Switch Java (o Scala Match Case):
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.
potremmo riscriverlo come
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.
In realtà non ho provato questo, dal momento che probabilmente ho fatto un errore cambiando i "numeri di riga" per adattarsi alla goto_w
s. Ma poiché è nelle specifiche, dovrebbe essere possibile farlo.
La mia domanda è se c'è un motivo che un compilatore o un altro generatore di bytecode potrebbe usare goto_w
con l'attuale limite 65535 oltre a dimostrare che può essere fatto?
// ... repeat 10K times ...
Quello si compila? So che esiste un limite alla dimensione di una singola classe di origine ... ma non so cosa sia esattamente (la generazione del codice è l'unica volta che ho visto qualcosa che l'ha effettivamente colpito).