Very neat, but it's a shame that interpretation is used. With the speed of current Javascript implementations, dynamic recompilation (block-based recompilation to JS functions, specifically) is insanely fast.
A while back, http://6502asm.com/ popped up with a web-based 6502 (chip used in the NES, Apple ][, and many others) emulator. I stumbled upon it and in a matter of hours, I patched it to become the first (to my knowledge) dynarec emulator in JS. You can see a live version here: http://ironbabel.googlepages.com/6502.html
This same technology could easily be applied to JSNES for considerable speedups.
No, sorry. I haven't done much in the way of optimizations with JS, but I'll explain how this is optimized. This is actually a simplified version of the structure used in IronBabel (emulator platform of mine, http://sourceforge.net/projects/ironbabel/ )
You have a hash table mapping an address to a block length, block function, and a hash/checksum. Your execution loop looks for the program counter in the hash table. If it exists, you take <block length> bytes from the program counter, hash/checksum it, and compare it against the hash table entry.
If the cache entry misses, you need to recompile the block. Starting from the program counter, read instructions and rather than executing the operation (as in an interpreter), you append the operation's code to a string. When you hit a branch and output the code, you break the loop. You now have the code of the block.
Wrap it in a function, eval it, and put the function in the cache.
There are a number of optimizations that can be done (see IronBabel for specifics), but the easiest is to group blocks into a state machine. Simply push all of the code into a big while(true) { switch(PC) { case 0xDEADBEEF: ... }} and break out if you hit a block that isn't in the state machine.
Yes, but it's also correct to say that he wrote a compiler.
He is taking the assembly code you type in and translating it to machine code, then he's translating the machine code to JavaScript source, then executing that source directly.
Translating a program from one language to another is compilation, by definition. While the first translation step could also be considered assembling, the second cannot.
A while back, http://6502asm.com/ popped up with a web-based 6502 (chip used in the NES, Apple ][, and many others) emulator. I stumbled upon it and in a matter of hours, I patched it to become the first (to my knowledge) dynarec emulator in JS. You can see a live version here: http://ironbabel.googlepages.com/6502.html
This same technology could easily be applied to JSNES for considerable speedups.