
org.opalj.br.reader.DeferredDynamicConstantResolution.scala Maven / Gradle / Ivy
The newest version!
/* BSD 2-Clause License - see OPAL/LICENSE for details. */
package org.opalj
package br
package reader
import org.opalj.br.instructions.INCOMPLETE_LDC
import org.opalj.br.instructions.INCOMPLETE_LDC2_W
import org.opalj.br.instructions.INCOMPLETE_LDC_W
import org.opalj.br.instructions.Instruction
import org.opalj.br.instructions.LoadDynamic
import org.opalj.br.instructions.LoadDynamic2_W
import org.opalj.br.instructions.LoadDynamic_W
/**
* Mixin this trait to resolve links between [[org.opalj.br.instructions.LDC]]
* instructions and the [[BootstrapMethodTable]].
*/
trait DeferredDynamicConstantResolution extends ConstantPoolBinding with CodeBinding {
/**
* 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.
*
* @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.
*
* @param classFile The [[ClassFile]] with which the deferred action was registered.
* @param cp The class file's [[Constant_Pool]].
* @param dynamicInfo The consttant pool entry describing the dynamic constant.
* @param instructions This method's array of [[instructions.Instruction]]s.
* (The array returned by the [[#Instructions]] method.)
* @param pc The program counter of the `invokedynamic` instruction.
*/
protected def deferredDynamicConstantResolution(
classFile: ClassFile,
cp: Constant_Pool,
ap_name_index: Constant_Pool_Index,
ap_descriptor_index: Constant_Pool_Index,
dynamicInfo: CONSTANT_Dynamic_info,
instructions: Array[Instruction],
pc: PC
): ClassFile = {
val bootstrapMethods = classFile.attributes collectFirst {
case BootstrapMethodTable(bms) => bms
}
val ldc = instructions(pc) match {
case INCOMPLETE_LDC =>
LoadDynamic(
bootstrapMethods.get(dynamicInfo.bootstrapMethodAttributeIndex),
dynamicInfo.name(cp),
dynamicInfo.descriptor(cp)
)
case INCOMPLETE_LDC_W =>
LoadDynamic_W(
bootstrapMethods.get(dynamicInfo.bootstrapMethodAttributeIndex),
dynamicInfo.name(cp),
dynamicInfo.descriptor(cp)
)
case INCOMPLETE_LDC2_W =>
LoadDynamic2_W(
bootstrapMethods.get(dynamicInfo.bootstrapMethodAttributeIndex),
dynamicInfo.name(cp),
dynamicInfo.descriptor(cp)
)
}
instructions(pc) = ldc
classFile
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy