@@ -81,6 +81,9 @@ def test_f64_eof_raises(self) -> None:
8181
8282
8383class TestIntegers :
84+ # Values chosen to cover the LEB128 encoding-length boundary (127/128 is the largest
85+ # 1-byte/smallest 2-byte unsigned value), a 3-byte encoding (624485), and the
86+ # extremes of each type's range.
8487 U32_VALUES = [0 , 1 , 127 , 128 , 300 , 624485 , 2 ** 32 - 1 ]
8588 U64_VALUES = [0 , 1 , 2 ** 32 , 2 ** 35 + 1 , 2 ** 64 - 1 ]
8689 I32_VALUES = [0 , 1 , - 1 , 127 , - 128 , 2 ** 31 - 1 , - (2 ** 31 )]
@@ -155,6 +158,9 @@ def test_i64_with_max(self) -> None:
155158 assert at == wast .i64
156159 assert lim == (1 , 2 )
157160
161+ # 0x02/0x03 sit between the accepted flags (0x00/0x01 i32, 0x04/0x05 i64) but are the
162+ # threads proposal's shared-memory flags; the K semantics has no shared memory, so they
163+ # must be rejected rather than misread as an address type.
158164 @pytest .mark .parametrize ('flag' , [0x02 , 0x03 ])
159165 def test_shared_memory_flags_rejected (self , flag : int ) -> None :
160166 with pytest .raises (WasmParseError ):
@@ -168,8 +174,8 @@ def test_successful_peek_does_not_advance_stream(self) -> None:
168174 assert s .tell () == 0
169175
170176 def test_partial_eof_restores_stream_position (self ) -> None :
171- # only 1 byte available, but 2 are requested : the short read must not leave the
172- # stream advanced past the byte it couldn't help but consume while trying .
177+ # 2 bytes requested but only 1 available : the failed peek must restore the
178+ # position instead of leaving the stream advanced by the partial read .
173179 s = stream (b'\x40 ' )
174180 with pytest .raises (WasmEOFError ):
175181 peek_bytes (2 , s )
@@ -187,9 +193,13 @@ def _wrap(self, *sections: bytes) -> bytes:
187193 return MAGIC + VERSION + b'' .join (sections )
188194
189195 def test_custom_sections_do_not_break_stream_alignment (self ) -> None :
196+ # 1 functype (0x60): params [i32 (0x7F)], results [i32 (0x7F)]
190197 type_section = section (1 , uleb128 (1 ) + bytes ([0x60 ]) + uleb128 (1 ) + bytes ([0x7F ]) + uleb128 (1 ) + bytes ([0x7F ]))
198+ # 1 function with typeidx 0
191199 func_section = section (3 , uleb128 (1 ) + uleb128 (0 ))
200+ # 1 export: name "f", kind func (0x00), funcidx 0
192201 export_section = section (7 , uleb128 (1 ) + (uleb128 (len (b'f' )) + b'f' + bytes ([0x00 ]) + uleb128 (0 )))
202+ # 1 code entry of size 4: 0 local decls, body 'local.get 0 (0x20 0x00); end (0x0B)'
193203 code_section = section (10 , uleb128 (1 ) + (uleb128 (4 ) + bytes ([0x00 , 0x20 , 0x00 , 0x0B ])))
194204
195205 data = self ._wrap (
@@ -231,12 +241,15 @@ def test_trailing_garbage_after_sections_rejected(self) -> None:
231241
232242class TestFuncCodeLengthMismatch :
233243 def test_more_funcs_than_code_entries_rejected (self ) -> None :
244+ # func section declares 1 function (typeidx 0), code section has 0 entries
234245 func_section = section (3 , uleb128 (1 ) + uleb128 (0 ))
235246 code_section = section (10 , uleb128 (0 ))
236247 with pytest .raises (WasmParseError ):
237248 parse_module (stream (MAGIC + VERSION + func_section + code_section ))
238249
239250 def test_more_code_entries_than_funcs_rejected (self ) -> None :
251+ # func section declares 0 functions, code section has 1 entry of size 2:
252+ # 0 local decls, body 'end (0x0B)'
240253 func_section = section (3 , uleb128 (0 ))
241254 code_section = section (10 , uleb128 (1 ) + (uleb128 (2 ) + bytes ([0x00 , 0x0B ])))
242255 with pytest .raises (WasmParseError ):
@@ -255,8 +268,9 @@ def unwrap_instr(k: KApply) -> KApply:
255268
256269
257270class TestInstructions :
258- # the trailing sentinel byte proves the parser consumes exactly the memidx
259- # operands; see the if tests below for details
271+ # Each success-case encoding ends with a 0x01 sentinel byte that is not part of the
272+ # instruction; asserting `s.read(1) == b'\x01'` after parsing proves the parser
273+ # consumed exactly the instruction's bytes (no under- or over-read).
260274 def test_memory_copy (self ) -> None :
261275 # 0xFC 10 dst_memidx=0 src_memidx=0
262276 s = stream (bytes ([0xFC ]) + uleb128 (10 ) + uleb128 (0 ) + uleb128 (0 ) + b'\x01 ' )
@@ -308,8 +322,7 @@ def test_if_without_else(self) -> None:
308322 # 0x40 blocktype: empty (no result type)
309323 # 0x01 nop (the then-branch) — no 0x05 else opcode follows
310324 # 0x0B end: terminates the if directly
311- # 0x01 sentinel: not part of the instruction; read back after parsing to
312- # prove the parser consumed exactly the instruction's bytes
325+ # 0x01 sentinel
313326 s = stream (bytes ([0x04 , 0x40 , 0x01 , 0x0B ]) + b'\x01 ' )
314327 i = instr (s )
315328 expected = wast .INSTR_WITH_POS (
@@ -331,8 +344,7 @@ def test_if_with_else(self) -> None:
331344 # 0x05 else opcode
332345 # 0x00 unreachable (the else-branch)
333346 # 0x0B end: terminates the if
334- # 0x01 sentinel: not part of the instruction; read back after parsing to
335- # prove the parser consumed exactly the instruction's bytes
347+ # 0x01 sentinel
336348 s = stream (bytes ([0x04 , 0x40 , 0x01 , 0x05 , 0x00 , 0x0B ]) + b'\x01 ' )
337349 i = instr (s )
338350 expected = wast .INSTR_WITH_POS (
@@ -355,8 +367,7 @@ def test_if_without_else_nested_in_block(self) -> None:
355367 # 0x00 unreachable (the then-branch)
356368 # 0x0B end: terminates the inner if (no else branch)
357369 # 0x0B end: terminates the enclosing block
358- # 0x01 sentinel: not part of the instruction; read back after parsing to
359- # prove the parser consumed exactly the instruction's bytes
370+ # 0x01 sentinel
360371 s = stream (bytes ([0x02 , 0x40 , 0x04 , 0x40 , 0x00 , 0x0B , 0x0B ]) + b'\x01 ' )
361372 i = instr (s )
362373 expected = wast .INSTR_WITH_POS (
0 commit comments