나는 당신 goto
이 Java 언어로 예약 된 키워드이지만 실제로 사용되지 않는다는 것을 대부분 알고 있습니다. 또한 goto
JVM (Java Virtual Machine) opcode 임을 알고있을 것입니다 . 나는 JVM 수준에서의 조합을 사용하여 구현하는 모든에게 자바, 스칼라와 코 틀린의 정교한 제어 흐름 구조를 이해 할수 goto
과 ifeq
, ifle
, iflt
, 등
JVM을 사양을 보면 https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.goto_w 나는 거기에 또한 참조 goto_w
연산 코드가. goto
2 바이트 분기 오프셋을 사용하는 반면 goto_w
4 바이트 분기 오프셋을 사용합니다. 사양은
있지만 goto_w 명령 오프셋 4 바이트 지점을 얻어, 다른 요인은 65,535 바이트 (§4.11)에있어서의 크기를 제한한다. 이 한계는 다음 릴리스의 Java Virtual Machine에서 발생할 수 있습니다.
goto_w
다른 *_w
opcode 와 마찬가지로 미래를 보장하는 것처럼 들립니다 . 그러나 필요에 따라 조정 goto_w
하여 2 개의 더 중요한 바이트가 0으로 설정되고 2 개의 덜 중요한 바이트가와 동일하게 사용될 수 있다는 것도 나에게 발생 goto
합니다.
예를 들어, 다음 Java 스위치 케이스 (또는 스칼라 매치 케이스)가 주어진 경우 :
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.
우리는 그것을 다음과 같이 다시 쓸 수 있습니다
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.
goto_w
s 를 수용하기 위해 "줄 번호"를 변경하는 실수를했기 때문에 실제로 이것을 시도하지 않았습니다 . 그러나 그것은 사양에 있기 때문에 가능할 것입니다.
내 질문은 컴파일러 또는 다른 바이트 코드 생성기가 goto_w
현재 65535 제한으로 사용할 수있는 이유가 있는지 여부입니다 .
// ... repeat 10K times ...
컴파일? 단일 소스 클래스의 크기에 제한이 있다는 것을 알고 있지만 정확히 무엇인지 알 수 없습니다 (코드 생성은 실제로 실제로 발생하는 것을 본 유일한 시간입니다).