Я пытаюсь скомпилировать следующий код, используя пользовательский компилятор:JVM: Invalid индекс 1 в LocalVariableTable
public static void main([String] args)
{
long i = 2L
i *= 2L
System out println i
}
в результате компиляции, при использовании javap
, это Bytecode:
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=2, args_size=1
0: ldc2_w #14 // long 2l
3: lstore_1
4: lload_1
5: ldc2_w #14 // long 2l
8: lmul
9: lstore_1
10: getstatic #21 // Field java/lang/System.out:Ljava/io/PrintStream;
13: lload_1
14: invokevirtual #27 // Method java/io/PrintStream.println:(J)V
17: return
LocalVariableTable:
Start Length Slot Name Signature
0 17 1 i J
0 17 0 args [Ljava/lang/String;
MethodParameters:
Name Flags
args
Однако, когда я пытаюсь запустить Bytecode, JVM выбрасывает ClassFormatError
, который читает Invalid index 1 in LocalVariableTable
. Связано ли это с тем, что в LocalVariableTable слот 1 приходит перед слотом 0?
EDIT:
Если изменить переменную long
на int
, виртуальная машина не жалуется на все, даже если LocalVariableTable еще НЕСОРТИРОВАННАЯ:
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: iconst_2
1: istore_1
2: iload_1
3: iconst_2
4: imul
5: istore_1
6: getstatic #19 // Field java/lang/System.out:Ljava/io/PrintStream;
9: iload_1
10: invokevirtual #25 // Method java/io/PrintStream.println:(I)V
13: return
LocalVariableTable:
Start Length Slot Name Signature
0 13 1 i I
0 13 0 args [Ljava/lang/String;
MethodParameters:
Name Flags
args
'LocalVariableTable' предназначен только для отладки , вы можете опустить его, если он вам не нужен. Btw. если вам не нужен параметр 'args', вы также можете сохранить' long' в индекс '0', повторно используя место кадра стека. Тогда вам нужно всего 2 'locals' (а не то, что вам нужно * любую * локальную переменную в этом коде). Еще одно замечание: если вы хотите нажать 'long' constant' 2L', более эффективно использовать 'iconst_2', за которым следует' i2l', это занимает 2 байта, а 'ldc2_w' требует три байта * плюс * выделенный пул констант entry ... – Holger
Более эффективный, чем в * более мелком байт-кодексе * или * более быстрое исполнение *? – Clashsoft
Поскольку исполнение является специфичным для реализации/непредсказуемым, а JIT/оптимизаторы смогут обрабатывать одинаково, это имеет значение только размер байтового кода, но размер кода оказывает очевидное влияние на время загрузки/инициализации. – Holger