If the emulator detects a memory write to one of the already recompiled blocks it can invalidate the results of the previous translation. If branch occurs to that block or to a new area in memory where new instructions were emitted, it can translate that part and cache the results. With a JIT binary translator this is no big deal. However, AOT translation of self-modifying code would not work.