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
- final def !=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def ##: Int
- Definition Classes
- AnyRef → Any
- final def ==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- 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
- final def asInstanceOf[T0]: T0
- Definition Classes
- Any
- def clone(): AnyRef
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.CloneNotSupportedException]) @native() @IntrinsicCandidate()
- 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 createDeferredActionsStore(): (DynamicConstantRewriting.this)#DeferredActionsStore
Creates a storage area for functions that will be called after the class file was completely loaded.
Creates a storage area for functions that will be called after the class file was completely loaded. This makes it possible to register functions that are newly created for a special class file object to perform actions related to that specific class file object. For further information study the resolving process of
invokedynamic
instructions.- Attributes
- protected[this]
- Definition Classes
- ConstantPoolBinding → Constant_PoolReader
- def createObjectMethodsTarget(bootstrapArgs: BootstrapArguments, methodName: String, newMethodName: String, classFile: br.ClassFile): Option[(br.ClassFile, MethodDescriptor)]
Creates the code required to perform the action of a method created by java.lang.runtime.ObjectMethods.bootstrap.
Creates the code required to perform the action of a method created by java.lang.runtime.ObjectMethods.bootstrap.
- bootstrapArgs
The arguments to the bootstrap method
- methodName
Name of the represented method (either equals, toString or hashCode)
- newMethodName
The name for the newly created method
- returns
Either a tuple of the updated class file and the descriptor of the new method or None
- Attributes
- protected[this]
- Definition Classes
- BootstrapArgumentLoading
- 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.
- final def eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def equals(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef → Any
- final def getClass(): Class[_ <: AnyRef]
- Definition Classes
- AnyRef → Any
- Annotations
- @native() @IntrinsicCandidate()
- def hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native() @IntrinsicCandidate()
- final def isInstanceOf[T0]: Boolean
- Definition Classes
- Any
- 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
- final def ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def newTargetMethodName(cp: cp.Constant_Pool, surroundingMethodNameIndex: Int, surroundingMethodDescriptorIndex: Int, pc: Int, targetMethodName: String): String
Generates a new, internal name for a method to be inserted.
Generates a new, internal name for a method to be inserted.
It follows the pattern:
$targetMethodName${surroundingMethodName}{surroundingMethodDescriptor}:pc
, where surroundingMethodDescriptor is the JVM descriptor of the method sanitized to not contain characters illegal in method names (replacing /, [, ;, < and > by $, ], :, _ and _ respectively) and where pc is the pc of the invokedynamic that is rewritten.- Attributes
- protected[this]
- Definition Classes
- BootstrapArgumentLoading
- final def notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native() @IntrinsicCandidate()
- final def notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native() @IntrinsicCandidate()
- val performRewriting: Boolean
- def registerDeferredAction(cp: (DynamicConstantRewriting.this)#Constant_Pool)(deferredAction: ((DynamicConstantRewriting.this)#ClassFile) => (DynamicConstantRewriting.this)#ClassFile): Unit
- Definition Classes
- Constant_PoolReader
- def replaceChars(in: String, oldChars: String, newChars: String): String
Replaces each of several characters in a String with a given corresponding character.
Replaces each of several characters in a String with a given corresponding character.
- Attributes
- protected[this]
- Definition Classes
- BootstrapArgumentLoading
- final def synchronized[T0](arg0: => T0): T0
- Definition Classes
- AnyRef
- def toString(): String
- Definition Classes
- AnyRef → Any
- final def wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
Deprecated Value Members
- def finalize(): Unit
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.Throwable]) @Deprecated
- Deprecated