BlockIter

Struct BlockIter 

Source
pub struct BlockIter<'global_state, 'input> {
    pub id: u32,
    /* private fields */
}
Expand description

Iterator content directly in a block

Fields§

§id: u32

ID of the block being iterated

Implementations§

Source§

impl<'global_state, 'input> BlockIter<'global_state, 'input>

Source

pub fn next_record<'parent>( &'parent mut self, ) -> Result<Option<RecordIter<'parent, 'input>>, Error>

Source

pub fn next<'parent>( &'parent mut self, ) -> Result<Option<BlockItem<'parent, 'input>>, Error>

Returns the next item (block or record) in this block

Examples found in repository?
examples/llvm_bca.rs (line 27)
25fn iter_block(mut block: BlockIter, depth: usize) -> Result<(), Error> {
26    let outer_block_id = block.id;
27    while let Some(b) = block.next()? {
28        match b {
29            BlockItem::Block(b) => {
30                let tag_name = block_tag_name(b.id as _);
31                println!(
32                    "{:indent$}<{tag_name} NumWords={nw} BlockCodeSize={ab}>",
33                    "",
34                    nw = b.debug_data_len().unwrap_or(0) / 4,
35                    ab = b.debug_abbrev_width(),
36                    indent = depth * 2
37                );
38                iter_block(b, depth + 1)?;
39                println!("{:indent$}</{tag_name}>", "", indent = depth * 2);
40            }
41            BlockItem::Record(mut r) => {
42                let tag_name = record_tag_name(outer_block_id as _, r.id as _);
43                print!("{:indent$}<{tag_name}", "", indent = depth * 2);
44                if let Some(a) = r.debug_abbrev_id() {
45                    print!(" abbrevid={a}");
46                }
47                let fields = r
48                    .by_ref()
49                    .map(|f| f.map(|f| f as i64))
50                    .collect::<Result<Vec<_>, _>>()?;
51                for (i, &op) in fields.iter().enumerate() {
52                    print!(" op{i}={op}");
53                }
54                let payload: Result<_, _> = r.payload();
55                match payload {
56                    Ok(Some(llvm_bitcode::bitcode::Payload::Array(a))) => {
57                        for (i, op) in a.iter().enumerate() {
58                            print!(" op{}={op}", i + fields.len());
59                        }
60                        if !a.is_empty() && a.iter().all(|&c| (c as u8) >= 0x20 && (c as u8) < 0x7F)
61                        {
62                            // lol bug in the original
63                            let s: String = a.iter().map(|&c| c as u8 as char).collect();
64                            println!("/> record string = '{s}'");
65                        } else {
66                            println!("/>");
67                        }
68                    }
69                    Ok(Some(llvm_bitcode::bitcode::Payload::Char6String(s))) => {
70                        for (i, op) in s.chars().enumerate() {
71                            print!(" op{}={}", i + fields.len(), op as u32);
72                        }
73                        if s.is_empty() {
74                            println!("/>");
75                        } else {
76                            println!("/> record string = '{s}'");
77                        }
78                    }
79                    Ok(None) => {
80                        if r.debug_abbrev_id().is_some()
81                            && fields.len() > 1
82                            && fields.iter().skip(1).all(|&c| (0x20..0x7F).contains(&c))
83                        {
84                            let s: String =
85                                fields.iter().skip(1).map(|&c| c as u8 as char).collect();
86                            println!("/> record string = '{s}'");
87                        } else {
88                            println!("/>");
89                        }
90                    }
91                    Ok(Some(llvm_bitcode::bitcode::Payload::Blob(b))) => {
92                        if b.len() < 10000 && b.iter().all(|&c| (0x20..0x7F).contains(&c)) {
93                            println!("/> blob data = {}", String::from_utf8_lossy(&b));
94                        } else {
95                            print!("/> blob data = ");
96                            if b.len() > 50 {
97                                print!("unprintable, {} bytes.", b.len());
98                            } else {
99                                print!("'");
100                                for b in b {
101                                    print!("{b:02x}");
102                                }
103                                print!("'");
104                            }
105                            println!();
106                        }
107                    }
108                    Err(err) => print!("/> payload_err={err}"),
109                }
110            }
111        }
112    }
113    Ok(())
114}
Source

