Je pense que la plupart d'entre vous savent que goto
c'est un mot-clé réservé dans le langage Java mais qu'il n'est pas réellement utilisé. Et vous savez probablement aussi qu'il goto
s'agit d'un opcode Java Virtual Machine (JVM). Je pense toutes les structures sophistiquées de contrôle de flux de Java, Scala et Kotlin sont, au niveau JVM, mis en œuvre en utilisant une combinaison de goto
et ifeq
, ifle
, iflt
, etc.
En regardant la spécification JVM https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.goto_w Je vois qu'il y a aussi un goto_w
opcode. Alors que goto
prend un décalage de branche de 2 octets, goto_w
prend un décalage de branche de 4 octets. La spécification indique que
Bien que l' instruction goto_w prenne un décalage de branche de 4 octets, d'autres facteurs limitent la taille d'une méthode à 65 535 octets (§4.11). Cette limite pourrait être relevée dans une future version de la machine virtuelle Java.
Cela me semble être à l' goto_w
épreuve du temps, comme certains des autres *_w
opcodes. Mais il me vient également à l'esprit que peut-être goto_w
pourrait être utilisé avec les deux octets plus significatifs mis à zéro et les deux octets moins significatifs identiques à goto
, avec des ajustements selon les besoins.
Par exemple, étant donné ce Java Switch-Case (ou 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.
nous pourrions le réécrire
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.
Je n'ai pas vraiment essayé cela, car j'ai probablement fait une erreur en changeant les "numéros de ligne" pour tenir compte du par goto_w
. Mais puisque c'est dans la spécification, il devrait être possible de le faire.
Ma question est de savoir s'il y a une raison qu'un compilateur ou un autre générateur de bytecode pourrait utiliser goto_w
avec la limite 65535 actuelle autre que pour montrer que cela peut être fait?
// ... repeat 10K times ...
Ça compile? Je sais qu'il y a une limite à la taille d'une classe source unique ... mais je ne sais pas ce que c'est précisément (la génération de code est la seule fois où j'ai vu quelque chose l'atteindre).