classfile: model RuntimeVisible/InvisibleParameterAnnotations (fixes ASM AIOOBE on write)
Parameter annotations were unmodeled and fell through to Raw with stale constant-pool indices after the pool rebuild. ASM (Paper converter, Fabric mixin transformer) then failed with ArrayIndexOutOfBoundsException in readParameterAnnotations. Now parsed and rewritten like class-level annotations.
This commit is contained in:
parent
045cd3ed9c
commit
b73c72d56d
5 changed files with 80 additions and 1 deletions
|
|
@ -123,6 +123,36 @@ pub(super) fn convert(attr: &RtAttr, pool: &ConstantPool<'_>) -> Result<Attribut
|
|||
.collect::<Result<_, _>>()?,
|
||||
)
|
||||
}
|
||||
RtAttr::RuntimeVisibleParameterAnnotations {
|
||||
parameter_annotations,
|
||||
..
|
||||
} => Attribute::RuntimeVisibleParameterAnnotations(
|
||||
parameter_annotations
|
||||
.iter()
|
||||
.map(|param| {
|
||||
param
|
||||
.annotations
|
||||
.iter()
|
||||
.map(|anno| annotation(pool, anno))
|
||||
.collect::<Result<_, _>>()
|
||||
})
|
||||
.collect::<Result<_, _>>()?,
|
||||
),
|
||||
RtAttr::RuntimeInvisibleParameterAnnotations {
|
||||
parameter_annotations,
|
||||
..
|
||||
} => Attribute::RuntimeInvisibleParameterAnnotations(
|
||||
parameter_annotations
|
||||
.iter()
|
||||
.map(|param| {
|
||||
param
|
||||
.annotations
|
||||
.iter()
|
||||
.map(|anno| annotation(pool, anno))
|
||||
.collect::<Result<_, _>>()
|
||||
})
|
||||
.collect::<Result<_, _>>()?,
|
||||
),
|
||||
other => raw(other)?,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -193,6 +193,38 @@ pub(super) fn convert(attr: &Attribute, pool: &mut Pool) -> Result<RtAttr, Class
|
|||
.map(|anno| annotation(anno, pool))
|
||||
.collect::<Result<_, _>>()?,
|
||||
},
|
||||
Attribute::RuntimeVisibleParameterAnnotations(params) => {
|
||||
RtAttr::RuntimeVisibleParameterAnnotations {
|
||||
name_index: pool.utf8("RuntimeVisibleParameterAnnotations")?,
|
||||
parameter_annotations: params
|
||||
.iter()
|
||||
.map(|param| {
|
||||
Ok(ristretto_classfile::attributes::ParameterAnnotation {
|
||||
annotations: param
|
||||
.iter()
|
||||
.map(|anno| annotation(anno, pool))
|
||||
.collect::<Result<_, _>>()?,
|
||||
})
|
||||
})
|
||||
.collect::<Result<_, _>>()?,
|
||||
}
|
||||
}
|
||||
Attribute::RuntimeInvisibleParameterAnnotations(params) => {
|
||||
RtAttr::RuntimeInvisibleParameterAnnotations {
|
||||
name_index: pool.utf8("RuntimeInvisibleParameterAnnotations")?,
|
||||
parameter_annotations: params
|
||||
.iter()
|
||||
.map(|param| {
|
||||
Ok(ristretto_classfile::attributes::ParameterAnnotation {
|
||||
annotations: param
|
||||
.iter()
|
||||
.map(|anno| annotation(anno, pool))
|
||||
.collect::<Result<_, _>>()?,
|
||||
})
|
||||
})
|
||||
.collect::<Result<_, _>>()?,
|
||||
}
|
||||
}
|
||||
Attribute::Raw { name, data } => RtAttr::Unknown {
|
||||
name_index: pool.utf8(name)?,
|
||||
info: data.clone(),
|
||||
|
|
|
|||
|
|
@ -48,6 +48,12 @@ pub enum Attribute {
|
|||
RuntimeVisibleAnnotations(Vec<Annotation>),
|
||||
/// `RuntimeInvisibleAnnotations` (JVMS §4.7.17): CLASS-retention ones.
|
||||
RuntimeInvisibleAnnotations(Vec<Annotation>),
|
||||
/// `RuntimeVisibleParameterAnnotations` (JVMS §4.7.18): per-parameter
|
||||
/// annotations. Parsed like the class-level ones - raw pool indices go
|
||||
/// stale when the pool is rebuilt.
|
||||
RuntimeVisibleParameterAnnotations(Vec<Vec<Annotation>>),
|
||||
/// `RuntimeInvisibleParameterAnnotations` (JVMS §4.7.19).
|
||||
RuntimeInvisibleParameterAnnotations(Vec<Vec<Annotation>>),
|
||||
/// Everything else: name + raw `info` bytes (careful with pool indices).
|
||||
Raw {
|
||||
name: String,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue