  Scores of compilers produce JavaScript, enabling programmers to use many
languages on the Web, reuse existing code, and even use Web IDEs.
Unfortunately, most compilers inherit the browser's compromised execution
model, so long-running programs freeze the browser tab, infinite loops crash
IDEs, and so on. The few compilers that avoid these problems suffer poor
performance and are difficult to engineer.
  This paper presents Stopify, a source-to-source compiler that extends
JavaScript with debugging abstractions and blocking operations, and easily
integrates with existing compilers. We apply Stopify to 10 programming
languages and develop a Web IDE that supports stopping, single-stepping,
breakpointing, and long-running computations. For nine languages, Stopify
requires no or trivial compiler changes. For eight, our IDE is the first that
provides these features. Two of our subject languages have compilers with
similar features. Stopify's performance is competitive with these compilers and
it makes them dramatically simpler.
  Stopify's abstractions rely on first-class continuations, which it provides
by compiling JavaScript to JavaScript. We also identify sub-languages of
JavaScript that compilers implicitly use, and exploit these to improve
performance. Finally, Stopify needs to repeatedly interrupt and resume program
execution. We use a sampling-based technique to estimate program speed that
outperforms other systems.
