labels: add class_reader, hand-rolled JVM .class file parser
Foundation for label parsers that need structured access to .class
files inside /BDMV/JAR/<x>.jar. Replaces noak (~3KLOC dep) with a
~1000-line std-only reader.
Public API:
- ClassFile::parse(&[u8]) -> Result<ClassFile>
- ConstantPool::{get, utf8, class_name, string, integer, member_ref, iter}
- Member::code(&pool) -> Option<CodeAttribute>
- CodeAttribute::instructions() -> Instructions iterator
- Instruction::{name, operand_u8, operand_u16, cp_index}
- Opcode constants (LDC, AASTORE, NEW, GETSTATIC, INVOKESPECIAL, ...)
Spec coverage:
- Constant pool: all 17 tag types incl. Long/Double 2-slot quirk
- Modified UTF-8 incl. 0xC0 0x80 -> U+0000 special case
- Bytecode iteration with full opcode size table
- Variable-length tableswitch / lookupswitch / wide
12 unit tests cover the opcode table edge cases (padded switch tables,
wide-iinc 6-byte form), modified-UTF-8 decoder, and iterator
stop-on-truncated behaviour.
Module is currently #![allow(dead_code)] — the public API is staged
for labels::deluxe (Phases A-E bytecode walker) and a labels::dbp
refactor onto the constant-pool iterator. Tests exercise the API
in isolation. The allow comes off as those callers land.
Also fixes two pre-existing clippy lints that 1.86's stricter checks
flagged after I touched the labels module:
- src/mux/disc.rs: while-let-loop in test fixture
- tests/pass_n_size_aware_skip.rs: type_complexity in helper signature
Precommit (cargo +1.86 fmt + clippy + test) green.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,7 @@
|
|||||||
//! 3. Implement `pub fn parse(reader: &mut dyn SectorReader, udf: &UdfFs) -> Option<Vec<StreamLabel>>`
|
//! 3. Implement `pub fn parse(reader: &mut dyn SectorReader, udf: &UdfFs) -> Option<Vec<StreamLabel>>`
|
||||||
//! 4. Add `mod myformat;` below and one line to `PARSERS` array
|
//! 4. Add `mod myformat;` below and one line to `PARSERS` array
|
||||||
|
|
||||||
|
pub(crate) mod class_reader;
|
||||||
mod criterion;
|
mod criterion;
|
||||||
mod ctrm;
|
mod ctrm;
|
||||||
mod dbp;
|
mod dbp;
|
||||||
|
|||||||
+2
-5
@@ -657,11 +657,8 @@ mod tests {
|
|||||||
// produces no frames, but the call still routes through the blanket
|
// produces no frames, but the call still routes through the blanket
|
||||||
// dispatch into Stream::read.
|
// dispatch into Stream::read.
|
||||||
let mut frames = 0usize;
|
let mut frames = 0usize;
|
||||||
loop {
|
while src.read().expect("read").is_some() {
|
||||||
match src.read().expect("read") {
|
frames += 1;
|
||||||
Some(_) => frames += 1,
|
|
||||||
None => break,
|
|
||||||
}
|
|
||||||
if frames > 1024 {
|
if frames > 1024 {
|
||||||
panic!("unexpected unbounded frame stream from empty title");
|
panic!("unexpected unbounded frame stream from empty title");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,8 +30,10 @@ struct PatternedSectorReader {
|
|||||||
trace: Arc<Mutex<Vec<(u32, u16)>>>,
|
trace: Arc<Mutex<Vec<(u32, u16)>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ReadTrace = Arc<Mutex<Vec<(u32, u16)>>>;
|
||||||
|
|
||||||
impl PatternedSectorReader {
|
impl PatternedSectorReader {
|
||||||
fn new(capacity: u32, bad_lbas: HashSet<u32>) -> (Self, Arc<Mutex<Vec<(u32, u16)>>>) {
|
fn new(capacity: u32, bad_lbas: HashSet<u32>) -> (Self, ReadTrace) {
|
||||||
let trace = Arc::new(Mutex::new(Vec::new()));
|
let trace = Arc::new(Mutex::new(Vec::new()));
|
||||||
(
|
(
|
||||||
Self {
|
Self {
|
||||||
|
|||||||
Reference in New Issue
Block a user