sim_codec_classfile/attribute/
class.rs1#[derive(Clone, Debug, Eq, PartialEq)]
3pub struct BootstrapMethod {
4 pub method_ref: u16,
6 pub arguments: Vec<u16>,
8}
9
10#[derive(Clone, Debug, Eq, PartialEq)]
12pub struct BootstrapMethodsAttribute {
13 pub methods: Vec<BootstrapMethod>,
15}
16
17impl BootstrapMethodsAttribute {
18 pub fn decode(reader: &mut ByteReader<'_>) -> Result<Self, AttributeError> {
20 let n = usize::from(reader.read_u2()?);
21 reader.preflight_allocation(n)?;
22 let mut methods = Vec::with_capacity(n);
23 for _ in 0..n {
24 let method_ref = reader.read_u2()?;
25 let argc = usize::from(reader.read_u2()?);
26 reader.preflight_allocation(argc)?;
27 let mut arguments = Vec::with_capacity(argc);
28 for _ in 0..argc {
29 arguments.push(reader.read_u2()?)
30 }
31 methods.push(BootstrapMethod {
32 method_ref,
33 arguments,
34 });
35 }
36 finish(reader)?;
37 Ok(Self { methods })
38 }
39 pub fn encode(&self, budget: usize) -> Result<Vec<u8>, AttributeError> {
41 let mut out = ByteWriter::new(budget);
42 out.write_u2(count(self.methods.len(), "bootstrap methods")?)?;
43 for method in &self.methods {
44 out.write_u2(method.method_ref)?;
45 out.write_u2(count(method.arguments.len(), "bootstrap arguments")?)?;
46 for argument in &method.arguments {
47 out.write_u2(*argument)?
48 }
49 }
50 Ok(out.into_bytes())
51 }
52}
53
54pub type RecordComponentAttribute = NestedAttribute;
56
57#[derive(Clone, Debug, Eq, PartialEq)]
59pub struct RecordComponent {
60 pub name_index: u16,
62 pub descriptor_index: u16,
64 pub attributes: Vec<RecordComponentAttribute>,
66}
67
68#[derive(Clone, Debug, Eq, PartialEq)]
70pub struct RecordAttribute {
71 pub components: Vec<RecordComponent>,
73}
74
75impl RecordAttribute {
76 pub fn decode(reader: &mut ByteReader<'_>) -> Result<Self, AttributeError> {
78 let n = usize::from(reader.read_u2()?);
79 reader.preflight_allocation(n)?;
80 let mut components = Vec::with_capacity(n);
81 for _ in 0..n {
82 let name_index = reader.read_u2()?;
83 let descriptor_index = reader.read_u2()?;
84 let attribute_count = usize::from(reader.read_u2()?);
85 reader.preflight_allocation(attribute_count)?;
86 let mut attributes = Vec::with_capacity(attribute_count);
87 for order in 0..attribute_count {
88 let start = reader.offset();
89 let name_index = reader.read_u2()?;
90 let declared_length = reader.read_u4()?;
91 let length = usize::try_from(declared_length).map_err(|_| {
92 error(
93 AttributeErrorKind::StaticConstraint,
94 reader.offset(),
95 "record component attribute length is not addressable",
96 )
97 })?;
98 attributes.push(NestedAttribute {
99 name_index,
100 owner: NestedAttributeOwner::RecordComponent,
101 order,
102 declared_length,
103 bytes: reader.take(length)?.to_vec(),
104 origin: annotation_origin(start, reader),
105 });
106 }
107 components.push(RecordComponent {
108 name_index,
109 descriptor_index,
110 attributes,
111 });
112 }
113 finish(reader)?;
114 Ok(Self { components })
115 }
116
117 pub fn encode(&self, budget: usize) -> Result<Vec<u8>, AttributeError> {
119 let mut out = ByteWriter::new(budget);
120 out.write_u2(count(self.components.len(), "record components")?)?;
121 for component in &self.components {
122 out.write_u2(component.name_index)?;
123 out.write_u2(component.descriptor_index)?;
124 out.write_u2(count(
125 component.attributes.len(),
126 "record component attributes",
127 )?)?;
128 for attribute in &component.attributes {
129 if usize::try_from(attribute.declared_length).ok() != Some(attribute.bytes.len()) {
130 return Err(error(
131 AttributeErrorKind::StaticConstraint,
132 attribute.origin.start,
133 "record component attribute declared length differs from retained bytes",
134 ));
135 }
136 out.write_u2(attribute.name_index)?;
137 out.write_u4(attribute.declared_length)?;
138 out.write_bytes(&attribute.bytes)?;
139 }
140 }
141 Ok(out.into_bytes())
142 }
143}
144
145#[derive(Clone, Copy, Debug, Eq, PartialEq)]
147pub struct ModuleRequire {
148 pub module_index: u16,
150 pub flags: u16,
152 pub version_index: u16,
154}
155#[derive(Clone, Debug, Eq, PartialEq)]
157pub struct ModuleExport {
158 pub package_index: u16,
160 pub flags: u16,
162 pub targets: Vec<u16>,
164}
165#[derive(Clone, Debug, Eq, PartialEq)]
167pub struct ModuleProvide {
168 pub service_index: u16,
170 pub providers: Vec<u16>,
172}
173#[derive(Clone, Debug, Eq, PartialEq)]
175pub struct ModuleAttribute {
176 pub name_index: u16,
178 pub flags: u16,
180 pub version_index: u16,
182 pub requires: Vec<ModuleRequire>,
184 pub exports: Vec<ModuleExport>,
186 pub opens: Vec<ModuleExport>,
188 pub uses: Vec<u16>,
190 pub provides: Vec<ModuleProvide>,
192}
193
194fn decode_module_exports(reader: &mut ByteReader<'_>) -> Result<Vec<ModuleExport>, AttributeError> {
195 let n = usize::from(reader.read_u2()?);
196 reader.preflight_allocation(n)?;
197 let mut values = Vec::with_capacity(n);
198 for _ in 0..n {
199 let package_index = reader.read_u2()?;
200 let flags = reader.read_u2()?;
201 let m = usize::from(reader.read_u2()?);
202 reader.preflight_allocation(m)?;
203 let mut targets = Vec::with_capacity(m);
204 for _ in 0..m {
205 targets.push(reader.read_u2()?);
206 }
207 values.push(ModuleExport {
208 package_index,
209 flags,
210 targets,
211 });
212 }
213 Ok(values)
214}
215fn encode_module_exports(
216 values: &[ModuleExport],
217 out: &mut ByteWriter,
218 what: &str,
219) -> Result<(), AttributeError> {
220 out.write_u2(count(values.len(), what)?)?;
221 for v in values {
222 out.write_u2(v.package_index)?;
223 out.write_u2(v.flags)?;
224 out.write_u2(count(v.targets.len(), "module directive targets")?)?;
225 for target in &v.targets {
226 out.write_u2(*target)?;
227 }
228 }
229 Ok(())
230}
231
232impl ModuleAttribute {
233 pub fn decode(reader: &mut ByteReader<'_>) -> Result<Self, AttributeError> {
235 let name_index = reader.read_u2()?;
236 let flags = reader.read_u2()?;
237 let version_index = reader.read_u2()?;
238 let n = usize::from(reader.read_u2()?);
239 reader.preflight_allocation(n)?;
240 let mut requires = Vec::with_capacity(n);
241 for _ in 0..n {
242 requires.push(ModuleRequire {
243 module_index: reader.read_u2()?,
244 flags: reader.read_u2()?,
245 version_index: reader.read_u2()?,
246 });
247 }
248 let exports = decode_module_exports(reader)?;
249 let opens = decode_module_exports(reader)?;
250 let n = usize::from(reader.read_u2()?);
251 reader.preflight_allocation(n)?;
252 let mut uses = Vec::with_capacity(n);
253 for _ in 0..n {
254 uses.push(reader.read_u2()?);
255 }
256 let n = usize::from(reader.read_u2()?);
257 reader.preflight_allocation(n)?;
258 let mut provides = Vec::with_capacity(n);
259 for _ in 0..n {
260 let service_index = reader.read_u2()?;
261 let m = usize::from(reader.read_u2()?);
262 reader.preflight_allocation(m)?;
263 let mut providers = Vec::with_capacity(m);
264 for _ in 0..m {
265 providers.push(reader.read_u2()?);
266 }
267 provides.push(ModuleProvide {
268 service_index,
269 providers,
270 });
271 }
272 finish(reader)?;
273 Ok(Self {
274 name_index,
275 flags,
276 version_index,
277 requires,
278 exports,
279 opens,
280 uses,
281 provides,
282 })
283 }
284 pub fn encode(&self, budget: usize) -> Result<Vec<u8>, AttributeError> {
286 let mut out = ByteWriter::new(budget);
287 out.write_u2(self.name_index)?;
288 out.write_u2(self.flags)?;
289 out.write_u2(self.version_index)?;
290 out.write_u2(count(self.requires.len(), "module requires")?)?;
291 for v in &self.requires {
292 out.write_u2(v.module_index)?;
293 out.write_u2(v.flags)?;
294 out.write_u2(v.version_index)?;
295 }
296 encode_module_exports(&self.exports, &mut out, "module exports")?;
297 encode_module_exports(&self.opens, &mut out, "module opens")?;
298 out.write_u2(count(self.uses.len(), "module uses")?)?;
299 for v in &self.uses {
300 out.write_u2(*v)?;
301 }
302 out.write_u2(count(self.provides.len(), "module provides")?)?;
303 for v in &self.provides {
304 out.write_u2(v.service_index)?;
305 out.write_u2(count(v.providers.len(), "module providers")?)?;
306 for provider in &v.providers {
307 out.write_u2(*provider)?;
308 }
309 }
310 Ok(out.into_bytes())
311 }
312}
313
314pub fn standard_attribute_min_major(name: &str) -> Option<u16> {
316 match name {
317 "Signature"
318 | "SourceDebugExtension"
319 | "LocalVariableTypeTable"
320 | "EnclosingMethod"
321 | "RuntimeVisibleAnnotations"
322 | "RuntimeInvisibleAnnotations"
323 | "RuntimeVisibleParameterAnnotations"
324 | "RuntimeInvisibleParameterAnnotations"
325 | "AnnotationDefault" => Some(49),
326 "StackMapTable" => Some(50),
327 "BootstrapMethods" => Some(51),
328 "MethodParameters"
329 | "RuntimeVisibleTypeAnnotations"
330 | "RuntimeInvisibleTypeAnnotations" => Some(52),
331 "Module" | "ModulePackages" | "ModuleMainClass" => Some(53),
332 "NestHost" | "NestMembers" => Some(55),
333 "Record" => Some(60),
334 "PermittedSubclasses" => Some(61),
335 "ConstantValue" | "Code" | "Exceptions" | "InnerClasses" | "Synthetic" | "SourceFile"
336 | "LineNumberTable" | "LocalVariableTable" | "Deprecated" => Some(45),
337 _ => None,
338 }
339}