pub fn debug_abbrev_width(&self) -> u8

Bit width of abbreviation IDs in this block.

This is an implementation detail, intended only for debugging or data dumps.

Examples found in repository?
examples/llvm_bca.rs (line 35)
25fn iter_block(mut block: BlockIter, depth: usize) -> Result<(), Error> {
26    let outer_block_id = block.id;
27    while let Some(b) = block.next()? {
28        match b {
29            BlockItem::Block(b) => {
30                let tag_name = block_tag_name(b.id as _);
31                println!(
32                    "{:indent$}<{tag_name} NumWords={nw} BlockCodeSize={ab}>",
33                    "",
34                    nw = b.debug_data_len().unwrap_or(0) / 4,
35                    ab = b.debug_abbrev_width(),
36                    indent = depth * 2
37                );
38                iter_block(b, depth + 1)?;
39                println!("{:indent$}</{tag_name}>", "", indent = depth * 2);
40            }
41            BlockItem::Record(mut r) => {
42                let tag_name = record_tag_name(outer_block_id as _, r.id as _);
43                print!("{:indent$}<{tag_name}", "", indent = depth * 2);
44                if let Some(a) = r.debug_abbrev_id() {
45                    print!(" abbrevid={a}");
46                }
47                let fields = r
48                    .by_ref()
49                    .map(|f| f.map(|f| f as i64))
50                    .collect::<Result<Vec<_>, _>>()?;
51                for (i, &op) in fields.iter().enumerate() {
52                    print!(" op{i}={op}");
53                }
54                let payload: Result<_, _> = r.payload();
55                match payload {
56                    Ok(Some(llvm_bitcode::bitcode::Payload::Array(a))) => {
57                        for (i, op) in a.iter().enumerate() {
58                            print!(" op{}={op}", i + fields.len());
59                        }
60                        if !a.is_empty() && a.iter().all(|&c| (c as u8) >= 0x20 && (c as u8) < 0x7F)
61                        {
62                            // lol bug in the original
63                            let s: String = a.iter().map(|&c| c as u8 as char).collect();
64                            println!("/> record string = '{s}'");
65                        } else {
66                            println!("/>");
67                        }
68                    }
69                    Ok(Some(llvm_bitcode::bitcode::Payload::Char6String(s))) => {
70                        for (i, op) in s.chars().enumerate() {
71                            print!(" op{}={}", i + fields.len(), op as u32);
72                        }
73                        if s.is_empty() {
74                            println!("/>");
75                        } else {
76                            println!("/> record string = '{s}'");
77                        }
78                    }
79                    Ok(None) => {
80                        if r.debug_abbrev_id().is_some()
81                            && fields.len() > 1
82                            && fields.iter().skip(1).all(|&c| (0x20..0x7F).contains(&c))
83                        {
84                            let s: String =
85                                fields.iter().skip(1).map(|&c| c as u8 as char).collect();
86                            println!("/> record string = '{s}'");
87                        } else {
88                            println!("/>");
89                        }
90                    }
91                    Ok(Some(llvm_bitcode::bitcode::Payload::Blob(b))) => {
92                        if b.len() < 10000 && b.iter().all(|&c| (0x20..0x7F).contains(&c)) {
93                            println!("/> blob data = {}", String::from_utf8_lossy(&b));
94                        } else {
95                            print!("/> blob data = ");
96                            if b.len() > 50 {
97                                print!("unprintable, {} bytes.", b.len());
98                            } else {
99                                print!("'");
100                                for b in b {
101                                    print!("{b:02x}");
102                                }
103                                print!("'");
104                            }
105                            println!();
106                        }
107                    }
108                    Err(err) => print!("/> payload_err={err}"),
109                }
110            }
111        }
112    }
113    Ok(())
114}
Source

pub fn debug_data_len(&self) -> Option<usize>

Valid only before any record or subblock has been read. This is the block size in bytes.

This is an implementation detail, intended only for debugging or data dumps.

