@@ -7,11 +7,11 @@ use std::fmt::Write as _;
77
88use crate :: colors:: Colors ;
99
10- use super :: format:: { format_effect , nav_symbol_epsilon , width_for_count , LineBuilder , Symbol } ;
10+ use super :: format:: { LineBuilder , Symbol , format_effect , nav_symbol_epsilon , width_for_count } ;
1111use super :: ids:: { QTypeId , StepId } ;
1212use super :: module:: { Instruction , Module } ;
1313use super :: type_meta:: TypeKind ;
14- use super :: { Call , Match , Return } ;
14+ use super :: { Call , Match , Return , Trampoline } ;
1515
1616/// Generate a human-readable dump of the bytecode module.
1717pub fn dump ( module : & Module , colors : Colors ) -> String {
@@ -37,7 +37,6 @@ fn dump_header(out: &mut String, module: &Module, ctx: &DumpContext) {
3737 out. push ( '\n' ) ;
3838}
3939
40-
4140/// Context for dump formatting, precomputes lookups for O(1) access.
4241struct DumpContext {
4342 /// Whether the bytecode is linked (contains grammar IDs vs StringIds).
@@ -74,6 +73,8 @@ impl DumpContext {
7473 let node_fields = module. node_fields ( ) ;
7574
7675 let mut step_labels = BTreeMap :: new ( ) ;
76+ // Preamble always starts at step 0
77+ step_labels. insert ( 0 , "_ObjWrap" . to_string ( ) ) ;
7778 for i in 0 ..entrypoints. len ( ) {
7879 let ep = entrypoints. get ( i) ;
7980 let name = strings. get ( ep. name ) . to_string ( ) ;
@@ -249,10 +250,7 @@ fn dump_types_members(out: &mut String, module: &Module, ctx: &DumpContext) {
249250 writeln ! (
250251 out,
251252 "M{i:0mw$}: S{:0sw$} → T{:0tw$} {}; {name}: {type_name}{}" ,
252- member. name. 0 ,
253- member. type_id. 0 ,
254- c. dim,
255- c. reset
253+ member. name. 0 , member. type_id. 0 , c. dim, c. reset
256254 )
257255 . unwrap ( ) ;
258256 }
@@ -274,11 +272,7 @@ fn dump_types_names(out: &mut String, module: &Module, ctx: &DumpContext) {
274272 writeln ! (
275273 out,
276274 "N{i:0nw$}: S{:0sw$} → T{:0tw$} {}; {}{name}{}" ,
277- entry. name. 0 ,
278- entry. type_id. 0 ,
279- c. dim,
280- c. blue,
281- c. reset
275+ entry. name. 0 , entry. type_id. 0 , c. dim, c. blue, c. reset
282276 )
283277 . unwrap ( ) ;
284278 }
@@ -356,10 +350,16 @@ fn dump_code(out: &mut String, module: &Module, ctx: &DumpContext) {
356350 writeln ! ( out, "{}[transitions]{}" , c. blue, c. reset) . unwrap ( ) ;
357351
358352 let mut step = 0u16 ;
353+ let mut first_label = true ;
359354 while ( step as usize ) < transitions_count {
360355 // Check if this step has a label (using raw u16)
361356 if let Some ( label) = ctx. step_labels . get ( & step) {
362- writeln ! ( out, "\n {}{label}{}:" , c. blue, c. reset) . unwrap ( ) ;
357+ if first_label {
358+ writeln ! ( out, "{}{label}{}:" , c. blue, c. reset) . unwrap ( ) ;
359+ first_label = false ;
360+ } else {
361+ writeln ! ( out, "\n {}{label}{}:" , c. blue, c. reset) . unwrap ( ) ;
362+ }
363363 }
364364
365365 let instr = module. decode_step_alloc ( step) ;
@@ -373,7 +373,6 @@ fn dump_code(out: &mut String, module: &Module, ctx: &DumpContext) {
373373 }
374374}
375375
376-
377376fn instruction_step_count ( instr : & Instruction ) -> u16 {
378377 match instr {
379378 Instruction :: Match ( m) => {
@@ -400,11 +399,10 @@ fn instruction_step_count(instr: &Instruction) -> u16 {
400399 8 // Match64
401400 }
402401 }
403- Instruction :: Call ( _) | Instruction :: Return ( _) => 1 ,
402+ Instruction :: Call ( _) | Instruction :: Return ( _) | Instruction :: Trampoline ( _ ) => 1 ,
404403 }
405404}
406405
407-
408406fn format_instruction (
409407 step : u16 ,
410408 instr : & Instruction ,
@@ -416,10 +414,10 @@ fn format_instruction(
416414 Instruction :: Match ( m) => format_match ( step, m, module, ctx, step_width) ,
417415 Instruction :: Call ( c) => format_call ( step, c, module, ctx, step_width) ,
418416 Instruction :: Return ( r) => format_return ( step, r, module, ctx, step_width) ,
417+ Instruction :: Trampoline ( t) => format_trampoline ( step, t, ctx, step_width) ,
419418 }
420419}
421420
422-
423421fn format_match (
424422 step : u16 ,
425423 m : & Match ,
@@ -571,6 +569,20 @@ fn format_return(
571569 builder. pad_successors ( prefix, "▶" )
572570}
573571
572+ fn format_trampoline ( step : u16 , t : & Trampoline , _ctx : & DumpContext , step_width : usize ) -> String {
573+ let builder = LineBuilder :: new ( step_width) ;
574+ let prefix = format ! (
575+ " {:0sw$} {} " ,
576+ step,
577+ Symbol :: EMPTY . format( ) ,
578+ sw = step_width
579+ ) ;
580+ let content = "Trampoline" ;
581+ let successors = format ! ( "{:0w$}" , t. next. get( ) , w = step_width) ;
582+ let base = format ! ( "{prefix}{content}" ) ;
583+ builder. pad_successors ( base, & successors)
584+ }
585+
574586/// Format a step ID, showing entrypoint label or numeric ID.
575587fn format_step ( step : StepId , ctx : & DumpContext , step_width : usize ) -> String {
576588 let c = & ctx. colors ;
@@ -580,4 +592,3 @@ fn format_step(step: StepId, ctx: &DumpContext, step_width: usize) -> String {
580592 format ! ( "{:0w$}" , step. get( ) , w = step_width)
581593 }
582594}
583-
0 commit comments