
org.opalj.br.cp.ConstantsPool.scala Maven / Gradle / Ivy
The newest version!
/* BSD 2-Clause License - see OPAL/LICENSE for details. */
package org.opalj
package br
package cp
import scala.collection.immutable
/**
* An immutable view of a created constants pool. The `ConstantsPool` object is typically
* created using a [[ConstantsBuffer]]'s `build` method.
*
* @author Michael Eichberg
*/
class ConstantsPool(
val constantPool: immutable.Map[Constant_Pool_Entry, Constant_Pool_Index],
val bootstrapMethods: IndexedSeq[BootstrapMethod]
) extends ConstantsPoolLike {
private[this] def validateIndex(index: Int, requiresUByteIndex: Boolean): Int = {
if (requiresUByteIndex && index > UByte.MaxValue) {
val message = s"the constant pool index $index is larger than ${UByte.MaxValue}"
throw new ConstantPoolException(message)
}
index
}
@throws[ConstantPoolException]
override def CPEClass(referenceType: ReferenceType, requiresUByteIndex: Boolean): Int = {
val cpeUtf8 = CPEUtf8OfCPEClass(referenceType)
validateIndex(constantPool(CONSTANT_Class_info(cpeUtf8)), requiresUByteIndex)
}
@throws[ConstantPoolException]
override def CPEFloat(value: Float, requiresUByteIndex: Boolean): Int = {
validateIndex(constantPool(CONSTANT_Float_info(ConstantFloat(value))), requiresUByteIndex)
}
@throws[ConstantPoolException]
override def CPEInteger(value: Int, requiresUByteIndex: Boolean): Int = {
val cpEntry = CONSTANT_Integer_info(ConstantInteger(value))
validateIndex(constantPool(cpEntry), requiresUByteIndex)
}
@throws[ConstantPoolException]
override def CPEString(value: String, requiresUByteIndex: Boolean): Int = {
validateIndex(constantPool(CONSTANT_String_info(CPEUtf8(value))), requiresUByteIndex)
}
@throws[ConstantPoolException]
override def CPEMethodHandle(methodHandle: MethodHandle, requiresUByteIndex: Boolean): Int = {
val (tag, cpRefIndex) = CPERefOfCPEMethodHandle(methodHandle)
validateIndex(constantPool(CONSTANT_MethodHandle_info(tag, cpRefIndex)), requiresUByteIndex)
}
@throws[ConstantPoolException]
def CPEMethodType(descriptor: String, requiresUByteIndex: Boolean): Int = {
val cpEntry = CONSTANT_MethodType_info(constantPool(CONSTANT_Utf8_info(descriptor)))
validateIndex(constantPool(cpEntry), requiresUByteIndex)
}
override def CPEMethodType(descriptor: MethodDescriptor, requiresUByteIndex: Boolean): Int = {
CPEMethodType(descriptor.toJVMDescriptor, requiresUByteIndex)
}
override def CPEDouble(value: Double): Int = {
constantPool(CONSTANT_Double_info(ConstantDouble(value)))
}
override def CPELong(value: Long): Int = {
constantPool(CONSTANT_Long_info(ConstantLong(value)))
}
override def CPEUtf8(value: String): Int = constantPool(CONSTANT_Utf8_info(value))
override def CPENameAndType(name: String, tpe: String): Int = {
val nameIndex = CPEUtf8(name)
val typeIndex = CPEUtf8(tpe)
constantPool(CONSTANT_NameAndType_info(nameIndex, typeIndex))
}
override def CPEFieldRef(
objectType: ObjectType,
fieldName: String,
fieldType: String
): Int = {
val nameAndTypeRef = CPENameAndType(fieldName, fieldType)
val cpeClass = CPEClass(objectType, false)
constantPool(CONSTANT_Fieldref_info(cpeClass, nameAndTypeRef))
}
def CPEMethodRef(
referenceType: ReferenceType,
methodName: String,
descriptor: String
): Int = {
val class_index = CPEClass(referenceType, false)
val name_and_type_index = CPENameAndType(methodName, descriptor)
constantPool(CONSTANT_Methodref_info(class_index, name_and_type_index))
}
override def CPEMethodRef(
objectType: ReferenceType,
name: String,
descriptor: MethodDescriptor
): Int = {
CPEMethodRef(objectType, name, descriptor.toJVMDescriptor)
}
def CPEInterfaceMethodRef(
objectType: ReferenceType,
methodName: String,
descriptor: String
): Int = {
val class_index = CPEClass(objectType, false)
val name_and_type_index = CPENameAndType(methodName, descriptor)
constantPool(CONSTANT_InterfaceMethodref_info(class_index, name_and_type_index))
}
override def CPEInterfaceMethodRef(
objectType: ReferenceType,
name: String,
descriptor: MethodDescriptor
): Int = {
CPEInterfaceMethodRef(objectType, name, descriptor.toJVMDescriptor)
}
def CPEInvokeDynamic(
bootstrapMethod: BootstrapMethod,
name: String,
descriptor: String
): Int = {
val indexOfBootstrapMethod = bootstrapMethods.indexOf(bootstrapMethod)
if (indexOfBootstrapMethod == -1) {
throw new ConstantPoolException(s"the bootstrap method $bootstrapMethod is unknown")
}
val cpNameAndTypeIndex = CPENameAndType(name, descriptor)
constantPool(CONSTANT_InvokeDynamic_info(indexOfBootstrapMethod, cpNameAndTypeIndex))
}
override def CPEInvokeDynamic(
bootstrapMethod: BootstrapMethod,
name: String,
descriptor: MethodDescriptor
): Int = {
CPEInvokeDynamic(bootstrapMethod, name, descriptor.toJVMDescriptor)
}
@throws[ConstantPoolException]
def CPEDynamic(
bootstrapMethod: BootstrapMethod,
name: String,
descriptor: String,
requiresUByteIndex: Boolean
): Int = {
val indexOfBootstrapMethod = bootstrapMethods.indexOf(bootstrapMethod)
if (indexOfBootstrapMethod == -1) {
throw new ConstantPoolException(s"the bootstrap method $bootstrapMethod is unknown")
}
val cpNameAndTypeIndex = CPENameAndType(name, descriptor)
validateIndex(
constantPool(CONSTANT_Dynamic_info(indexOfBootstrapMethod, cpNameAndTypeIndex)),
requiresUByteIndex
)
}
@throws[ConstantPoolException]
override def CPEDynamic(
bootstrapMethod: BootstrapMethod,
name: String,
descriptor: FieldType,
requiresUByteIndex: Boolean
): Int = {
CPEDynamic(bootstrapMethod, name, descriptor.toJVMTypeName, requiresUByteIndex)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy