Skip to main content

ferro_babe/model/
constant.rs

1use rust_asm::constant_pool::CpInfo;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4/// An index into a class file's constant-pool table.
5///
6/// Index values are preserved exactly as stored in the class file. They are one-based in valid
7/// class files, and some values can refer to unusable reserved slots after `Long` or `Double`
8/// constants.
9pub struct ConstantPoolIndex(u16);
10
11impl ConstantPoolIndex {
12    pub(crate) const fn new(index: u16) -> Self {
13        Self(index)
14    }
15
16    /// Returns the raw constant-pool index value.
17    #[must_use]
18    pub const fn get(self) -> u16 {
19        self.0
20    }
21}
22
23#[derive(Debug, Clone, Copy)]
24/// A borrowed view of one constant-pool entry.
25///
26/// Index-bearing variants retain their raw class-file indices instead of resolving or rewriting
27/// the referenced entries.
28pub enum ConstantRef<'a> {
29    /// A reserved constant-pool slot with no value.
30    Unusable,
31    /// A modified UTF-8 string decoded by the underlying parser.
32    Utf8(&'a str),
33    /// A 32-bit integer literal.
34    Integer(i32),
35    /// A 32-bit floating-point literal.
36    Float(f32),
37    /// A 64-bit integer literal.
38    Long(i64),
39    /// A 64-bit floating-point literal.
40    Double(f64),
41    /// A class reference whose name is stored in another constant-pool entry.
42    Class {
43        /// Index of the UTF-8 internal class name.
44        name: ConstantPoolIndex,
45    },
46    /// A string constant whose value is stored in another constant-pool entry.
47    String {
48        /// Index of the UTF-8 string value.
49        value: ConstantPoolIndex,
50    },
51    /// A field member reference.
52    FieldReference {
53        /// Index of the declaring class entry.
54        class: ConstantPoolIndex,
55        /// Index of the member name-and-descriptor entry.
56        name_and_type: ConstantPoolIndex,
57    },
58    /// A class method reference.
59    MethodReference {
60        /// Index of the declaring class entry.
61        class: ConstantPoolIndex,
62        /// Index of the member name-and-descriptor entry.
63        name_and_type: ConstantPoolIndex,
64    },
65    /// An interface method reference.
66    InterfaceMethodReference {
67        /// Index of the declaring interface entry.
68        class: ConstantPoolIndex,
69        /// Index of the member name-and-descriptor entry.
70        name_and_type: ConstantPoolIndex,
71    },
72    /// A member name and descriptor pair.
73    NameAndType {
74        /// Index of the UTF-8 member name.
75        name: ConstantPoolIndex,
76        /// Index of the UTF-8 descriptor.
77        descriptor: ConstantPoolIndex,
78    },
79    /// A method-handle constant.
80    MethodHandle {
81        /// Raw JVM reference-kind value.
82        reference_kind: u8,
83        /// Index of the referenced field or method entry.
84        reference: ConstantPoolIndex,
85    },
86    /// A method-type constant.
87    MethodType {
88        /// Index of the UTF-8 method descriptor.
89        descriptor: ConstantPoolIndex,
90    },
91    /// A dynamically computed constant.
92    Dynamic {
93        /// Index into the `BootstrapMethods` attribute.
94        bootstrap_method: u16,
95        /// Index of the name-and-descriptor entry.
96        name_and_type: ConstantPoolIndex,
97    },
98    /// An `invokedynamic` call-site constant.
99    InvokeDynamic {
100        /// Index into the `BootstrapMethods` attribute.
101        bootstrap_method: u16,
102        /// Index of the name-and-descriptor entry.
103        name_and_type: ConstantPoolIndex,
104    },
105    /// A Java Platform Module System module constant.
106    Module {
107        /// Index of the UTF-8 module name.
108        name: ConstantPoolIndex,
109    },
110    /// A Java Platform Module System package constant.
111    Package {
112        /// Index of the UTF-8 package name.
113        name: ConstantPoolIndex,
114    },
115}
116
117impl<'a> From<&'a CpInfo> for ConstantRef<'a> {
118    fn from(value: &'a CpInfo) -> Self {
119        match value {
120            CpInfo::Unusable => Self::Unusable,
121            CpInfo::Utf8(value) => Self::Utf8(value),
122            CpInfo::Integer(value) => Self::Integer(*value),
123            CpInfo::Float(value) => Self::Float(*value),
124            CpInfo::Long(value) => Self::Long(*value),
125            CpInfo::Double(value) => Self::Double(*value),
126            CpInfo::Class { name_index } => Self::Class {
127                name: ConstantPoolIndex::new(*name_index),
128            },
129            CpInfo::String { string_index } => Self::String {
130                value: ConstantPoolIndex::new(*string_index),
131            },
132            CpInfo::Fieldref {
133                class_index,
134                name_and_type_index,
135            } => Self::FieldReference {
136                class: ConstantPoolIndex::new(*class_index),
137                name_and_type: ConstantPoolIndex::new(*name_and_type_index),
138            },
139            CpInfo::Methodref {
140                class_index,
141                name_and_type_index,
142            } => Self::MethodReference {
143                class: ConstantPoolIndex::new(*class_index),
144                name_and_type: ConstantPoolIndex::new(*name_and_type_index),
145            },
146            CpInfo::InterfaceMethodref {
147                class_index,
148                name_and_type_index,
149            } => Self::InterfaceMethodReference {
150                class: ConstantPoolIndex::new(*class_index),
151                name_and_type: ConstantPoolIndex::new(*name_and_type_index),
152            },
153            CpInfo::NameAndType {
154                name_index,
155                descriptor_index,
156            } => Self::NameAndType {
157                name: ConstantPoolIndex::new(*name_index),
158                descriptor: ConstantPoolIndex::new(*descriptor_index),
159            },
160            CpInfo::MethodHandle {
161                reference_kind,
162                reference_index,
163            } => Self::MethodHandle {
164                reference_kind: *reference_kind,
165                reference: ConstantPoolIndex::new(*reference_index),
166            },
167            CpInfo::MethodType { descriptor_index } => Self::MethodType {
168                descriptor: ConstantPoolIndex::new(*descriptor_index),
169            },
170            CpInfo::Dynamic {
171                bootstrap_method_attr_index,
172                name_and_type_index,
173            } => Self::Dynamic {
174                bootstrap_method: *bootstrap_method_attr_index,
175                name_and_type: ConstantPoolIndex::new(*name_and_type_index),
176            },
177            CpInfo::InvokeDynamic {
178                bootstrap_method_attr_index,
179                name_and_type_index,
180            } => Self::InvokeDynamic {
181                bootstrap_method: *bootstrap_method_attr_index,
182                name_and_type: ConstantPoolIndex::new(*name_and_type_index),
183            },
184            CpInfo::Module { name_index } => Self::Module {
185                name: ConstantPoolIndex::new(*name_index),
186            },
187            CpInfo::Package { name_index } => Self::Package {
188                name: ConstantPoolIndex::new(*name_index),
189            },
190        }
191    }
192}