All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opalj.br.reader.DeferredInvokedynamicResolution.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.Instruction
import org.opalj.br.instructions.DEFAULT_INVOKEDYNAMIC

/**
 * Mixin this trait to resolve links between [[org.opalj.br.instructions.INVOKEDYNAMIC]]
 * instructions and the [[BootstrapMethodTable]].
 */
trait DeferredInvokedynamicResolution extends ConstantPoolBinding with CodeBinding {

    /**
     * Resolves an [[org.opalj.br.instructions.INCOMPLETE_INVOKEDYNAMIC]] 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 `invokedynamic`
     *          instruction is found in a method's byte code.
     *
     * ==Overriding this Method==
     * To perform additional analyses on `invokedynamic` instructions, e.g., to
     * fully resolve the call target, a subclass may override this method to do so.
     * When you override this method, you should call this method
     * (`super.deferredResolveInvokedynamicResolution`) 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   invokeDynamicInfo The [[org.opalj.br.instructions.INVOKEDYNAMIC]] instruction's
     *          constant pool entry.
     * @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 deferredInvokedynamicResolution(
        classFile:           ClassFile,
        cp:                  Constant_Pool,
        ap_name_index:       Constant_Pool_Index,
        ap_descriptor_index: Constant_Pool_Index,
        invokeDynamicInfo:   CONSTANT_InvokeDynamic_info,
        instructions:        Array[Instruction],
        pc:                  PC
    ): ClassFile = {

        val bootstrapMethods = classFile.attributes collectFirst {
            case BootstrapMethodTable(bms) => bms
        }
        val invokeDynamic = DEFAULT_INVOKEDYNAMIC(
            bootstrapMethods.get(invokeDynamicInfo.bootstrapMethodAttributeIndex),
            invokeDynamicInfo.methodName(cp),
            invokeDynamicInfo.methodDescriptor(cp)
        )
        instructions(pc) = invokeDynamic
        classFile
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy