parsley
parsley copied to clipboard
[BUG] Recursive Let Found parsers in flat-map causes CalleeSave re-entry
Description
CalleeSave is designed to either be entered or exited, however as this parser can be let found (meaning we don't regenerate the instructions for it), if you recursively call a flatMap from within a flatMap and access the same CalleeSave instance, CalleeSave thinks we're leaving this scope so restores the outside registers which leads to undefined behaviour
Reproduction Steps
Write this code:
var x: Parsley[Unit] = pure(())
var death: Parsley[Unit] = 'x'.flatMap(_ => x)
x = death *> 1.makeRef(_=> pure('a'))
death.parse("xxx")
Expected behavior
This parser should return a failure with unexpected end of input but the scopes of the registers inside should still be consistent (it's possible to write a recursive state like this that uses the state to end the infinite recursion but this is the simplest example I could find that shows the bug)
Additional context
Parsley Version: 5.0 staging Scala Version: Both 2.13 and 3