passes: rename rewrites invokedynamic descriptors and BootstrapMethods refs

This commit is contained in:
Loki 2026-10-11 10:34:42 +02:00
parent 9a33cef9b1
commit 8fcecee849
Signed by: boba
GPG key ID: 253067914055423B
3 changed files with 166 additions and 6 deletions

View file

@ -2,7 +2,7 @@
mod code;
use noxis_classfile::{Attribute, ClassFile, StackMapFrame, VerificationType};
use noxis_classfile::{Attribute, ClassFile, Const, StackMapFrame, VerificationType};
use noxis_core::{Config, Context};
use super::assign::{RenameMaps, rewrite_descriptor};
@ -141,6 +141,14 @@ fn rewrite_attributes(
}
}
}
Attribute::BootstrapMethods(methods) => {
for bsm in methods.iter_mut() {
rewrite_method_ref(&mut bsm.owner, &mut bsm.name, &mut bsm.descriptor, maps);
for arg in bsm.args.iter_mut() {
rewrite_const(arg, maps);
}
}
}
Attribute::LocalVariableTable(vars) => {
for var in vars.iter_mut() {
var.descriptor = rewrite_descriptor(&var.descriptor, &maps.classes);
@ -164,6 +172,54 @@ fn rewrite_attributes(
}
}
/// A method reference (invoke/bootstrap/method-handle): the owner follows
/// class renames, the name follows member renames, the descriptor is
/// rewritten. Callers decide whether the name may move at all.
fn rewrite_method_ref(
owner: &mut String,
name: &mut String,
descriptor: &mut String,
maps: &RenameMaps,
) {
if let Some(new_name) = maps.method(owner, name, descriptor) {
*name = new_name;
}
if let Some(mapped) = maps.classes.get(owner.as_str()) {
*owner = mapped.clone();
}
*descriptor = rewrite_descriptor(descriptor, &maps.classes);
}
/// A constant-pool reference inside code or bootstrap arguments: class
/// literals (plain or array), method types, method handles, condy payloads.
/// Anything else (numbers, strings) has no references to follow.
fn rewrite_const(value: &mut Const, maps: &RenameMaps) {
match value {
Const::Class(name) => {
if name.starts_with('[') {
*name = rewrite_descriptor(name, &maps.classes);
} else if let Some(mapped) = maps.classes.get(name.as_str()) {
*name = mapped.clone();
}
}
Const::MethodType(descriptor) => {
*descriptor = rewrite_descriptor(descriptor, &maps.classes);
}
Const::MethodHandle {
owner,
name,
descriptor,
..
} => {
rewrite_method_ref(owner, name, descriptor, maps);
}
Const::Dynamic { descriptor, .. } => {
*descriptor = rewrite_descriptor(descriptor, &maps.classes);
}
_ => {}
}
}
/// Имена классов внутри одного кадра (`Object(..)` в locals/stack).
fn rewrite_frame(frame: &mut StackMapFrame, maps: &RenameMaps) {
match frame {