-
Notifications
You must be signed in to change notification settings - Fork 1
Load and Link
Loading is the process of finding the binary representation of a class or interface type with a particular name and creating a class or interface from that binary representation.
Linking is the process of taking a class or interface and comibining it into the run-time stat of the Java Virtual Machine so that it can be executed.
Initialization of a class or interface consists of excuting the class or interface initialization method <clinit>
.
Cruiser currently aims at loading and linking.
Creation of a class or interface is either triggered by being referred in another class's or interface's run-time constant pool; or by invoking methods in certain Java SE platform class libraries such as reflection.
However, creation of a class or interface in Cruiser is triggered by invoking function parseClassfile
, which only creates at most one class.
Array classes do not have an external binary representation; they are created by the Java Virtual Machine rather than by a class loader.
Linking is divided into 5 parts, verification, preparation, resolution, access control, and overriding.
Linking of a class or interface in Cruiser is eager and static, which means Cruiser will resolve all symbolic references at once when the class is being verified.
Cruiser maintains a temporary static ClassFile during the verification of a binary representation, which will abandoned immediatly after the verification. However, verification is optional and will only be activated if certain flag appears in Cruiser's command line arguments.
Preparation involves creating the static fields and initializing such fields to their default values. This does not require the execution of any Java Virtual Machine code; explicit initializers for static fields are executed as part of initialization, not prepartion.
Cruiser enforces prepartion of any static fields, which means ConstantValue
attribute of such fields will never be ignored.
During prepartion of a class or interface, the Java Virtual Machine also imposes loading constraints, which validates signature of overrided method of this class, superclass and superinterfaces.
The Java Virtual Machine instructions anewarray, checkcast, getfield, getstatic, instanceof, invokedynamic, invokeinterface, invokespecial, invokestatic, invokevirtual, ldc, ldc_w, multianewarray, new, putfield, and putstatic make symbolic references to the run-time constant pool. Execution of any of these instructions requires resolution of its symbolic reference.
Disassembling and decompiling are twisted processes of execution, which means they need proper resolution of constant pool as well.
Resolution, on the other hand, is the process of dynamically determining concrete values from symbolic references in the run-time constant pool. Resolution of the symbolic refernece of one occurence of an invokedynamic instruction does not imply that the same symbolic reference is considered resolved for any other invokedynamic instruction. For all other instructions above, resolution of the symbolic reference of one occurrence of an instruction does imply that the the same symbolic reference is considered resolved for any other non-invokedynamic instruction.
The above text implies that the concrete value determined by resolution for a specific invokedynamic instruction is a call site object bound to that specific invokedynamic instruction.