Examples found in repository?
examples/llvm_bca.rs (line 34)
25fn iter_block(mut block: BlockIter, depth: usize) -> Result<(), Error> {
26    let outer_block_id = block.id;
27    while let Some(b) = block.next()? {
28        match b {
29            BlockItem::Block(b) => {
30                let tag_name = block_tag_name(b.id as _);
31                println!(
32                    "{:indent$}<{tag_name} NumWords={nw} BlockCodeSize={ab}>",
33                    "",
34                    nw = b.debug_data_len().unwrap_or(0) / 4,
35                    ab = b.debug_abbrev_width(),
36                    indent = depth * 2
37                );
38                iter_block(b, depth + 1)?;
39                println!("{:indent$}</{tag_name}>", "", indent = depth * 2);
40            }
41            BlockItem::Record(mut r) => {
42                let tag_name = record_tag_name(outer_block_id as _, r.id as _);
43                print!("{:indent$}<{tag_name}", "", indent = depth * 2);
44                if let Some(a) = r.debug_abbrev_id() {
45                    print!(" abbrevid={a}");
46                }
47                let fields = r
48                    .by_ref()
49                    .map(|f| f.map(|f| f as i64))
50                    .collect::<Result<Vec<_>, _>>()?;
51                for (i, &op) in fields.iter().enumerate() {
52                    print!(" op{i}={op}");
53                }
54                let payload: Result<_, _> = r.payload();
55                match payload {
56                    Ok(Some(llvm_bitcode::bitcode::Payload::Array(a))) => {
57                        for (i, op) in a.iter().enumerate() {
58                            print!(" op{}={op}", i + fields.len());
59                        }
60                        if !a.is_empty() && a.iter().all(|&c| (c as u8) >= 0x20 && (c as u8) < 0x7F)
61                        {
62                            // lol bug in the original
63                            let s: String = a.iter().map(|&c| c as u8 as char).collect();
64                            println!("/> record string = '{s}'");
65                        } else {
66                            println!("/>");
67                        }
68                    }
69                    Ok(Some(llvm_bitcode::bitcode::Payload::Char6String(s))) => {
70                        for (i, op) in s.chars().enumerate() {
71                            print!(" op{}={}", i + fields.len(), op as u32);
72                        }
73                        if s.is_empty() {
74                            println!("/>");
75                        } else {
76                            println!("/> record string = '{s}'");
77                        }
78                    }
79                    Ok(None) => {
80                        if r.debug_abbrev_id().is_some()
81                            && fields.len() > 1
82                            && fields.iter().skip(1).all(|&c| (0x20..0x7F).contains(&c))
83                        {
84                            let s: String =
85                                fields.iter().skip(1).map(|&c| c as u8 as char).collect();
86                            println!("/> record string = '{s}'");
87                        } else {
88                            println!("/>");
89                        }
90                    }
91                    Ok(Some(llvm_bitcode::bitcode::Payload::Blob(b))) => {
92                        if b.len() < 10000 && b.iter().all(|&c| (0x20..0x7F).contains(&c)) {
93                            println!("/> blob data = {}", String::from_utf8_lossy(&b));
94                        } else {
95                            print!("/> blob data = ");
96                            if b.len() > 50 {
97                                print!("unprintable, {} bytes.", b.len());
98                            } else {
99                                print!("'");
100                                for b in b {
101                                    print!("{b:02x}");
102                                }
103                                print!("'");
104                            }
105                            println!();
106                        }
107                    }
108                    Err(err) => print!("/> payload_err={err}"),
109                }
110            }
111        }
112    }
113    Ok(())
114}

Trait Implementations§

Source§

impl<'global_state, 'input> Debug for BlockIter<'global_state, 'input>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'global_state, 'input> Freeze for BlockIter<'global_state, 'input>

§

impl<'global_state, 'input> RefUnwindSafe for BlockIter<'global_state, 'input>

§

impl<'global_state, 'input> Send for BlockIter<'global_state, 'input>

§

impl<'global_state, 'input> Sync for BlockIter<'global_state, 'input>

§

impl<'global_state, 'input> Unpin for BlockIter<'global_state, 'input>

§

impl<'global_state, 'input> !UnwindSafe for BlockIter<'global_state, 'input>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.