diff --git a/emcc b/emcc index 621cb340a7e87..e02854bdb231f 100755 --- a/emcc +++ b/emcc @@ -1973,6 +1973,11 @@ try: if debug_level >= 4: generate_source_map(target) shutil.move(final, js_target) + # TODO: use an async blob, which would allow code rewriting on the client: + # var blob = new Blob([codeString]); + # var script = document.createElement('script'); + # script.src = URL.createObjectURL(blob); + # document.body.appendChild(script); script_tag = '''''' % base_js_target html.write(shell.replace('{{{ SCRIPT }}}', script_tag)) else: diff --git a/src/jsifier.js b/src/jsifier.js index 58dc46532e1f8..d533e36b76058 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -18,7 +18,7 @@ var INDENTATION = ' '; var functionStubSigs = {}; // JSifier -function JSify(data, functionsOnly, givenFunctions) { +function JSify(data, functionsOnly) { //B.start('jsifier'); var mainPass = !functionsOnly; @@ -109,7 +109,7 @@ function JSify(data, functionsOnly, givenFunctions) { dprint('unparsedFunctions','====================\n// Processing function batch of ' + currBaseLineNums.length + ' functions, ' + currFuncLines.length + ' lines, functions left: ' + data.unparsedFunctions.length); if (DEBUG_MEMORY) MemoryDebugger.tick('pre-func'); - JSify(analyzer(intertyper(currFuncLines, true, currBaseLineNums), true), true, Functions); + JSify(analyzer(intertyper(currFuncLines, true, currBaseLineNums), true), true); if (DEBUG_MEMORY) MemoryDebugger.tick('post-func'); } currFuncLines = currBaseLineNums = null; // Do not hold on to anything from inside that loop (JS function scoping..) @@ -1796,7 +1796,7 @@ function JSify(data, functionsOnly, givenFunctions) { } }); } - JSify(globalsData, true, Functions); + JSify(globalsData, true); globalsData = null; data.unparsedGlobalss = null; diff --git a/src/library_browser.js b/src/library_browser.js index b368c6ac8ba1d..e0f53052d1639 100644 --- a/src/library_browser.js +++ b/src/library_browser.js @@ -478,19 +478,30 @@ mergeInto(LibraryManager.library, { // in the coordinates. var rect = Module["canvas"].getBoundingClientRect(); var x, y; + + // Neither .scrollX or .pageXOffset are defined in a spec, but + // we prefer .scrollX because it is currently in a spec draft. + // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/) + var scrollX = ((typeof window.scrollX !== 'undefined') ? window.scrollX : window.pageXOffset); + var scrollY = ((typeof window.scrollY !== 'undefined') ? window.scrollY : window.pageYOffset); +#if ASSERTIONS + // If this assert lands, it's likely because the browser doesn't support scrollX or pageXOffset + // and we have no viable fallback. + assert((typeof scrollX !== 'undefined') && (typeof scrollY !== 'undefined'), 'Unable to retrieve scroll position, mouse positions likely broken.'); +#endif if (event.type == 'touchstart' || event.type == 'touchend' || event.type == 'touchmove') { var t = event.touches.item(0); if (t) { - x = t.pageX - (window.scrollX + rect.left); - y = t.pageY - (window.scrollY + rect.top); + x = t.pageX - (scrollX + rect.left); + y = t.pageY - (scrollY + rect.top); } else { return; } } else { - x = event.pageX - (window.scrollX + rect.left); - y = event.pageY - (window.scrollY + rect.top); + x = event.pageX - (scrollX + rect.left); + y = event.pageY - (scrollY + rect.top); } // the canvas might be CSS-scaled compared to its backbuffer; diff --git a/src/library_sdl.js b/src/library_sdl.js index 1c1e8107cb819..fc38dd1ca48ca 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1059,11 +1059,35 @@ var LibrarySDL = { var src = buffer >> 2; var dst = 0; var isScreen = surf == SDL.screen; - var data32 = new Uint32Array(data.buffer); - var num = data32.length; - while (dst < num) { - // HEAP32[src++] is an optimization. Instead, we could do {{{ makeGetValue('buffer', 'dst', 'i32') }}}; - data32[dst++] = HEAP32[src++] | (isScreen ? 0xff000000 : 0); + var num; + if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { + // IE10/IE11: ImageData objects are backed by the deprecated CanvasPixelArray, + // not UInt8ClampedArray. These don't have buffers, so we need to revert + // to copying a byte at a time. We do the undefined check because modern + // browsers do not define CanvasPixelArray anymore. + num = data.length; + while (dst < num) { + var val = HEAP32[src]; // This is optimized. Instead, we could do {{{ makeGetValue('buffer', 'dst', 'i32') }}}; + data[dst ] = val & 0xff; + data[dst+1] = (val >> 8) & 0xff; + data[dst+2] = (val >> 16) & 0xff; + data[dst+3] = isScreen ? 0xff : ((val >> 24) & 0xff); + src++; + dst += 4; + } + } else { + var data32 = new Uint32Array(data.buffer); + num = data32.length; + if (isScreen) { + while (dst < num) { + // HEAP32[src++] is an optimization. Instead, we could do {{{ makeGetValue('buffer', 'dst', 'i32') }}}; + data32[dst++] = HEAP32[src++] | 0xff000000; + } + } else { + while (dst < num) { + data32[dst++] = HEAP32[src++]; + } + } } #else var num = surfData.image.data.length; diff --git a/src/relooper/Relooper.cpp b/src/relooper/Relooper.cpp index de69e0ef3520b..389d7447d963f 100644 --- a/src/relooper/Relooper.cpp +++ b/src/relooper/Relooper.cpp @@ -308,7 +308,7 @@ void MultipleShape::Render(bool InLoop) { } RenderLoopPostfix(); if (Next) Next->Render(InLoop); -}; +} // LoopShape @@ -323,7 +323,7 @@ void LoopShape::Render(bool InLoop) { Indenter::Unindent(); PrintIndented("}\n"); if (Next) Next->Render(InLoop); -}; +} // EmulatedShape @@ -350,7 +350,7 @@ void EmulatedShape::Render(bool InLoop) { Indenter::Unindent(); PrintIndented("}\n"); if (Next) Next->Render(InLoop); -}; +} // Relooper @@ -358,8 +358,8 @@ Relooper::Relooper() : Root(NULL), Emulate(false), BlockIdCounter(1), ShapeIdCou } Relooper::~Relooper() { - for (int i = 0; i < Blocks.size(); i++) delete Blocks[i]; - for (int i = 0; i < Shapes.size(); i++) delete Shapes[i]; + for (unsigned i = 0; i < Blocks.size(); i++) delete Blocks[i]; + for (unsigned i = 0; i < Shapes.size(); i++) delete Shapes[i]; } void Relooper::AddBlock(Block *New) { @@ -399,7 +399,7 @@ void Relooper::Calculate(Block *Entry) { // RAII cleanup. Without splitting, we will be forced to introduce labelled loops to allow // reaching the final block void SplitDeadEnds() { - int TotalCodeSize = 0; + unsigned TotalCodeSize = 0; for (BlockSet::iterator iter = Live.begin(); iter != Live.end(); iter++) { Block *Curr = *iter; TotalCodeSize += strlen(Curr->Code); @@ -451,7 +451,7 @@ void Relooper::Calculate(Block *Entry) { Pre.FindLive(Entry); // Add incoming branches from live blocks, ignoring dead code - for (int i = 0; i < Blocks.size(); i++) { + for (unsigned i = 0; i < Blocks.size(); i++) { Block *Curr = Blocks[i]; if (!contains(Pre.Live, Curr)) continue; for (BlockBranchMap::iterator iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) { diff --git a/src/relooper/test.txt b/src/relooper/test.txt index 540f7bdb1a9b1..9bdd40939c1ee 100644 --- a/src/relooper/test.txt +++ b/src/relooper/test.txt @@ -91,7 +91,7 @@ } default: { var $x_1 = $x_0; - label = -1; + label = 8; break L1; } } @@ -106,7 +106,7 @@ } } } - if (label == -1) { + if (label == 8) { // code 7 } // code 4 diff --git a/tests/runner.py b/tests/runner.py index 37e307e9e17e8..72e940cb92c41 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -649,6 +649,7 @@ def reftest(self, expected): def btest(self, filename, expected=None, reference=None, force_c=False, reference_slack=0, manual_reference=False, post_build=None, args=[], outfile='test.html', message='.'): # TODO: use in all other tests + if os.environ.get('EMCC_FAST_COMPILER') == '1' and 'LEGACY_GL_EMULATION=1' in args: return self.skip('no legacy gl emulation in fastcomp') # if we are provided the source and not a path, use that filename_is_src = '\n' in filename src = filename if filename_is_src else '' diff --git a/tests/sdl_canvas.c b/tests/sdl_canvas.c index 6bd659b8ff51b..cab48985b11b3 100644 --- a/tests/sdl_canvas.c +++ b/tests/sdl_canvas.c @@ -62,6 +62,8 @@ int main(int argc, char **argv) { printf("you should see two lines of text in different colors and a blue rectangle\n"); + SDL_UnlockSurface(screen); + SDL_Quit(); printf("done.\n"); diff --git a/tests/test_benchmark.py b/tests/test_benchmark.py index d84f36e469148..625340ea7fda7 100644 --- a/tests/test_benchmark.py +++ b/tests/test_benchmark.py @@ -58,7 +58,7 @@ def __init__(self, name, cc, cxx): def build(self, parent, filename, args, shared_args, emcc_args, native_args, native_exec, lib_builder): self.parent = parent - if lib_builder: native_args += lib_builder(self.name, native=True, env_init={ 'CC': self.cc, 'CXX': self.cxx }) + if lib_builder: native_args = native_args + lib_builder(self.name, native=True, env_init={ 'CC': self.cc, 'CXX': self.cxx }) if not native_exec: compiler = self.cxx if filename.endswith('cpp') else self.cc process = Popen([compiler, '-O2', '-fno-math-errno', filename, '-o', filename+'.native'] + shared_args + native_args, stdout=PIPE, stderr=parent.stderr_redirect) @@ -90,7 +90,7 @@ def __init__(self, name, engine, extra_args=[], env={}): def build(self, parent, filename, args, shared_args, emcc_args, native_args, native_exec, lib_builder): self.filename = filename - if lib_builder: emcc_args += lib_builder('js', native=False, env_init={}) + if lib_builder: emcc_args = emcc_args + lib_builder('js', native=False, env_init={}) open('hardcode.py', 'w').write(''' def process(filename): diff --git a/tests/test_browser.py b/tests/test_browser.py index 920c6f8c589d4..20b38bb500fd0 100644 --- a/tests/test_browser.py +++ b/tests/test_browser.py @@ -120,6 +120,8 @@ def test_html_source_map(self): ''' def test_emscripten_log(self): + if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('fastcomp uses asm, where call stacks are sometimes less clear') + src = os.path.join(self.get_dir(), 'src.cpp') open(src, 'w').write(self.with_report_result(open(path_from_root('tests', 'emscripten_log', 'emscripten_log.cpp')).read())) @@ -680,10 +682,7 @@ def test_sdl_stb_image_data(self): self.btest('sdl_stb_image_data.c', reference='screenshot.jpg', args=['-s', 'STB_IMAGE=1', '--preload-file', 'screenshot.not']) def test_sdl_canvas(self): - open(os.path.join(self.get_dir(), 'sdl_canvas.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_canvas.c')).read())) - - Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'sdl_canvas.c'), '-o', 'page.html', '-s', 'LEGACY_GL_EMULATION=1']).communicate() - self.run_browser('page.html', '', '/report_result?1') + self.btest('sdl_canvas.c', expected='1', args=['-s', 'LEGACY_GL_EMULATION=1']) def test_sdl_canvas_proxy(self): def post(): @@ -1111,6 +1110,8 @@ def test_sdl_audio_quickload(self): self.run_browser('page.html', '', '/report_result?1') def test_sdl_audio_beeps(self): + if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo c++ exceptions in fastcomp') + open(os.path.join(self.get_dir(), 'sdl_audio_beep.cpp'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio_beep.cpp')).read())) # use closure to check for a possible bug with closure minifying away newer Audio() attributes @@ -1194,10 +1195,7 @@ def test_openal_buffers(self): self.btest('openal_buffers.c', '0', args=['--preload-file', 'the_entertainer.wav'],) def test_glfw(self): - open(os.path.join(self.get_dir(), 'glfw.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'glfw.c')).read())) - - Popen([PYTHON, EMCC, '-O2', os.path.join(self.get_dir(), 'glfw.c'), '-o', 'page.html', '-s', 'LEGACY_GL_EMULATION=1']).communicate() - self.run_browser('page.html', '', '/report_result?1') + self.btest('glfw.c', '1', args=['-s', 'LEGACY_GL_EMULATION=1']) def test_egl(self): open(os.path.join(self.get_dir(), 'test_egl.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'test_egl.c')).read())) @@ -1436,6 +1434,8 @@ def test_sdl_resize(self): self.btest('sdl_resize.c', '1') def test_gc(self): + if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('flaky in fastcomp and also non-fastcomp -O1, timing issues') + self.btest('browser_gc.cpp', '1') def test_glshaderinfo(self): @@ -1622,11 +1622,12 @@ def test_s3tc_crunch_split(self): # load several datafiles/outputs of file packa self.btest('s3tc_crunch.c', reference='s3tc_crunch.png', reference_slack=11, args=['--pre-js', 'asset_a.js', '--pre-js', 'asset_b.js', '-s', 'LEGACY_GL_EMULATION=1']) def test_aniso(self): - if SPIDERMONKEY_ENGINE in JS_ENGINES: + if SPIDERMONKEY_ENGINE in JS_ENGINES and os.environ.get('EMCC_FAST_COMPILER') != '1': # asm.js-ification check Popen([PYTHON, EMCC, path_from_root('tests', 'aniso.c'), '-O2', '-g2', '-s', 'LEGACY_GL_EMULATION=1']).communicate() Settings.ASM_JS = 1 self.run_generated_code(SPIDERMONKEY_ENGINE, 'a.out.js') + print 'passed asm test' shutil.copyfile(path_from_root('tests', 'water.dds'), 'water.dds') self.btest('aniso.c', reference='aniso.png', reference_slack=2, args=['--preload-file', 'water.dds', '-s', 'LEGACY_GL_EMULATION=1']) @@ -1681,6 +1682,8 @@ def test_emscripten_async_wget2(self): self.btest('http.cpp', expected='0', args=['-I' + path_from_root('tests')]) def test_module(self): + if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') + Popen([PYTHON, EMCC, path_from_root('tests', 'browser_module.cpp'), '-o', 'module.js', '-O2', '-s', 'SIDE_MODULE=1', '-s', 'DLOPEN_SUPPORT=1', '-s', 'EXPORTED_FUNCTIONS=["_one", "_two"]']).communicate() self.btest('browser_main.cpp', args=['-O2', '-s', 'MAIN_MODULE=1', '-s', 'DLOPEN_SUPPORT=1'], expected='8') diff --git a/tests/test_core.py b/tests/test_core.py index a1b8279a549a0..6442f8942c78f 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -937,6 +937,8 @@ def test_strings(self): for named in (0, 1): print named + if os.environ.get('EMCC_FAST_COMPILER') == '1' and named: continue # no named globals in fastcomp + Settings.NAMED_GLOBALS = named self.do_run_from_file(src, output, ['wowie', 'too', '74']) diff --git a/tests/test_webgl_context_attributes_common.c b/tests/test_webgl_context_attributes_common.c index 7131203bffa2a..80506b5003ccc 100644 --- a/tests/test_webgl_context_attributes_common.c +++ b/tests/test_webgl_context_attributes_common.c @@ -238,9 +238,9 @@ static void draw() { } -extern int webglAntialiasSupported(); -extern int webglDepthSupported(); -extern int webglStencilSupported(); +extern int webglAntialiasSupported(void); +extern int webglDepthSupported(void); +extern int webglStencilSupported(void); // Check attributes support in the WebGL implementation (see test_webgl_context_attributes function in test_browser.py) // Tests will succeed if they are not. diff --git a/tools/shared.py b/tools/shared.py index 5b02fa4c75850..bd0626dc2fe23 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -337,7 +337,7 @@ def find_temp_directory(): # we re-check sanity when the settings are changed) # We also re-check sanity and clear the cache when the version changes -EMSCRIPTEN_VERSION = '1.8.2' +EMSCRIPTEN_VERSION = '1.8.3' def generate_sanity(): return EMSCRIPTEN_VERSION + '|' + get_llvm_target() + '|' + LLVM_ROOT