trait DynamicConstantRewriting extends DeferredDynamicConstantResolution with BootstrapArgumentLoading
Provides support for rewriting Java 11 dynamic constant loading instructions. This trait should be mixed in alongside a BytecodeReaderAndBinding, which extracts basic dynamic constant information from the BootstrapMethodTable.
Specifically, whenever an ldc
, ldc_w
or ldc2_w
instruction is encountered that loads a
dynamic constant, this trait tries to rewrite it to a simpler expression providing the same
constant or an invocation of a method providing the constant from a lazily-initialized field.
- Self Type
- DynamicConstantRewriting with ClassFileBinding
- Source
- DynamicConstantRewriting.scala
- Note
This rewriting is best-effort only. As
ldc
instructions take only two bytes, they cannot easily be rewritten to invocations, etc.ldc_w
andldc2_w
instructions, however, are rewritten more aggressively.- See also
Hands on Java 11's constantdynamic for further information.
- Alphabetic
- By Inheritance
- DynamicConstantRewriting
- BootstrapArgumentLoading
- DeferredDynamicConstantResolution
- CodeBinding
- ConstantPoolBinding
- Constant_PoolReader
- Constant_PoolAbstractions
- AnyRef
- Any
- Hide All
- Show All
- Public
- Protected
Type Members
- type CONSTANT_Class_info = cp.CONSTANT_Class_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- type CONSTANT_Double_info = cp.CONSTANT_Double_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- type CONSTANT_Dynamic_info = cp.CONSTANT_Dynamic_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- type CONSTANT_Fieldref_info = cp.CONSTANT_Fieldref_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- type CONSTANT_Float_info = cp.CONSTANT_Float_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- type CONSTANT_Integer_info = cp.CONSTANT_Integer_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- type CONSTANT_InterfaceMethodref_info = cp.CONSTANT_InterfaceMethodref_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- type CONSTANT_InvokeDynamic_info = cp.CONSTANT_InvokeDynamic_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- type CONSTANT_Long_info = cp.CONSTANT_Long_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- type CONSTANT_MethodHandle_info = cp.CONSTANT_MethodHandle_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- type CONSTANT_MethodType_info = cp.CONSTANT_MethodType_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- type CONSTANT_Methodref_info = cp.CONSTANT_Methodref_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- type CONSTANT_Module_info = cp.CONSTANT_Module_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- type CONSTANT_NameAndType_info = cp.CONSTANT_NameAndType_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- type CONSTANT_Package_info = cp.CONSTANT_Package_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- type CONSTANT_String_info = cp.CONSTANT_String_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- type CONSTANT_Utf8_info = cp.CONSTANT_Utf8_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader → Constant_PoolAbstractions
- abstract type ClassFile <: br.ClassFile
- Definition Classes
- ConstantPoolBinding → Constant_PoolAbstractions
- final type Constant_Pool = Array[(DynamicConstantRewriting.this)#Constant_Pool_Entry]
- Definition Classes
- Constant_PoolAbstractions
- type Constant_Pool_Entry = cp.Constant_Pool_Entry
- Definition Classes
- ConstantPoolBinding → Constant_PoolAbstractions
- final type Constant_Pool_Index = Int
- Definition Classes
- Constant_PoolAbstractions
- type DeferredActionsStore = Buffer[((DynamicConstantRewriting.this)#ClassFile) => (DynamicConstantRewriting.this)#ClassFile] with (DynamicConstantRewriting.this)#Constant_Pool_Entry
A DeferredActionsStore stores all functions that need to perform post load actions.
A DeferredActionsStore stores all functions that need to perform post load actions.
One example is the resolution of references to attributes. (The constant pool is the only structure that is passed around and hence it is the only place where to store information/functions related to a specific class file).
- Definition Classes
- Constant_PoolAbstractions
- type Instructions = Array[Instruction]
- Definition Classes
- CodeBinding
Value Members
- def CONSTANT_Class_info(i: Int): (DynamicConstantRewriting.this)#CONSTANT_Class_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def CONSTANT_Double_info(d: Double): (DynamicConstantRewriting.this)#CONSTANT_Double_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def CONSTANT_Dynamic_info(bootstrap_method_attr_index: (DynamicConstantRewriting.this)#Constant_Pool_Index, name_and_type_index: (DynamicConstantRewriting.this)#Constant_Pool_Index): (DynamicConstantRewriting.this)#CONSTANT_Dynamic_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def CONSTANT_Fieldref_info(class_index: (DynamicConstantRewriting.this)#Constant_Pool_Index, name_and_type_index: (DynamicConstantRewriting.this)#Constant_Pool_Index): (DynamicConstantRewriting.this)#CONSTANT_Fieldref_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def CONSTANT_Float_info(f: Float): (DynamicConstantRewriting.this)#CONSTANT_Float_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def CONSTANT_Integer_info(i: Int): (DynamicConstantRewriting.this)#CONSTANT_Integer_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def CONSTANT_InterfaceMethodref_info(class_index: (DynamicConstantRewriting.this)#Constant_Pool_Index, name_and_type_index: (DynamicConstantRewriting.this)#Constant_Pool_Index): (DynamicConstantRewriting.this)#CONSTANT_InterfaceMethodref_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def CONSTANT_InvokeDynamic_info(bootstrap_method_attr_index: (DynamicConstantRewriting.this)#Constant_Pool_Index, name_and_type_index: (DynamicConstantRewriting.this)#Constant_Pool_Index): (DynamicConstantRewriting.this)#CONSTANT_InvokeDynamic_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def CONSTANT_Long_info(l: Long): (DynamicConstantRewriting.this)#CONSTANT_Long_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def CONSTANT_MethodHandle_info(reference_kind: Int, reference_index: Int): (DynamicConstantRewriting.this)#CONSTANT_MethodHandle_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def CONSTANT_MethodType_info(descriptor_index: (DynamicConstantRewriting.this)#Constant_Pool_Index): (DynamicConstantRewriting.this)#CONSTANT_MethodType_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def CONSTANT_Methodref_info(class_index: (DynamicConstantRewriting.this)#Constant_Pool_Index, name_and_type_index: (DynamicConstantRewriting.this)#Constant_Pool_Index): (DynamicConstantRewriting.this)#CONSTANT_Methodref_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def CONSTANT_Module_info(name_index: (DynamicConstantRewriting.this)#Constant_Pool_Index): (DynamicConstantRewriting.this)#CONSTANT_Module_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def CONSTANT_NameAndType_info(name_index: (DynamicConstantRewriting.this)#Constant_Pool_Index, descriptor_index: (DynamicConstantRewriting.this)#Constant_Pool_Index): (DynamicConstantRewriting.this)#CONSTANT_NameAndType_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def CONSTANT_Package_info(name_index: (DynamicConstantRewriting.this)#Constant_Pool_Index): (DynamicConstantRewriting.this)#CONSTANT_Package_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def CONSTANT_String_info(i: Int): (DynamicConstantRewriting.this)#CONSTANT_String_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def CONSTANT_Utf8_info(r: Array[Byte], s: String): (DynamicConstantRewriting.this)#CONSTANT_Utf8_info
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def Constant_Pool(in: DataInputStream): (DynamicConstantRewriting.this)#Constant_Pool
- Definition Classes
- Constant_PoolReader
- def applyDeferredActions(cp: (DynamicConstantRewriting.this)#Constant_Pool, classFile: (DynamicConstantRewriting.this)#ClassFile): (DynamicConstantRewriting.this)#ClassFile
This method is called/needs to be called after the class file was completely loaded to perform class file specific transformations.
This method is called/needs to be called after the class file was completely loaded to perform class file specific transformations.
- Definition Classes
- Constant_PoolReader → Constant_PoolAbstractions
- implicit val constantPoolEntryType: ClassTag[cp.Constant_Pool_Entry]
- Definition Classes
- ConstantPoolBinding → Constant_PoolAbstractions
- implicit def cpIndexTocpEntry(index: (DynamicConstantRewriting.this)#Constant_Pool_Index)(implicit cp: (DynamicConstantRewriting.this)#Constant_Pool): (DynamicConstantRewriting.this)#Constant_Pool_Entry
- Definition Classes
- ConstantPoolBinding
- def deferredDynamicConstantResolution(classFile: (DynamicConstantRewriting.this)#ClassFile, cp: (DynamicConstantRewriting.this)#Constant_Pool, methodNameIndex: (DynamicConstantRewriting.this)#Constant_Pool_Index, methodDescriptorIndex: (DynamicConstantRewriting.this)#Constant_Pool_Index, dynamicInfo: (DynamicConstantRewriting.this)#CONSTANT_Dynamic_info, instructions: Array[Instruction], pc: PC): (DynamicConstantRewriting.this)#ClassFile
Resolves an org.opalj.br.instructions.INCOMPLETE_LDC instruction using the BootstrapMethodTable of the class.
Resolves an org.opalj.br.instructions.INCOMPLETE_LDC instruction using the BootstrapMethodTable of the class.
Deferred resolution is necessary since the BootstrapMethodTable – which is an attribute of the class file – is loaded after the methods.
- classFile
The ClassFile with which the deferred action was registered.
- cp
The class file's Constant_Pool.
- dynamicInfo
The consttant pool entry describing the dynamic constant.
- instructions
This method's array of instructions.Instructions. (The array returned by the #Instructions method.)
- pc
The program counter of the
invokedynamic
instruction.
- Definition Classes
- DynamicConstantRewriting → DeferredDynamicConstantResolution
- Note
This method is called (back) after the class file was completely loaded. Registration as a callback method happens whenever an
ldc
instruction is found in a method's byte code that refers to a dynamic constant.Overriding this Method
To perform additional analyses on dynamic constant loading
ldc
instructions, e.g., to fully resolve the constant, a subclass may override this method to do so. When you override this method, you should call this method (super.deferredResolveDynamicConstantResolution
) to ensure that the default resolution is carried out.
- def loadBootstrapArgument(argument: ConstantValue[_], instructions: InstructionsBuilder, classFile: br.ClassFile, boxed: Boolean = false): (Int, br.ClassFile)
Generate instructions to load a constant argument for a bootstrap method.
Generate instructions to load a constant argument for a bootstrap method.
- argument
The argument to be loaded
- instructions
The instruction builder the instructions are appended to
- classFile
The class file the constant is in
- boxed
If true, ensures the argument is of a reference type, boxing it if necessary
- returns
The maximum stack height the generated instructions require and the (potentially new!) class file
- Definition Classes
- BootstrapArgumentLoading
- def loadDynamicConstant(bootstrapMethod: BootstrapMethod, name: String, descriptor: FieldType, instructions: InstructionsBuilder, classFile: br.ClassFile, boxed: Boolean = false): (Int, br.ClassFile)
Generate instructions to load a dynamic constant.
Generate instructions to load a dynamic constant.
- bootstrapMethod
The constant's bootstrap method
- name
The constant's name information, passed as the bootstrap method's 2. argument
- descriptor
The constant's type, passed as the bootstrap method's 3. argument
- instructions
The instruction builder the instructions are appended to
- classFile
The class file the constant is in
- boxed
If true, ensures the constant is of a reference type, boxing it if necessary
- returns
The maximum stack height the generated instructions require and the (potentially new!) class file
- Definition Classes
- BootstrapArgumentLoading
- val logRewrites: Boolean
- val logUnknownDynamicConstants: Boolean
- val logUnresolvedDynamicConstants: Boolean
- val performRewriting: Boolean
- def registerDeferredAction(cp: (DynamicConstantRewriting.this)#Constant_Pool)(deferredAction: ((DynamicConstantRewriting.this)#ClassFile) => (DynamicConstantRewriting.this)#ClassFile): Unit
- Definition Classes
- Constant_PoolReader