HTML and CSS Reference
In-Depth Information
Math.imul is an interesting case, actually. Previous and current JavaScript specifications, ECMAScript 3 and
ECMAScript 5, don't have an expression that directly corresponds to C's 32-bit integer multiplication. The function in
Listing 18-9 implements C-like multiplication in JavaScript.
Listing 18-9. 32-bit Integer Multiplication Fallback
// courtesy of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/
Math/imul
function imul(a, b) {
var ah = (a >>> 16) & 0xffff;
var al = a & 0xffff;
var bh = (b >>> 16) & 0xffff;
var bl = b & 0xffff;
// the shift by 0 fixes the sign on the high part
// the final |0 converts the unsigned value into a signed value
return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0)|0);
}
Math.imul will be introduced in ECMAScript 6 (and is already available in Firefox and Chrome!) so that asm.
js can efficiently translate it into a native multiply instruction. In addition, there are upcoming JavaScript proposals
to expose other native instruction capabilities such as SIMD vector processing and 32-bit floating arithmetic. (All
numbers in JavaScript are IEEE 64-bit floats.) Beyond instruction-level performance, as of ECMAScript 5, JavaScript
has no access to shared-memory threads, though WebWorkers provide support for message-passing concurrency.
In short, the Web is a bit less capable than native platforms, but it's certainly powerful enough to run a wide range
of games, especially since the gap between desktop PCs and mobile phones is much larger than the gap between
native code and asm.js. Moreover, we can expect improvements to performance over time. Emscripten, being a new
compiler, still has room for improvement in its code generation. At the time of this writing, Alon Zakai is rewriting
the compiler as a proper LLVM backend rather than a set of programs that parse LLVM IR directly. Emscripten as an
LLVM backend is expected to enable further LLVM optimizations.
Concurrently with improvements to the Emscripten compiler itself, browsers are optimizing for asm.js.
In November 2013, Google and Opera announced that their browsers have faster asm.js code generation
( http://www.unrealengine.com/en/news/epic_citadel_cleared_for_chrome_and_opera_browsers/ ) . I predict
that the performance of asm.js will continue to improve. It's unrealistic to assume that the restricted, secure asm.js
will equal native code performance, but if it reaches 80% to 90% of the performance of native code, then asm.js will be
sufficiently fast that we can treat it like any other first-class target.
Debugging
Sadly, if you're used to IDEs with wonderful debuggers like Visual Studio or even simpler tools like WinDbg or gdb,
Emscripten is a step backwards. There are no Emscripten debuggers, though you can invoke emcc with the -g flag and
use your web browser's JavaScript debugger. With -g , emcc tries hard to preserve function and variable names, so it's
not terribly painful to figure out what's happening at runtime from within a JavaScript debugger. Unfortunately, all
current JavaScript debuggers are painfully slow given the large JavaScript files that Emscripten produces.
Thus, most of the time, it's easiest to fall back on traditional printf debugging.
However, there is one trick that comes in handy. Much like Win32's DebugBreak() function or x86's __asm int 3 ,
in Emscripten, you can cause the debugger to break on a line of code with asm(“debugger”); . In Emscripten, asm()
allows insertion of arbitrary JavaScript into the generated code, and the JavaScript debugger statement causes the
debugger to kick in when that code is reached. I recommend inserting asm(“debugger”); into your assertion and
fatal error functions, as shown in Listing 18-10.
 
Search WWH ::




Custom Search