diff options
-rw-r--r-- | src/library.js | 19 | ||||
-rw-r--r-- | src/library_browser.js | 54 | ||||
-rw-r--r-- | src/library_openal.js | 100 | ||||
-rw-r--r-- | src/library_sdl.js | 38 | ||||
-rw-r--r-- | src/parseTools.js | 4 | ||||
-rw-r--r-- | src/shell.html | 8 | ||||
-rw-r--r-- | system/include/libc/ctype.h | 44 | ||||
-rwxr-xr-x | tests/runner.py | 72 | ||||
-rw-r--r-- | tools/js-optimizer.js | 11 |
9 files changed, 220 insertions, 130 deletions
diff --git a/src/library.js b/src/library.js index d5f11cf3..aebad63b 100644 --- a/src/library.js +++ b/src/library.js @@ -382,7 +382,7 @@ LibraryManager.library = { // do preloading for the Image/Audio part, as if the typed array were the // result of an XHR that you did manually. createPreloadedFile: function(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile) { - Browser.ensureObjects(); + Browser.init(); var fullname = FS.joinPath([parent, name], true); function processData(byteArray) { function finish(byteArray) { @@ -2642,7 +2642,7 @@ LibraryManager.library = { // format: A pointer to the format string. // varargs: A pointer to the start of the arguments list. // Returns the resulting string string as a character array. - _formatString__deps: ['strlen'], + _formatString__deps: ['strlen', '_reallyNegative'], _formatString: function(format, varargs) { var textIndex = format; var argIndex = 0; @@ -2897,7 +2897,6 @@ LibraryManager.library = { // Float. var currArg = getNextArg('double'); var argText; - if (isNaN(currArg)) { argText = 'nan'; flagZeroPad = false; @@ -2932,6 +2931,9 @@ LibraryManager.library = { } } else if (next == {{{ charCode('f') }}} || next == {{{ charCode('F') }}}) { argText = currArg.toFixed(effectivePrecision); + if (currArg === 0 && __reallyNegative(currArg)) { + argText = '-' + argText; + } } var parts = argText.split('e'); @@ -4950,7 +4952,7 @@ LibraryManager.library = { var ret = 0; while (x) { if (x&1) ret++; - x >>= 1; + x >>>= 1; } return ret; }, @@ -5478,9 +5480,14 @@ LibraryManager.library = { return isNaN(x); }, __isnan: 'isnan', + + _reallyNegative: function(x) { + return x < 0 || (x === 0 && (1/x) === -Infinity); + }, + + copysign__deps: ['_reallyNegative'], copysign: function(a, b) { - if (a < 0 === b < 0) return a; - return -a; + return __reallyNegative(a) === __reallyNegative(b) ? a : -a; }, copysignf: 'copysign', __signbit__deps: ['copysign'], diff --git a/src/library_browser.js b/src/library_browser.js index bdd94bac..e61f84b5 100644 --- a/src/library_browser.js +++ b/src/library_browser.js @@ -45,9 +45,9 @@ mergeInto(LibraryManager.library, { moduleContextCreatedCallbacks: [], workers: [], - ensureObjects: function() { - if (Browser.ensured) return; - Browser.ensured = true; + init: function() { + if (Browser.initted) return; + Browser.initted = true; try { new Blob(); Browser.hasBlobConstructor = true; @@ -193,6 +193,36 @@ mergeInto(LibraryManager.library, { } }; Module['preloadPlugins'].push(audioPlugin); + + // Canvas event setup + + var canvas = Module['canvas']; + canvas.requestPointerLock = canvas['requestPointerLock'] || + canvas['mozRequestPointerLock'] || + canvas['webkitRequestPointerLock']; + canvas.exitPointerLock = document['exitPointerLock'] || + document['mozExitPointerLock'] || + document['webkitExitPointerLock']; + canvas.exitPointerLock = canvas.exitPointerLock.bind(document); + + function pointerLockChange() { + Browser.pointerLock = document['pointerLockElement'] === canvas || + document['mozPointerLockElement'] === canvas || + document['webkitPointerLockElement'] === canvas; + } + + document.addEventListener('pointerlockchange', pointerLockChange, false); + document.addEventListener('mozpointerlockchange', pointerLockChange, false); + document.addEventListener('webkitpointerlockchange', pointerLockChange, false); + + if (Module['elementPointerLock']) { + canvas.addEventListener("click", function(ev) { + if (!Browser.pointerLock && canvas.requestPointerLock) { + canvas.requestPointerLock(); + ev.preventDefault(); + } + }, false); + } }, createContext: function(canvas, useWebGL, setInModule) { @@ -271,6 +301,7 @@ mergeInto(LibraryManager.library, { Module.ctx = ctx; Module.useWebGL = useWebGL; Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() }); + Browser.init(); } return ctx; }, @@ -292,13 +323,6 @@ mergeInto(LibraryManager.library, { if ((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] || document['mozFullScreenElement'] || document['mozFullscreenElement'] || document['fullScreenElement'] || document['fullscreenElement']) === canvas) { - canvas.requestPointerLock = canvas['requestPointerLock'] || - canvas['mozRequestPointerLock'] || - canvas['webkitRequestPointerLock']; - canvas.exitPointerLock = document['exitPointerLock'] || - document['mozExitPointerLock'] || - document['webkitExitPointerLock']; - canvas.exitPointerLock = canvas.exitPointerLock.bind(document); canvas.cancelFullScreen = document['cancelFullScreen'] || document['mozCancelFullScreen'] || document['webkitCancelFullScreen']; @@ -312,21 +336,11 @@ mergeInto(LibraryManager.library, { if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen); } - function pointerLockChange() { - Browser.pointerLock = document['pointerLockElement'] === canvas || - document['mozPointerLockElement'] === canvas || - document['webkitPointerLockElement'] === canvas; - } - if (!this.fullScreenHandlersInstalled) { this.fullScreenHandlersInstalled = true; document.addEventListener('fullscreenchange', fullScreenChange, false); document.addEventListener('mozfullscreenchange', fullScreenChange, false); document.addEventListener('webkitfullscreenchange', fullScreenChange, false); - - document.addEventListener('pointerlockchange', pointerLockChange, false); - document.addEventListener('mozpointerlockchange', pointerLockChange, false); - document.addEventListener('webkitpointerlockchange', pointerLockChange, false); } canvas.requestFullScreen = canvas['requestFullScreen'] || diff --git a/src/library_openal.js b/src/library_openal.js index 6bd0f6b0..b785a89f 100644 --- a/src/library_openal.js +++ b/src/library_openal.js @@ -57,6 +57,7 @@ var LibraryOpenAL = { } if (ctx) { + ctx.listener.panningModel = "equalpower"; AL.contexts.push({ctx: ctx, err: 0, src: [], buf: []}); return AL.contexts.length; } else { @@ -72,6 +73,12 @@ var LibraryOpenAL = { } }, + alcGetError__deps: ['alGetError'], + alcGetError: function(device) { + // We have only one audio device, so just return alGetError. + return _alGetError(); + }, + alDeleteSources: function(count, sources) { if (!AL.currentContext) { @@ -81,7 +88,7 @@ var LibraryOpenAL = { return; } for (var i = 0; i < count; ++i) { - var sourceIdx = {{{ makeGetValue('sources', 'i', 'i32') }}} - 1; + var sourceIdx = {{{ makeGetValue('sources', 'i*4', 'i32') }}} - 1; delete AL.currentContext.src[sourceIdx]; } }, @@ -96,14 +103,8 @@ var LibraryOpenAL = { for (var i = 0; i < count; ++i) { var gain = AL.currentContext.ctx.createGain(); var panner = AL.currentContext.ctx.createPanner(); - if (typeof(webkitAudioContext) == 'function') { - gain.connect(panner); - panner.connect(AL.currentContext.ctx.destination); - } else { - // Work around a Firefox bug (bug 849916) - gain.connect(AL.currentContext.ctx.destination); - } - gain.gain.value = 1; // work around a Firefox bug (bug 850970) + gain.connect(panner); + panner.connect(AL.currentContext.ctx.destination); AL.currentContext.src.push({ loop: false, buffer: null, @@ -113,7 +114,7 @@ var LibraryOpenAL = { playTime: -1, pausedTime: 0 }); - {{{ makeSetValue('sources', 'i', 'AL.currentContext.src.length', 'i32') }}}; + {{{ makeSetValue('sources', 'i*4', 'AL.currentContext.src.length', 'i32') }}}; } }, @@ -196,15 +197,15 @@ var LibraryOpenAL = { case 0x1004 /* AL_POSITION */: AL.currentContext.src[source - 1].panner.setPosition( {{{ makeGetValue('value', '0', 'float') }}}, - {{{ makeGetValue('value', '1', 'float') }}}, - {{{ makeGetValue('value', '2', 'float') }}} + {{{ makeGetValue('value', '4', 'float') }}}, + {{{ makeGetValue('value', '8', 'float') }}} ); break; case 0x1006 /* AL_VELOCITY */: AL.currentContext.src[source - 1].panner.setVelocity( {{{ makeGetValue('value', '0', 'float') }}}, - {{{ makeGetValue('value', '1', 'float') }}}, - {{{ makeGetValue('value', '2', 'float') }}} + {{{ makeGetValue('value', '4', 'float') }}}, + {{{ makeGetValue('value', '8', 'float') }}} ); break; default: @@ -235,7 +236,7 @@ var LibraryOpenAL = { return; } for (var i = 0; i < count; ++i) { - var buffer = {{{ makeGetValue('buffers', 'i', 'i32') }}}; + var buffer = {{{ makeGetValue('buffers', 'i*4', 'i32') }}}; if (buffer > AL.currentContext.buf.length) { #if OPENAL_DEBUG console.error("alSourceQueueBuffers called with an invalid buffer"); @@ -270,7 +271,7 @@ var LibraryOpenAL = { var buffer = AL.currentContext.src[source - 1].buffer; for (var j = 0; j < AL.currentContext.buf.length; ++j) { if (buffer == AL.currentContext.buf[j].buf) { - {{{ makeSetValue('buffers', 'i', 'j+1', 'i32') }}}; + {{{ makeSetValue('buffers', 'i*4', 'j+1', 'i32') }}}; AL.currentContext.src[source - 1].buffer = null; break; } @@ -287,7 +288,7 @@ var LibraryOpenAL = { return; } for (var i = 0; i < count; ++i) { - var bufferIdx = {{{ makeGetValue('buffers', 'i', 'i32') }}} - 1; + var bufferIdx = {{{ makeGetValue('buffers', 'i*4', 'i32') }}} - 1; var buffer = AL.currentContext.buf[bufferIdx].buf; for (var j = 0; j < AL.currentContext.src.length; ++j) { if (buffer == AL.currentContext.src[j].buffer) { @@ -308,7 +309,7 @@ var LibraryOpenAL = { } for (var i = 0; i < count; ++i) { AL.currentContext.buf.push({buf: null}); - {{{ makeSetValue('buffers', 'i', 'AL.currentContext.buf.length', 'i32') }}}; + {{{ makeSetValue('buffers', 'i*4', 'AL.currentContext.buf.length', 'i32') }}}; } }, @@ -385,22 +386,25 @@ var LibraryOpenAL = { return; } var offset = 0; - if ("src" in AL.currentContext.src[source - 1]) { - // If the source is already playing, we need to resume from beginning. - // We do that by stopping the current source and replaying it. - _alSourceStop(source); - } else if (AL.currentContext.src[source - 1].paused) { - // So now we have to resume playback, remember the offset here. - offset = AL.currentContext.src[source - 1].pausedTime - - AL.currentContext.src[source - 1].playTime; + if ("src" in AL.currentContext.src[source - 1] && + AL.currentContext.src[source - 1]["src"].buffer == + AL.currentContext.src[source - 1].buffer) { + if (AL.currentContext.src[source - 1].paused) { + // So now we have to resume playback, remember the offset here. + offset = AL.currentContext.src[source - 1].pausedTime - + AL.currentContext.src[source - 1].playTime; + } else { + // If the source is already playing, we need to resume from beginning. + // We do that by stopping the current source and replaying it. + _alSourceStop(source); + } } var src = AL.currentContext.ctx.createBufferSource(); src.loop = AL.currentContext.src[source - 1].loop; src.buffer = AL.currentContext.src[source - 1].buffer; src.connect(AL.currentContext.src[source - 1].gain); src.start(0, offset); - // Work around Firefox bug 851338 - AL.currentContext.src[source - 1].playTime = AL.currentContext.ctx.currentTime || 0; + AL.currentContext.src[source - 1].playTime = AL.currentContext.ctx.currentTime; AL.currentContext.src[source - 1].paused = false; AL.currentContext.src[source - 1]['src'] = src; }, @@ -440,8 +444,7 @@ var LibraryOpenAL = { if ("src" in AL.currentContext.src[source - 1] && !AL.currentContext.src[source - 1].paused) { AL.currentContext.src[source - 1].paused = true; - // Work around Firefox bug 851338 - AL.currentContext.src[source - 1].pausedTime = AL.currentContext.ctx.currentTime || 0; + AL.currentContext.src[source - 1].pausedTime = AL.currentContext.ctx.currentTime; AL.currentContext.src[source - 1]["src"].stop(0); delete AL.currentContext.src[source - 1].src; } @@ -513,9 +516,43 @@ var LibraryOpenAL = { }, alListenerfv: function(param, values) { + if (!AL.currentContext) { +#if OPENAL_DEBUG + console.error("alListenerfv called without a valid context"); +#endif + return; + } + switch (param) { + case 0x1004 /* AL_POSITION */: + AL.currentContext.ctx.listener.setPosition( + {{{ makeGetValue('values', '0', 'float') }}}, + {{{ makeGetValue('values', '4', 'float') }}}, + {{{ makeGetValue('values', '8', 'float') }}} + ); + break; + case 0x1006 /* AL_VELOCITY */: + AL.currentContext.ctx.listener.setVelocity( + {{{ makeGetValue('values', '0', 'float') }}}, + {{{ makeGetValue('values', '4', 'float') }}}, + {{{ makeGetValue('values', '8', 'float') }}} + ); + break; + case 0x100F /* AL_ORIENTATION */: + AL.currentContext.ctx.listener.setOrientation( + {{{ makeGetValue('values', '0', 'float') }}}, + {{{ makeGetValue('values', '4', 'float') }}}, + {{{ makeGetValue('values', '8', 'float') }}}, + {{{ makeGetValue('values', '12', 'float') }}}, + {{{ makeGetValue('values', '16', 'float') }}}, + {{{ makeGetValue('values', '20', 'float') }}} + ); + break; + default: #if OPENAL_DEBUG - console.log("alListenerfv is not supported yet"); + console.log("alListenerfv with param " + param + " not implemented yet"); #endif + break; + } }, alIsExtensionPresent: function(extName) { @@ -533,7 +570,6 @@ var LibraryOpenAL = { alcGetProcAddress: function(device, fname) { return 0; }, - }; autoAddDeps(LibraryOpenAL, '$AL'); diff --git a/src/library_sdl.js b/src/library_sdl.js index 77305609..42207f23 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -443,23 +443,6 @@ var LibrarySDL = { return false; }, - offsetsTemp: { left: 0, top: 0 }, // temporary object to avoid generating garbage in offsets(). assumes the object is not captured - - offsets: function(element) { - var left = 0; - var top = 0; - - do { - left += element.offsetLeft; - top += element.offsetTop; - } while (element = element.offsetParent) - - var ret = SDL.offsetsTemp; - ret.left = left; - ret.top = top; - return ret; - }, - makeCEvent: function(event, ptr) { if (typeof event === 'number') { // This is a pointer to a native C event that was SDL_PushEvent'ed @@ -541,9 +524,18 @@ var LibrarySDL = { } else { // Otherwise, calculate the movement based on the changes // in the coordinates. - var offsets = SDL.offsets(Module["canvas"]); - var x = event.pageX - offsets.left; - var y = event.pageY - offsets.top; + var rect = Module["canvas"].getBoundingClientRect(); + var x = event.pageX - (window.scrollX + rect.left); + var y = event.pageY - (window.scrollY + rect.top); + + // the canvas might be CSS-scaled compared to its backbuffer; + // SDL-using content will want mouse coordinates in terms + // of backbuffer units. + var cw = Module["canvas"].width; + var ch = Module["canvas"].height; + x = x * (cw / rect.width); + y = y * (ch / rect.height); + var movementX = x - SDL.mouseX; var movementY = y - SDL.mouseY; } @@ -930,11 +922,11 @@ var LibrarySDL = { SDL_WarpMouse: function(x, y) { return; // TODO: implement this in a non-buggy way. Need to keep relative mouse movements correct after calling this - var offsets = SDL.offsets(Module["canvas"]); + var rect = Module["canvas"].getBoundingClientRect(); SDL.events.push({ type: 'mousemove', - pageX: x + offsets.left, - pageY: y + offsets.top + pageX: x + (window.scrollX + rect.left), + pageY: y + (window.scrollY + rect.top) }); }, diff --git a/src/parseTools.js b/src/parseTools.js index 2664baed..9fddacbb 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -818,7 +818,9 @@ function parseNumerical(value, type) { return '0'; } if (isNumber(value)) { - return parseFloat(value).toString(); // will change e.g. 5.000000e+01 to 50 + var ret = parseFloat(value); // will change e.g. 5.000000e+01 to 50 + if (type in Runtime.FLOAT_TYPES && value[0] == '-' && ret === 0) return '-0'; // fix negative 0, toString makes it 0 + return ret.toString(); } else { return value; } diff --git a/src/shell.html b/src/shell.html index 8743d403..f7eb9e1f 100644 --- a/src/shell.html +++ b/src/shell.html @@ -6,9 +6,11 @@ <title>Emscripten-Generated Code</title> <style> .emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; } - canvas.emscripten { border: 1px solid black; } textarea.emscripten { font-family: monospace; width: 80%; } div.emscripten { text-align: center; } + div.emscripten_border { border: 1px solid black; } + /* the canvas *must not* have any border or padding, or mouse coords will be wrong */ + canvas.emscripten { border: 0px none; } </style> </head> <body> @@ -17,7 +19,9 @@ <div class="emscripten"> <progress value="0" max="100" id="progress" hidden=1></progress> </div> - <canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas> + <div class="emscripten_border"> + <canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas> + </div> <hr/> <div class="emscripten"> <input type="checkbox" id="resize">Resize canvas diff --git a/system/include/libc/ctype.h b/system/include/libc/ctype.h index 383a8db1..666c4d7c 100644 --- a/system/include/libc/ctype.h +++ b/system/include/libc/ctype.h @@ -117,20 +117,6 @@ extern __IMPORT _CONST char _ctype_[]; _END_STD_C - - - - - - - - - - - - - - /* * Copyright (c) 2000, 2005, 2008 Apple Inc. All rights reserved. * @@ -196,25 +182,15 @@ _END_STD_C * @(#)ctype.h 8.4 (Berkeley) 1/21/94 */ -#define _CTYPE_A 0x00000100L /* Alpha */ -#define _CTYPE_C 0x00000200L /* Control */ -#define _CTYPE_D 0x00000400L /* Digit */ -#define _CTYPE_G 0x00000800L /* Graph */ -#define _CTYPE_L 0x00001000L /* Lower */ -#define _CTYPE_P 0x00002000L /* Punct */ -#define _CTYPE_S 0x00004000L /* Space */ -#define _CTYPE_U 0x00008000L /* Upper */ -#define _CTYPE_X 0x00010000L /* X digit */ -#define _CTYPE_B 0x00020000L /* Blank */ -#define _CTYPE_R 0x00040000L /* Print */ -#define _CTYPE_I 0x00080000L /* Ideogram */ -#define _CTYPE_T 0x00100000L /* Special */ -#define _CTYPE_Q 0x00200000L /* Phonogram */ -#define _CTYPE_SW0 0x20000000L /* 0 width character */ -#define _CTYPE_SW1 0x40000000L /* 1 width character */ -#define _CTYPE_SW2 0x80000000L /* 2 width character */ -#define _CTYPE_SW3 0xc0000000L /* 3 width character */ -#define _CTYPE_SWM 0xe0000000L /* Mask for screen width data */ -#define _CTYPE_SWS 30 /* Bits to shift to get width */ +#define _CTYPE_A 0x00000400 /* Alpha */ +#define _CTYPE_C 0x00000002 /* Control */ +#define _CTYPE_D 0x00000800 /* Digit */ +#define _CTYPE_L 0x00000200 /* Lower */ +#define _CTYPE_P 0x00000004 /* Punct */ +#define _CTYPE_S 0x00002000 /* Space */ +#define _CTYPE_U 0x00000100 /* Upper */ +#define _CTYPE_X 0x00001000 /* X digit */ +#define _CTYPE_B 0x00000001 /* Blank */ +#define _CTYPE_R 0x00004000 /* Print */ #endif /* _CTYPE_H_ */ diff --git a/tests/runner.py b/tests/runner.py index 529dcc48..168567d2 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -1234,6 +1234,59 @@ m_divisor is 1091269979 ''' self.do_run(src, ',0,,2,C!,0,C!,0,,65535,C!,0,') + def test_negative_zero(self): + src = r''' + #include <stdio.h> + #include <math.h> + + int main() { + #define TEST(x, y) \ + printf("%.2f, %.2f ==> %.2f\n", x, y, copysign(x, y)); + TEST( 5.0f, 5.0f); + TEST( 5.0f, -5.0f); + TEST(-5.0f, 5.0f); + TEST(-5.0f, -5.0f); + TEST( 5.0f, 4.0f); + TEST( 5.0f, -4.0f); + TEST(-5.0f, 4.0f); + TEST(-5.0f, -4.0f); + TEST( 0.0f, 5.0f); + TEST( 0.0f, -5.0f); + TEST(-0.0f, 5.0f); + TEST(-0.0f, -5.0f); + TEST( 5.0f, 0.0f); + TEST( 5.0f, -0.0f); + TEST(-5.0f, 0.0f); + TEST(-5.0f, -0.0f); + TEST( 0.0f, 0.0f); + TEST( 0.0f, -0.0f); + TEST(-0.0f, 0.0f); + TEST(-0.0f, -0.0f); + return 0; + } + ''' + self.do_run(src, '''5.00, 5.00 ==> 5.00 +5.00, -5.00 ==> -5.00 +-5.00, 5.00 ==> 5.00 +-5.00, -5.00 ==> -5.00 +5.00, 4.00 ==> 5.00 +5.00, -4.00 ==> -5.00 +-5.00, 4.00 ==> 5.00 +-5.00, -4.00 ==> -5.00 +0.00, 5.00 ==> 0.00 +0.00, -5.00 ==> -0.00 +-0.00, 5.00 ==> 0.00 +-0.00, -5.00 ==> -0.00 +5.00, 0.00 ==> 5.00 +5.00, -0.00 ==> -5.00 +-5.00, 0.00 ==> 5.00 +-5.00, -0.00 ==> -5.00 +0.00, 0.00 ==> 0.00 +0.00, -0.00 ==> -0.00 +-0.00, 0.00 ==> 0.00 +-0.00, -0.00 ==> -0.00 +''') + def test_llvm_intrinsics(self): if self.emcc_args == None: return self.skip('needs ta2') @@ -1269,6 +1322,7 @@ m_divisor is 1091269979 printf("%d,%d\n", (int)llvm_ctlz_i64(((int64_t)1) << 40), llvm_ctlz_i32(1<<10)); printf("%d,%d\n", (int)llvm_cttz_i64(((int64_t)1) << 40), llvm_cttz_i32(1<<10)); printf("%d,%d\n", (int)llvm_ctpop_i64((0x3101ULL << 32) | 1), llvm_ctpop_i32(0x3101)); + printf("%d\n", (int)llvm_ctpop_i32(-594093059)); printf("%d\n", llvm_expect_i32(x % 27, 3)); @@ -1286,6 +1340,7 @@ c5,de,15,8a 23,21 40,10 5,4 +22 13 72057594037927936 ''') @@ -5095,7 +5150,7 @@ def process(filename): 0 0 0 - 0 + -0 1 1 1 @@ -10003,6 +10058,7 @@ f.close() (path_from_root('tools', 'test-js-optimizer-asm-last.js'), open(path_from_root('tools', 'test-js-optimizer-asm-last-output.js')).read(), ['asm', 'last']), ]: + print input output = Popen(listify(NODE_JS) + [path_from_root('tools', 'js-optimizer.js'), input] + passes, stdin=PIPE, stdout=PIPE).communicate()[0] self.assertIdentical(expected, output.replace('\r\n', '\n').replace('\n\n', '\n')) @@ -10019,13 +10075,19 @@ f.close() try: os.environ['EMCC_DEBUG'] = '1' for asm, linkable, chunks, js_chunks in [ - (0, 0, 3, 2), (0, 1, 4, 4), - (1, 0, 3, 2), (1, 1, 4, 5) + (0, 0, 3, 2), (0, 1, 3, 4), + (1, 0, 3, 2), (1, 1, 3, 4) ]: print asm, linkable, chunks, js_chunks output, err = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_libcxx.cpp'), '-O1', '-s', 'LINKABLE=%d' % linkable, '-s', 'ASM_JS=%d' % asm, '-s', 'UNRESOLVED_AS_DEAD=1'], stdout=PIPE, stderr=PIPE).communicate() - assert 'phase 2 working on %d chunks' %chunks in err, err - assert 'splitting up js optimization into %d chunks' % js_chunks in err, err + ok = False + for c in range(chunks, chunks+2): + ok = ok or ('phase 2 working on %d chunks' % c in err) + assert ok, err + ok = False + for c in range(js_chunks, js_chunks+2): + ok = ok or ('splitting up js optimization into %d chunks' % c in err) + assert ok, err finally: del os.environ['EMCC_DEBUG'] diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 48ab5a1f..5ede0ce8 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -2287,19 +2287,16 @@ function minifyGlobals(ast) { function prepDotZero(ast) { traverse(ast, function(node, type) { if (type == 'unary-prefix' && node[1] == '+') { - if (node[2][0] == 'num') { + if (node[2][0] == 'num' || + (node[2][0] == 'unary-prefix' && node[2][1] == '-' && node[2][2][0] == 'num')) { return ['call', ['name', 'DOT$ZERO'], [node[2]]]; - } else if (node[2][0] == 'unary-prefix' && node[2][1] == '-' && node[2][2][0] == 'num') { - node[2][2][1] = -node[2][2][1]; - return ['call', ['name', 'DOT$ZERO'], [node[2][2]]]; } } }); } function fixDotZero(js) { - return js.replace(/DOT\$ZERO\(((0x)?[-+]?[0-9a-f]*\.?[0-9]+([eE][-+]?[0-9]+)?)\)/g, function(m, num) { - if (num.substr(0, 2) == '0x') { - if (num[2] == '-') num = '-0x' + num.substr(3); // uglify generates 0x-8000 for some reason + return js.replace(/DOT\$ZERO\(([-+]?(0x)?[0-9a-f]*\.?[0-9]+([eE][-+]?[0-9]+)?)\)/g, function(m, num) { + if (num.substr(0, 2) == '0x' || num.substr(0, 3) == '-0x') { return eval(num) + '.0'; } if (num.indexOf('.') >= 0) return num; |