
Am Dienstag 05 Mai 2009 21:42:00 schrieb Tobias Olausson:
This simple implementation of CPU does not behave as expected in the latest version of ghc using ST.Lazy since it updates the `pc` in the wrong order. When we use ghc-6.8 the code works as expected both with lazy and strict ST. How is that? How do we fix this so we can use ghc-6.10.
Fix 1: compile with optimisations. The sample code worked here with that. Fix 2: change fetch:
fetch :: CPU s OPCode fetch = getVar pc >>= \v -> alterVar pc (+1) >> readMem v
The lazy ST doesn't actually read the STRef before readMem v is called, so it reads the altered STRef and consequently the wrong memory address. Make sure that v is determined before the STRef is altered, e.g. by fetch = getVar pc >>= \v -> v `seq` (alterVar pc (+1) >> readMem v) or fetch = do v <- getVar pc w <- readMem v alterVar pc succ return w