@@ -1965,6 +1965,46 @@ test('bindings chunks contain valid CST nodes and tagged terminals', async t =>
19651965 t . true ( totalNonZero >= 1 , 'should have found at least one non-zero binding' ) ;
19661966} ) ;
19671967
1968+ // RLE-compress a Uint8Array: non-zero i32 words shown as hex, runs of
1969+ // zero words collapsed to "00*N".
1970+ function rleHexDump ( bytes ) {
1971+ const view = new DataView ( bytes . buffer , bytes . byteOffset , bytes . byteLength ) ;
1972+ const parts = [ ] ;
1973+ let i = 0 ;
1974+ while ( i < bytes . length ) {
1975+ if ( i + 4 <= bytes . length && view . getUint32 ( i , true ) === 0 ) {
1976+ let zeroWords = 0 ;
1977+ while ( i + 4 <= bytes . length && view . getUint32 ( i , true ) === 0 ) {
1978+ zeroWords ++ ;
1979+ i += 4 ;
1980+ }
1981+ parts . push ( `00*${ zeroWords } ` ) ;
1982+ } else {
1983+ const word = view . getUint32 ( i , true ) ;
1984+ parts . push ( word . toString ( 16 ) . padStart ( 8 , '0' ) ) ;
1985+ i += 4 ;
1986+ }
1987+ }
1988+ return parts . join ( ' ' ) ;
1989+ }
1990+
1991+ test ( 'snapshot: raw heap after match' , async t => {
1992+ const g = ohm . grammar ( 'G { start = "a" b\nb = "b" }' ) ;
1993+ const wasmGrammar = await toWasmGrammar ( g ) ;
1994+
1995+ const { memory, __offset} = wasmGrammar . _instance . exports ;
1996+
1997+ wasmGrammar . match ( 'ab' ) . use ( r => {
1998+ t . true ( r . succeeded ( ) ) ;
1999+
2000+ // Capture the heap region allocated during this match.
2001+ const heapStart = r . _heapWatermark ;
2002+ const heapEnd = __offset . value ;
2003+ const bytes = new Uint8Array ( memory . buffer , heapStart , heapEnd - heapStart ) ;
2004+ t . snapshot ( rleHexDump ( bytes ) ) ;
2005+ } ) ;
2006+ } ) ;
2007+
19682008test ( 'chunkedBindings: false' , async t => {
19692009 const g = ohm . grammar ( 'G { Start = letter+ ";" }' ) ;
19702010 const wasmGrammar = await toWasmGrammar ( g , { chunkedBindings : false } ) ;
0 commit comments