passes: junk classes with real bodies and no fingerprint

NoisePass now builds branching helper methods (counted int loop,
random arithmetic, even/odd merge, non-throwing ops only) whose
results the entry sums into a private static field, instead of an
empty run()V. Names come from the same NameGenerator styles as
real code and live in a random real package (no more shadow/decoy
uniformity for grep to catch); every generated method gets fresh
StackMapTable frames. weave_first_reachable takes (class, entry)
pairs. New NoiseConfig.junk_methods_per_class (default 3).

Tests assert invariants (unique valid identifiers, calls, field
store, determinism) plus real-JVM verification of junk classes;
paranoid+junk_ratio=1 smoke on lorep: 18 junk classes, all load.
This commit is contained in:
Loki 2026-10-09 14:04:24 +02:00
parent 74ad4552e4
commit 2cbb9db31e
Signed by: boba
GPG key ID: 253067914055423B
11 changed files with 648 additions and 159 deletions

View file

@ -148,6 +148,9 @@ impl Default for ConstantsConfig {
pub struct NoiseConfig {
/// How many junk classes per real one (0 = disabled).
pub junk_ratio: usize,
/// Branching helper methods per junk class (their results feed a
/// static field so the bodies read as live code, not dead weight).
pub junk_methods_per_class: usize,
/// Number of junk annotations per class.
pub junk_annotations: usize,
/// Weave junk classes into the reachability graph (required for them to
@ -159,6 +162,7 @@ impl Default for NoiseConfig {
fn default() -> Self {
Self {
junk_ratio: 0,
junk_methods_per_class: 3,
junk_annotations: 0,
weave_reachable: true,
}

View file

@ -72,7 +72,7 @@ impl Rng {
}
}
/// Перемешать срез на месте (Fisher–Yates).
/// Перемешать срез на месте (Fisher-Yates).
pub fn shuffle<T>(&mut self, items: &mut [T]) {
for i in (1..items.len()).rev() {
let j = self.below((i + 1) as u64) as usize;