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 gotoe 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_wcodice operativo. Considerando che gotoassume un offset di ramo a 2 byte, goto_waccetta 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_wsia a prova di futuro, come alcuni degli altri *_wcodici operativi. Ma mi viene anche in mente che forse goto_wpotrebbe 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_ws. 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_wcon 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).