@@ -44,6 +44,10 @@ pub struct Printer {
44
44
print_offsets : bool ,
45
45
printers : HashMap < String , Box < dyn FnMut ( & mut Printer , usize , & [ u8 ] ) -> Result < ( ) > > > ,
46
46
result : String ,
47
+ /// The `i`th line in `result` is at offset `lines[i]`.
48
+ lines : Vec < usize > ,
49
+ /// The binary offset for the `i`th line is `line_offsets[i]`.
50
+ line_offsets : Vec < Option < usize > > ,
47
51
nesting : u32 ,
48
52
line : usize ,
49
53
group_lines : Vec < usize > ,
@@ -160,6 +164,29 @@ impl Printer {
160
164
Ok ( mem:: take ( & mut self . result ) )
161
165
}
162
166
167
+ /// Get the line-by-line WAT disassembly for the given Wasm, along with the
168
+ /// binary offsets for each line.
169
+ pub fn offsets_and_lines < ' a > (
170
+ & ' a mut self ,
171
+ wasm : & [ u8 ] ,
172
+ ) -> Result < impl Iterator < Item = ( Option < usize > , & ' a str ) > + ' a > {
173
+ self . print_contents ( wasm) ?;
174
+
175
+ let end = self . result . len ( ) ;
176
+ let result = & self . result ;
177
+
178
+ let mut offsets = self . line_offsets . iter ( ) . copied ( ) ;
179
+ let mut lines = self . lines . iter ( ) . copied ( ) . peekable ( ) ;
180
+
181
+ Ok ( std:: iter:: from_fn ( move || {
182
+ let offset = offsets. next ( ) ?;
183
+ let i = lines. next ( ) ?;
184
+ let j = lines. peek ( ) . copied ( ) . unwrap_or ( end) ;
185
+ let line = & result[ i..j] ;
186
+ Some ( ( offset, line) )
187
+ } ) )
188
+ }
189
+
163
190
fn read_names_and_code < ' a > (
164
191
& mut self ,
165
192
mut bytes : & ' a [ u8 ] ,
@@ -233,6 +260,11 @@ impl Printer {
233
260
}
234
261
235
262
fn print_contents ( & mut self , mut bytes : & [ u8 ] ) -> Result < ( ) > {
263
+ self . lines . clear ( ) ;
264
+ self . lines . push ( 0 ) ;
265
+ self . line_offsets . clear ( ) ;
266
+ self . line_offsets . push ( Some ( 0 ) ) ;
267
+
236
268
let mut expected = None ;
237
269
let mut states: Vec < State > = Vec :: new ( ) ;
238
270
let mut parser = Parser :: new ( 0 ) ;
@@ -1009,6 +1041,10 @@ impl Printer {
1009
1041
1010
1042
fn print_newline ( & mut self , offset : Option < usize > ) {
1011
1043
self . result . push ( '\n' ) ;
1044
+
1045
+ self . lines . push ( self . result . len ( ) ) ;
1046
+ self . line_offsets . push ( offset) ;
1047
+
1012
1048
if self . print_offsets {
1013
1049
match offset {
1014
1050
Some ( offset) => write ! ( self . result, "(;@{offset:<6x};)" ) . unwrap ( ) ,
0 commit comments