| APPENDIX A |
This chapter describes JASM syntax, and how to encode class files
using this
syntax. Jasm is a java
assembler that accepts text in the JASM
format and produces a .class file for use
with a Java Virtual Machine. Jasm's
primary
use
is
as
a
tool for producing specialized tests for testing a JVM
implementation
This chapter describes JASM syntax in the following sections:
JASM syntax can come in one of two variations: short-form or
verbose-form. Short form uses Java-style names to refer to items
in a constant-pool. Verbose form uses explicit constant-pool
indexes to refer to items in the constant pool. The normal output
from JDIS produces jasm files in the short-form. Using the -g
option for JDIS (ie. jdis -g file.class) produces JASM source in
the verbose-form.
The source text file can be free form (newlines are considered blanks) and may contain Java-style commenting. The first line of a JASM file represents the name of the resulting file in the destination directory. This name does not affect the content of the resulting file. This line has two forms:
file FILENAMEor
class CLASSNAMEIn the latter case, extension
.class will be added to
form FILENAME. Jasm's -d option allows you to define the
destination
directory. A list of structured dataWriter items follows the class name. The
length (in bytes) of each item
is determined by its representation.
Description formats
TERM1|TERM2 TERM1 or TERM2 (not both) [TERM] TERM is optional TERM... TERM repeated 1 or more times [TERM...] TERM repeated 0 or more times "sequence of" all the following terms are mandatory, in the order given. "set of" any of following terms, or none of them, may appear in any order. However, repetitions are not allowed. "list of" any of following terms, or none of them, may appear in any sequence. If more than one term appear, they are separated by commas (',')
Lexical Structure
The source text file can be free form (newlines, tabs, and blank spaces are equivalent). Additionally, the source may contain standard Java and C++ comments.
STRING,NUMBER, andIDENTare treated the same as in the Java Language Specification. One difference is that LETTERs include also `/', `<', `>', `(', and `)' .
STRING:" [ STRING_CHARACTER... ] "NUMBER:DIGIT...IDENT:LETTER [ LETTER_OR_DIGIT ...]ACCESS(depends on the context): set ofabstract final interface native private protected public static super synchronized transient volatile deprecated synthetic bridge varargsNot all access bits make sense for all declarations: for example, the "super" and "interface" access flags are applied to classes only.
If an access bit is used improperly, the assembler prints a warning, but places the bit in the access set.
Note that
deprecatedandsynthetickeywords are not translated to access flags in the Java sense. For these jasm generates a correspondingDeprecatedorSyntheticattributes instead of access bits. Thesyntheticaccess flag is used to mark compiler generated members not seen in the source (for example, a field reference to an anonymous outer class).Local names represent labels, rangePC-labels and local variables. Their scope is constrained by method parenthesis.
TAG: one ofint float long double Asciz String class Field Method NameAndType InterfaceMethod MethodType MethodHandle InvokeDynamic Dynamic
LOCAL_NAME:IDENT
CONSTANT_INDEX:#NUMBEREach CONSTANT_INDEX represents a reference into the constant pool at the specified location.
INTERFACES:list of CONSTANT_CELL(class|@interface|interface) TOP_LEVEL_COMPONENT: one of CONSTANT_DECLARATION FIELD_DECLARATION METHOD_DECLARATION
INNER_CLASS_DECLARATIONS CLASS: sequence of ANNOTATIONS CLASS_ACCESS CONSTANT_CELL(class|@interface|interface) [extends
CONSTANT_CELL(class)]
[implements INTERFACES] [version INTEGER:INTEGER] {
[TOP_LEVEL_COMPONENT...] }CLASS_ACCESS:
list
of[public][final][super][interface][abstract][synthetic][annotation][enum]
The extends CONSTANT_CELL(class) clause places the
"super" element of the
class file. The implements INTERFACES clause places the
table of interfaces.
Since the assembler does not distinguish interfaces and ordinary
classes
(the only difference is one access bit), the table of interfaces of an
interface class must be declared with implements keyword,
and not extends, as in Java language.
Note:The last two rules allow TOP_LEVEL_COMPONENT
to appear in any order and number. For example, you can split constant
pool table into several parts, mixing constants and method
declarations.
MODULE: sequence of ANNOTATIONS [MODULE_FLAGS] moduleContent CONSTANT_CELL(moduleContent) [version INTEGER:INTEGER] {[TOP_LEVEL_MODULE_PROPERTIES...]}TOP_LEVEL_MODULE_PROPERTIES: one of MODULE_REQUIRES MODULE_EXPORTS MODULE_OPENS MODULE_USES MODULE_PROVIDES MODULE_FLAGS:set
of[open]PACKAGE_DECLARATION: package IDENT; CLASS_FILE: sequence of PACKAGE_DECLARATION CLASS... MODULE_FILE: MODULE... SOURCE_FILE: MODULE_FILE|CLASS_FILE
A CONSTANT_CELL refers to an element in the constant
pool.
It may refer to the element either by its index or its value:
CONSTANT_CELL: CONSTANT_INDEX TAGGED_CONSTANT_VALUE TAGGED_CONSTANT_VALUE: [TAG] CONSTANT_VALUE
A TAG may be omitted when the context only allows one kind of a tag.
For example, the argument of an anewarray instruction
should be a CONSTANT_CELL which represents a class, so
instead of
anewarray class java/lang/Objectone may write:
anewarray java/lang/ObjectIt is possible to write another tag, e.g.:
anewarray String java/lang/ObjectHowever, the resulting program will be incorrect.
Another example of an implicit tag (eg. a context which implies tag) is the header of a class declaration. You may write:
aClass {
}
which is equivalent to:
class aClass {
}
Below, the tag implied by context will be included in the rules, e.g.:
CONSTANT_VALUE(int).
The exact notation of CONSTANT_VALUE depends on the
(explicit or implicit) TAG.
TAGGED_CONSTANT_VALUE: Note
When the JASM parser encounters an InvokeDynamic constant, it creates an entry in the BootstrapMethods attribute (the BootstrapMethods attribute is produced if it has not already been created). The entry contains a reference to the MethodHandle item in the constant pool, and, optionally, a sequence of references to additional static arguments (ldc-type constants) to the bootstrap method
INVOKESUBTAGs for MethodHandle and (const) InvokeDynamic are defined as follows and can be presented as either an index or a tag:
INVOKESUBTAG: [INVOKESUBTAG_INDEX]
REF_GETFIELD[1]REF_GETSTATIC[2]REF_PUTFIELD[3]REF_PUTSTATIC[4]REF_INVOKEVIRTUAL[5]REF_INVOKESTATIC[6]REF_INVOKESPECIAL[7]REF_NEWINVOKESPECIAL[8]REF_INVOKEINTERFACE[9]
Static arguments for an InvokeDynamic constant are defined as follows:
INVOKEDYNAMIC_STATIC_ARGUMENTS: INVOKEDYNAMIC_STATIC_ARG ',' ... INVOKEDYNAMIC_STATIC_ARG: (one of) INVOKEDYNAMIC_STATIC_ARG_CONSTANT_VALUE INVOKEDYNAMIC_STATIC_ARG_CONSTANT_VALUE:
intINTEGERlong[INTEGER|LONG]float[FLOAT|INTEGER]double[FLOAT|DOUBLE|INTEGER|LONG]classCONSTANT_NAMEStringCONSTANT_NAMEMethodHandleINVOKESUBTAG:CONSTANT_FIELDMethodTypeCONSTANT_NAME
INTEGER, LONG, FLOAT, and DOUBLE
correspond to IntegerLiteral
and FloatingPointLiteral as described in
The
Java
Language
Specification. If a double-word constant (LONG
or DOUBLE) is represented with a single-word value (INTEGER
or FLOAT, respectively), single-word value
is simply promoted to double-word, as described in
The
Java
Language
Specification. If floating-point constant (FLOAT
or DOUBLE) is represented with an integral value
(INTEGER or LONG, respectively),
the result depends on whether the integral number is preceded with the
keyword
"bits". If "bits" is not used, the result is a floating-point number
closest in value to the decimal number. If the keyword "bits" is used,
the floating-point constant takes bits of the integral value without
conversion.
Thus,
float 2;means the same as
float 2.0f;and the same as
float bits 0x40000000;while
float bits 2;actually means the same as
float bits 0x00000002;and the same as
float 2.8026e-45f
CONSTANT_NAME: CONSTANT_INDEX
EXTERNAL_NAME EXTERNAL_NAME: IDENT STRING
External names are names of class, method, field, or type, which stay
in resulting .class file, and may be represented both by
IDENT or by STRING (which is useful when
name contains non-letter characters).
NAME_AND_TYPE: CONSTANT_INDEXCONSTANT_NAME:CONSTANT_NAME
In this second example, the first CONSTANT_NAME denotes
the name of a field and second denotes its type.
CONSTANT_FIELD: CONSTANT_INDEX[CONSTANT_NAME.]NAME_AND_TYPE
In this third example, CONSTANT_NAME denotes to the class
of a field. If CONSTANT_NAME is omitted, the current
class is
assumed.
Constant declarations are demonstrated in the examples below:
const #1=int 1234
, #2=String "a string"
, #3=Method get:I
;
CONSTANT_DECLARATION: const CONSTANT_DECLARATORS ; CONSTANT_DECLARATORS: list of CONSTANT_DECLARATOR CONSTANT_DECLARATOR: CONSTANT_INDEX = TAGGED_CONSTANT_VALUE FIELD_DECLARATION: ANNOTATIONS FIELD_ACCESS Field
FIELD_DECLARATORS ; FIELD_DECLARATORS: list of FIELD_DECLARATOR FIELD_DECLARATOR: EXTERNAL_NAME:CONSTANT_NAME [:SIGNATURE] [ = TAGGED_CONSTANT_VALUE ]FIELD_ACCESS:
list
of[public|private|protected][final][static][volatile][transient][synthetic][enum]public static Field
field1:I = int 1234,
field2:"Ljava/lang/String;",
field3:"Ljava/util/List;":"Ljava/util/List<+Ljava/lang/String;>"
;
Access bits (public and static) are applied both to field1 and
field2.
The EXTERNAL_NAME denotes the name of the field, CONSTANT_NAME
denotes its type, TAGGED_CONSTANT_VALUE
denotes initial value.
METHOD_DECLARATION: sequence of ANNOTATIONS METHOD_ACCESS Method
EXTERNAL_NAME:CONSTANT_NAME
[THROWS]
STACK_SIZE
[LOCAL_VAR_SIZE]
{ INSTRUCTION_STATEMENT...
ANNOTATIONS }
The EXTERNAL_NAME denotes the name of the method, CONSTANT_NAME
denotes its type.
METHOD_ACCESS:
list
of[public|private|protected][static][final][synthetic][bridge][varargs][native][abstract][strict][synthetic]THROWS: throws EXCEPTIONS EXCEPTIONS: list of CONSTANT_CELL(class)
The meaning of the THROWS clause is the same as in Java
Language Specification - it forms Exceptions attribute of a method.
Jasm itself does not use this attribute in any way.
STACK_SIZE: stack NUMBER
The NUMBER denotes maximum operand stack size of the
method.
LOCAL_VAR_SIZE: locals NUMBER
The NUMBER denotes number of local variables of the
method. If omitted, it is calculated by assembler according to the
signature of
the method and local variable declarations.
VM Instructions
INSTRUCTION_STATEMENT:[NUMBER] [LABEL:] INSTRUCTION|PSEUDO_INSTRUCTION ;Jasm allows for a
NUMBER(which is ignored) at the beginning of each line. This is allowed in order to remain consistent with the jdis disassembler. Jdis puts line numbers in disassembled code that may be reassembled using Jasm without any additional modifications.
INSTRUCTION:OPCODE [ARGUMENTS]ARGUMENTS: list ofARGUMENTARGUMENT:NUMBER LABEL LOCAL_VARIABLE TRAP_IDENT CONSTANT_CELL SWITCHTABLE TYPELABEL:NUMBER IDENTLOCAL_VARIABLE:NUMBER IDENTTRAP_IDENT:IDENTTYPE:NUMBER boolean byte char int float long double classSWITCHTABLE:{ [NUMBER:LABEL...] [default:LABEL] }SWITCHTABLE example: Java_text
switch (x) {
case 11:
x=1;
break;
case 12:
x=2;
break;
default:
x=3;
}
will be coded in assembler as follows:
tableswitch {
11: L24;
12: L29;
default: L34
}
L24: iconst_1;
istore_1;
goto L36;
L29: iconst_2 ;
istore_1;
goto L36;
L34: iconst_3;
istore_1;
L36: ....
OPCODE is any mnemocode from the instruction set. If mnemocode needs an ARGUMENT, it cannot be omitted. Moreover, the kind (and number) of the argument(s) must match the kind (and number) required by the mnemocode:
aload, astore, fload, fstore, iload, istore, lload, lstore, dload, dstore, ver, endvar: LOCAL_VARIABLEiinc: LOCAL_VARIABLE, NUMBERsipush, bipush, bytecode: NUMBERtableswitch, lookupswitch: SWITCHTABLEnewarray: TYPEjsr, goto, ifeq, ifge, ifgt, ifle, iflt, ifne, if_icmpeq, if_icmpne, if_icmpge, if_icmpgt, if_icmple, if_icmplt, if_acmpeq, if_acmpne, ifnull, ifnonnull, try, endtry: LABELjsr_w, goto_w: LABELldc_w, ldc2_w, ldc: CONSTANT_CELLnew, anewarray, instanceof, checkcast, CONSTANT_CELL(class)multianewarray NUMBER,CONSTANT_CELL(class)putstatic, getstatic, putfield, getfield: CONSTANT_CELL(Field)invokevirtual, invokenonvirtual, invokestatic: CONSTANT_CELL(Method)invokeinterface: NUMBER, CONSTANT_CELL(Method)invokedynamic: CONSTANT_CELL(InvokeDynamic)aaload, aastore, aconst_null, aload_0, aload_1, aload_2, aload_3, aload_w , areturn, arraylength, astore_0, astore_1, astore_2, astore_3, astore_w, athrow, baload, bastore, caload, castore, d2f, d2i, d2l, dadd, daload, dastore, dcmpg, dcmpl, dconst_0, dconst_1, ddiv, dead, dload_0, dload_1, dload_2, dload_3, dload_w , dmul, dneg, drem, dreturn, dstore_0, dstore_1, dstore_2, dstore_3, dstore_w, dsub, dup, dup2, dup2_x1, dup2_x2, dup_x1, dup_x2, f2d, f2i, f2l, fadd, faload, fastore, fcmpg, fcmpl, fconst_0, fconst_1, fconst_2, fdiv, fload_0, fload_1, fload_2, fload_3, fload_w, fmul, fneg, frem, freturn , fstore_0, fstore_1, fstore_2, fstore_3, fstore_w, fsub , i2b, i2c, i2d, i2f, i2l, i2s, iadd, iaload, iand, iastore, iconst_0, iconst_1, iconst_2, iconst_3, iconst_4, iconst_5, iconst_m1, idiv, iinc_w, iload_0, iload_1, iload_2, iload_3, iload_w, imul, ineg, int2byte, int2char, int2short, ior, irem, ireturn, ishl, ishr, istore_0, istore_1, istore_2, istore_3, istore_w, isub, iushr, ixor, l2d, l2f, l2i, label, ladd, laload, land, lastore, lcmp, lconst_0, lconst_1, ldiv, lload_0, lload_1, lload_2, lload_3, lload_w, lmul, lneg, lor, lrem, lreturn, lshl, lshr, lstore_0, lstore_1, lstore_2, lstore_3, lstore_w, lsub, lushr, lxor, monitorenter, monitorexit, nonpriv, nop, pop, pop2, priv, ret, return, ret_w, saload, sastore, swap, wide
<No Arguments>InvokeDynamic Instructions
InvokeDynamic instructions are instructions that allow dynamic binding of methods to a call site. These instructions in JASM form are rather complex, and the JASM assembler does some of the necessary work to create a BootstrapMethods attribute for entries of binding methods.
class Test version 51:0 { Method m:"()V" stack 0 locals 1 { invokedynamic InvokeDynamic REF_invokeSpecial:bsmName:"()V" // information about bootstrap method :methName:"(I)I" // dynamic call-site name ("methName") plus the argument and return types of the call ("(I)I") int 1, long 2l; // optional sequence of additional static arguments to the bootstrap method (ldc-type constants) } } // end Class TestThis JASM code has an invokedynamic instruction of the form: invokedynamic InvokeDynamic (CONSTANT_CELL(INVOKEDYNAMIC)) where the INVOKEDYNAMIC constant is represented as specified
(i.e. invokedynamic InvokeDynamic INVOKESUBTAG : CONSTANT_FIELD (bootstrapmethod signature) : NAME_AND_TYPE (CallSite) [Arguments (Optional)] ).The JASM assembler creates the appropriate constant entries and entries into the BootstrapMethods attribute in a resulting class file.
You can also create InvokeDynamic constants and BootstrapMethods explicitly:
#22; //class Test3
version 51:0
{
const #1 = InvokeDynamic 0:#11; // REF_invokeSpecial:Test3.bsmName:"()V":name:"(I)I" int 1, long 2l
const #2 = Asciz "Test3";
const #3 = long 2l;
const #5 = class #6; // java/lang/Object
const #6 = Asciz "java/lang/Object";
const #7 = Asciz "name";
const #8 = int 1;
const #9 = Asciz "SourceFile";
const #10 = Asciz "Test3.jasm";
const #11 = NameAndType #7:#21; // name:"(I)I"
const #12 = Asciz "()V";
const #13 = Method #22.#17; // Test3.bsmName:"()V"
const #14 = Asciz "Code";
const #15 = Asciz "m";
const #16 = Asciz "BootstrapMethods";
const #17 = NameAndType #20:#12; // bsmName:"()V"
const #18 = Asciz "LineNumberTable";
const #19 = MethodHandle 7:#13; // REF_invokeSpecial:Test3.bsmName:"()V"
const #20 = Asciz "bsmName";
const #21 = Asciz "(I)I";
const #22 = class #2; // Test3
const #23 = class #6; // java/lang/Object
Method #15:#12
stack 0 locals 1
{
0: invokedynamic InvokeDynamic #1; // InvokeDynamic REF_invokeSpecial:Test3.bsmName:"()V":name:"(I)I" int 1, long 2l;
}
BootstrapMethod #19 #8 #3;
} // end Class Test3In this example,
const #1 = InvokeDynamic 0:#11;is the InvokeDynamic constant that refers to BootstrapMethod at index '0' in the BootstrapMethods Attribute (BootstrapMethod #19 #8 #3;which refers to the MethodHandle at const #19, plus 2 other static args (at const #8 and const #3).
Pseudo instructions are 'assembler directives', and not really instructions (in the VM sense) They typically come in two forms: Code-generating Pseudo-Instructions, and Attribute-Generating Pseudo-Instructions.
Code-Generating Pseudo-Instructions
The bytecode directive instructs the assembler to put a collection of raw bytes into the code attribute of a methodK
bytecode NUMBERS- NUMBERS is list of NUMBERs (divided by COMMA).
Insert bytes in place of the instruction. May have any number of numeric arguments, each of them to be converted into a byte and inserted in method's code.Attribute-Generating Pseudo-Instructions
The rest of pseudo_instructions do not produce any bytecodes, and are used to form tables: local variable table, exception table,
Stack Maps, and Stack Map Frames. Line Number Tables can not be specified, but they are constructed by the assembler itself.Local Variable Table Attribute Generation
var LOCAL_VARIABLE- Starts local variable range
endvar LOCAL_VARIABLE- Ends local variable range. LOCAL_VARIABLE means name or index of local variable table entry.
Example:
static void main (String[] args) {
Tester inst = new Tester();
inst.callSub();
}will be coded in assembler as follows:
static Method #8:#9 // main:"([Ljava/lang/String;)V"
stack 2 locals 2
{
4 var 0; // args:"[Ljava/lang/String;"
0: new #1; // class Tester;
3: dup;
4: invokespecial #2; // Method "<init>":"()V";
7: astore_1;
6 var 1; // inst:"LTester;"
8: aload_1;
9: invokevirtual #3; // Method callSub:"()V";
7 12: return;
endvar 0, 1;
}Exception Table Attribute Generation
To generate exception table, three pseudo-instructions are used.
try TRAP_IDENT- Starts rangePC range
endtry TRAP_IDENT- Ends rangePC range
catch TRAP_IDENT CONSTANT_CELL(class)- Starts exception handler.
TRAP_IDENTrepresents the name or number of an exception table entry.CONSTANT_CELLin "catch" pseudo_instruction means catch type. Each exception table entry contains 4 values:start-pc, end-pc, catch-pc, catch-type. In jasm, each entry is denoted with some (local) identifier, as an example:TRAP_IDENT.To set start-pc, place "try TRAP_IDENT" before the instruction with the desirable program counter. Similarly, use "endtry TRAP_IDENT" for end-pc and "catch TRAP_IDENT, catch-type" for catch-pc and catch-type (which is usually a constant pool reference). Try, endtry, and catch pseudoinstructions may be placed in any order. The order of entries in exception table is significant (see JVM specification). However, the only way to control this order is to place catch-clauses in appropriate textual order: assembler adds an entry in the exception table each time it encounters a catch-clause.
Example:
try {
try {
throw new Exception("EXC");
} catch (NullPointerException e){
throw e;
} catch (Exception e){
throw e;
}
} catch (Throwable e){
throw e;
}will be coded in assembler as follows:
try R1, R2; // single "try" or "endtry" can start several regions
new class java/lang/Exception;
dup;
ldc String "EXC";
invokespecial java/lang/Exception.<init>:"(Ljava/lang/String;)V";
athrow;
endtry R1;
catch R1 java/lang/NullPointerException; // only one "catch" per entry allowed
astore_1;
aload_1;
athrow;
catch R1 java/lang/Exception; // same region (R1) can appear in different catches
astore_1;
aload_1;
athrow;
endtry R2;
catch R2 java/lang/Throwable;
astore_1;
aload_1;
athrow;
StackMap Table Attribute Generation
Stack Maps are denoted by the pseudo-op opcode stack_map, and they can be identified by three basic items:
StackMapStatement =stack_map(stackMap_Item_MapType |stackMap_Item_Object | stackMap_Item_NewObject)stackMap_Item_MapType = (bogus | int | float | double | long | null | this | CP)
stackMap_Item_Object = CONSTANT_CELL_CLASS
stackMap_Item_NewObject =atLABELAll stack_map directives are collected by the assembler, and are used to create a StackMap Table attribute.
Example 1 (MapType):
public Method "<init>":"()V"
stack 1 locals 1
{
aload_0;
invokespecial Method java/lang/Object."<init>":"()V";
return;
stack_frame_type full;
stack_map bogus;
...
}
Example 2 (Object):
public Method "<init>":"()V"
stack 2 locals 1
{
...
stack_map class java/lang/Object;
nop;
return;
}
Example 3 (NewObject):
public Method "<init>":"()V"
stack 2 locals 1
{
...
stack_map at L5;
nop;
return;
}
StackFrameType Table Attribute Generation
StackFrameTypes are similar assembler directives as StackMap. These directives can appear anywhere in the code, and the assembler will collect them to produce a StackFrameType attribute.
StackFrameStatement =stack_frame_typeframe_typeframe_type = (same | stack1 | stack1_ex | chop1 | chop2 | chop3 | same_ex | append | full)
Example 1 (full stack frame type):
public Method "<init>":"()V"Example 2 (append, chop2, and same stack frame types):
stack 1 locals 1
{
aload_0;
invokespecial Method java/lang/Object."<init>":"()V";
return;
stack_frame_type full;
stack_map bogus;
...
}
public Method foo:"(Z)V"
stack 2 locals 5
{
...
iload_2;
iconst_2;
if_icmpge L30;
L27: stack_frame_type append;
locals_map int, int;
iconst_2;
istore 4;
L30: stack_frame_type chop2;
goto L9;
L33: stack_frame_type same;
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc String "Chop2 attribute test";
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
return;
...
}LocalsMap Table
Locals Maps are typically associated with a stack_frame_type, and are accumulated per stack frame. They typically follow a stack_frame_type directive.
LocalsMapStatement =locals_maplocals_type (, locals_type )*locals_type = stackMap_Item_MapType | CONSTANT_CELL_CLASS
Example (a locals map specifying 2 ints):public Method foo:"(Z)V"
stack 2 locals 5
{
...
iload_2;
iconst_2;
if_icmpge L30;
L27: stack_frame_type append;
locals_map int, int;
iconst_2;
istore 4;
L30: stack_frame_type chop2;
goto L9;
L33: stack_frame_type same;
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc String "Chop2 attribute test";
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
return;
...
}
INNER_CLASS_DECLARATIONS: list of INNER_CLASS_DECLARATION INNER_CLASS_DECLARATION: INNER_CLASS_ACCESS InnerClass
[INNER_CLASS_NAME=]?
INNER_CLASS_INFO
[of OUTER_CLASS_INFO]? ; INNER_CLASS_NAME: IDENT | CPX_name INNER_CLASS_INFO: CONSTANT_CELL(class) OUTER_CLASS_INFO: CONSTANT_CELL(class)INNER_CLASS_ACCESS: list of[public|protected|private][static][final][interface][abstract][synthetic][annotation][enum]InnerClass InCl=class test$InCl of class test;
Member annotations are a subset of the basic annotations support provided in JDK 5.0 (1.5). These are annotations that ornament Packages, Classes, and Members either visibly (accessible at runtime) or invisibly (not accessible at runtime). In JASM, visible annotations are denoted by the token @, while invisible annotations are denoted by the token @-.
ANNOTATIONS: [ANNOTATION_DECLARATION]+; ANNOTATION_DECLARATION: @+|@- ANNOTATION_NAME
[ANNOTATION_VALUE_DECLARATIONS]The '@+' token identifies a Runtime Visible Annotation, where the '@-' token identifies a Runtime Invisible Annotation.
ANNOTATION_NAME: IDENT ANNOTATION_VALUE_DECLARATIONS: list
of (comma separated)ANNOTATION_VALUE_DECLARATION ANNOTATION_VALUE_DECLARATION: [ANNOTATION_VALUE_IDENT=] [ANNOTATION_VALUE]ANNOTATION_VALUE_IDENT: IDENT ANNOTATION_VALUE: ANNOTATION_VALUE_PRIMITIVE | Array of
ANNOTATION_VALUE_PRIMITIVE ANNOTATION_VALUE_PRIMITIVE: PRIMITIVE_TYPE | STRING | CLASS | ENUM |
ANNOTATION_DECLARATIONCLASS: class CONSTANT_CELL(class) ENUM: enum CONSTANT_CELL(class) CONSTANT_CELL(string) (where
string is Enum type name) PRIMITIVE_TYPE: BOOLEAN | BYTE | CHAR | SHORT | INTEGER | LONG | FLOAT |
DOUBLE@+ClassPreamble {
author = "John Doe",
date = "3/17/2002",
currentRevision = 6,
lastModified = "4/12/2004",
lastModifiedBy = "Jane Doe",
reviewers = {
"Alice",
"Bob",
"Cindy"}
}
super public class MyClass
version 50:0
{
...
@-FieldPreamble {
author = "Mustafa",
date = "3/17/2009",
currentRevision = 4
}
Field foo:I;
......
@+FieldPreamble {
boolAnnot = boolean 1, // Boolean
charBear = char 97, // Char
sharkByte = byte 17, // Byte
shortCircuit = short 4386, // Short
integerHead = 42, // Int
longJohnSilver = 55l, // Long
floatBoat = 1.0f, // Float
doubleDip = 10.0d, // Double
stringBeans = "foo", // String
severity = enum FieldPreamble$Severity IMPORTANT, // Enum
classAnnot = class FieldPreamble$FooBall, // Class
tm = @+Trademark { description = "embedded", owner = "ktl"} // Annotation
}
Field foo:I;
@+java/lang/Deprecated {
since = "9",
forRemoval = boolean true
}
moduleContent my.moduleContent
version 53:0
{
...
Note:
JASM does not enforce the annotation value declarations like a
compiler would. It only checks to see that an annotation
structure is well-formed.
Member annotations are a subset of the basic annotations support provided in JDK 7.0 (1.7). These are annotations that ornament Packages, Classes, and Members either visibly (accessible at runtime) or invisibly (not accessible at runtime). In JASM, visible annotations are denoted by the token @T+, while invisible annotations are denoted by the token @T-.
TYPE_ANNOTATION_DECLARATION:
@T+|@T- ANNOTATION_NAME
[TYPE_ANNOTATION_VALUE_DECLARATIONS]
TYPE_ANNOTATION_VALUE_DECLARATIONS:
list
of
(comma
separated)
TYPE_ANNOTATION_VALUE_DECLARATION
TYPE_ANNOTATION_VALUE_DECLARATION:
{ {
ANNOTATION_VALUE_DECLARATION+
} TARGET PATH }
TARGET:
{ TARGET_TYPE TARGET_INFO }
TARGET_TYPE:
|
|
|
|
METHOD_TYPE_PARAMETER
|
|
CLASS_EXTENDS
|
|
|
|
|
|
|
|
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TARGET_INFO_TYPE: TYPEPARAM | SUPERTYPE |
TYPEPARAM_BOUND
| EMPTY | METHODPARAM | EXCEPTION | LOCALVAR | CATCH | OFFSET
| TYPEARG
TYPEPARAM:
paramIndex(INTEGER)
SUPERTYPE:
typeIndex(INTEGER)typeIndex(INTEGER)
TYPEPARAM_BOUND:
paramIndex(INTEGER)
boundIndex(INTEGER)
EMPTY:
METHODPARAM:
index(
paramIndex(INTEGER)
EXCEPTION:
typeIndex(INTEGER)
LOCALVAR:
{ LVENTRY }+numEntries
LVENTRY:
startpc(INTEGER)
length(INTEGER)
index(INTEGER)
CATCH:
catch(INTEGER)
OFFSET:
offset(INTEGER)
TYPEARG:
offset(INTEGER)
typeIndex(INTEGER)
PATH: list
of (space separated)
{
PATH_ENTRY+
}
PATH_ENTRY:
{ PATH_KIND PATH_INDEX }
PATH_KIND:
ARRAY | INNER_TYPE | WILDCARD
| TYPE_ARGUMENT
PATH_INDEX:
INTEGER
Parameter annotations are another subset of the basic annotations
support provided in JDK 5.0 (1.5). These are annotations that
ornament Parameters to methods either visibly (accessible at runtime)
or invisibly (not accessible at
runtime). In JASM, visible parameter annotations are denoted by the
token @+, while invisible parameter annotations are denoted
by the token @-.
Parameter names come from an attribute introduced in JDK 8.0
(1.8). These are fixed parameter names that are used to ornament
parameters on methods. In Jasm, parameter names are identified by
the token # followed by { } braclets
METHOD DECLARATION: MODIFIERS Method METHOD_NAME:"METHOD_SIGNATURE"
[STACK_DECL] [LOCALS_DECL] [PARAMETERS_DECL] {[CODE]}PARAMETERS_DECL: [PARAMETER_DECL]N (where N < number of params
in method, each N is a unique param number)PARAMETER_DECL: PARAM_NUM : [PARAM_NAME_DECL] [ANNOTATION_DECLARATIONS]PARAM_NAME_DECL: #{ name PARAM_ACCESS}PARAM_ACCESS: list of[final][synthetic][mandated]public class MyClass2 {
...
public int doSomething(
@VisParamPreamble ( author = "gummy" ) @InVisParamPreamble ( author = "bears" ) int barber,
boolean of,
@VisParamPreamble ( author = "sour" ) @InVisParamPreamble ( author = "worms" ) int seville,
@InVisParamPreamble1 ( reviewers = {"Dilbert", "Garfield"} ) boolean pastrami) {
...
}
...
}
super public class MyClass2
version 50:0
{
...
public Method doSomething:"(IZIZ)I"
stack 2 locals 5
0: #{P0 mandated} @+VisParamPreamble { author = "gummy" } @-InVisParamPreamble { author = "bears" }
1: #{P1 final synthetic mandated}
2: #{P2 mandated} @+VisParamPreamble { author = "sour" } @-InVisParamPreamble { author = "worms" }
3: #{P3 mandated} @-InVisParamPreamble1 { reviewers = { "Dilbert", "Garfield"} }
{
...
}
} // end Class MyClass2
Default annotations are another subset of the basic
annotations
support provided in JDK 5.0 (1.5). These are annotations that
ornament Annotations either visibly (accessible at runtime)
or invisibly (not accessible at
runtime). Default annotations specify a default value for a given
annotation field.
ANNOTATION INTERFACE DECLARATION: @interface ANNOTATION_NAME { ANNOTATION_FIELD_DECL+
}
ANNOTATION_FIELD_DECL: ANNOT_FIELD_TYPE ANNOTATION_NAME
[ANNOTATION_DEFAULT_VALUE_DECL];
ANNOTATION_DEFAULT_VALUE_DECL: default ANNOTATION_VALUE (where value must be of the type
ANNOT_FIELD_TYPE)
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@interface Meth2Preamble {
String author() default "John Steinbeck";
}
interface Meth2Preamble
implements java/lang/annotation/Annotation
version 50:0
{
public abstract Method author:"()Ljava/lang/String;" default { "John Steinbeck" } ;
} // end Class Meth2Preamble
MODULE_REQUIRES: sequence of REQUIRES_FLAGS CONSTANT_CELL(moduleContent); REQUIRES_FLAGS: set of transitive] [static] requires transitive static foo.bar;
MODULE_EXPORTS: sequence of CONSTANT_CELL(package) [to EXPORT_TO_MODULES]; EXPORT_TO_MODULES: list of CONSTANT_CELL(moduleContent) exports com/foo/bar to
foo2.bar2,
foo3.bar3;
exports org/foo/bar;
MODULE_OPENS: sequence of CONSTANT_CELL(package) [to OPENS_TO_MODULES]; OPENS_TO_MODULES: list of CONSTANT_CELL(moduleContent) opens com/foo/bar to
foo2.bar2,
foo3.bar3;
opens org/foo/bar;
MODULE_USES: sequence of CONSTANT_CELL(class); uses com/foo/bar;
MODULE_PROVIDES: sequence of CONSTANT_CELL(class) [with MODULE_PROVIDES_WITH_CLASSES]; MODULE_PROVIDES_WITH_CLASSES: list of CONSTANT_CELL(class)provides com/foo/bar with
foo2.bar2,
foo3.bar3;
provides com/foo/bar;
|
Java Assembler Tools (AsmTools) User's Guide |
000-0000-00 |