A bytecode implemented method should be something like this:
@BytecodeImpl({
"LABEL METHOD_HEAD",
"GETSTATIC Ljava/lang/System;out:Ljava/io/PrintStream;",
"LDC (STRING \"Hello BCIG!\")",
"INVOKEVIRTUAL Ljava/io/PrintStream;println(Ljava/lang/String;)V",
"RETURN",
"LABEL METHOD_TAIL",
"MAXS 2 0"
})
private static void sayHelloBCIG() {
throw new BytecodeImplError();
}The method must be annotated by @BytecodeImpl, and must throw a newly constructed BytecodeImplError
as BytecodeImplGenerator may check this in the future versions.
The string array in @BytecodeImpl is called BCII, which stands for Bytecode Implementation Instructions.
This will be introduced later.
The method should be declared correctly, just like BCIG doesn't exist. Examples: if you like to declare a method with parameter(s) and a return value, you can code like this.
@BytecodeImpl({
"LABEL METHOD_HEAD",
"GETSTATIC Ljava/lang/System;out:Ljava/io/PrintStream;",
"ALOAD 0",
"INVOKEVIRTUAL Ljava/io/PrintStream;println(Ljava/lang/String;)V",
"LDC (STRING \"Return String\")",
"LABEL RELEASE_PARAMETER",
"ARETURN",
"LOCALVARIABLE text [java/lang/String; METHOD_HEAD RELEASE_PARAMETER 0",
"MAXS 2 1"
})
private static String sayString(String text) {
throw new BytecodeImplError();
}A BCII should be a string, which stands for Bytecode Implementation Instruction.
For a BCII, it should consist of an operator, a space (if parameters is required by this operator) and parameter(s). Each parameter must be separated by a space as well. These are legal BCII.
ALOAD 0:ALOADis the operator.0is the parameter.INVOKEVIRTUAL Ljava/io/PrintStream;println(Ljava/lang/String;)V:INVOKEVIRTUALis the operaotr.Ljava/io/PrintStream;println(Ljava/lang/String;)Vis the parameter.LOCALVARIABLE text [java/lang/String; METHOD_HEAD RELEASE_PARAMETER 0:LOCALVARIABLEis the operator.text,[java/lang/String;andMETHOD_HEAD RELEASE_PARAMETER 0
Each BCII describes a bytecode, or a part of the method info.
For BCIIs that describes a bytecode, they are cataloged base on the way that ASM declares them.
The operator is directly the name declared in Opcodes.
The parameter is not needed.
Examples: DUP, ARETURN, MONITORENTER
The operator is directly the name declared in Opcodes.
The parameter should be the name declared in Opcodes without "T_" prefix, or directly the value, which depends on the operator.
Examples: NEWARRAY BOOLEAN, BIPUSH 10 and SIPUSH 800
The operator is directly the name declared in Opcodes.
The parameter should be an int value which stands for the index of a local variable.
Examples: ILOAD 0, ALOAD 8
TODO
The operator is directly the name declared in Opcodes.
The parameter should be a VM field method descriptor.
Examples: GETSTATIC Ljava/lang/System;out:Ljava/io/PrintStream;, GETFIELD Lorg/objectweb/asm/MethodVisitor;api:I
The operator is directly the name declared in Opcodes, with a new operator INVOKEINTERFACESTATIC, which stands for invoking a static mehod in an interface.
The parameter should be a VM method descriptor.
Examples: INVOKESTATIC Ljava/lang/System;getProperty(Ljava/lang/String;)Ljava/lang/String;, INVOKEVIRTUAL Ljava/io/PrintStream;println(Ljava/lang/String;)V and INVOKEINTERFACE Ljava/lang/Runnable;run()V
TODO
The operator is directly the name declared in Opcodes.
The parameter should be a Label ID.
Examples: GOTO TARGET_LABEL, IFNULL targetLabel
The operator should always be LABEL.
The parameter should be a Label ID.
Examples: LABEL METHOD_BEGIN, LABEL targetLabel2
This depends on the constant type.
The operator should always be LDCString.
The first parameter should always be STRING.
The next parameter should be a string placed in an apostrophe.
Examples: LDC (STRING \"Hello World!\") which stands for push Hello World! into the JVM runtime stack, is a legal BCII.
TODO
TODO
TODO
TODO
TODO
TODO
The operator should always be LOCALVARIABLE.
The parameter should be the name, the VM descriptor of the type, the start Label ID, the end Label ID and the index of this local variable.
Examples: LOCALVARIABLE more [C START_LABEL END_LABEL 0
The operator should always be MAXS.
The parameter should be the max stack number and the max local number.
Examples: MAXS 2 1