diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | ChangeLog | 35 | ||||
-rw-r--r-- | cmake/Platform/Emscripten.cmake | 18 | ||||
-rwxr-xr-x | emcc | 49 | ||||
-rwxr-xr-x | emrun | 26 | ||||
-rw-r--r-- | src/intertyper.js | 2 | ||||
-rw-r--r-- | src/jsifier.js | 26 | ||||
-rw-r--r-- | src/library.js | 3 | ||||
-rw-r--r-- | src/library_browser.js | 19 | ||||
-rw-r--r-- | src/library_gl.js | 38 | ||||
-rw-r--r-- | src/library_glut.js | 2 | ||||
-rw-r--r-- | src/library_sdl.js | 34 | ||||
-rw-r--r-- | src/parseTools.js | 36 | ||||
-rw-r--r-- | src/preamble.js | 15 | ||||
-rw-r--r-- | src/relooper/Relooper.cpp | 16 | ||||
-rw-r--r-- | src/relooper/test.txt | 4 | ||||
-rw-r--r-- | src/runtime.js | 2 | ||||
-rw-r--r-- | tests/aniso.c | 5 | ||||
-rw-r--r-- | tests/cubegeom.c | 12 | ||||
-rw-r--r-- | tests/openal_buffers.c | 4 | ||||
-rwxr-xr-x | tests/runner.py | 5 | ||||
-rw-r--r-- | tests/sdl_canvas.c | 2 | ||||
-rw-r--r-- | tests/test_benchmark.py | 56 | ||||
-rw-r--r-- | tests/test_browser.py | 21 | ||||
-rw-r--r-- | tests/test_core.py | 3 | ||||
-rw-r--r-- | tests/test_other.py | 21 | ||||
-rw-r--r-- | tests/test_sanity.py | 28 | ||||
-rw-r--r-- | tests/test_webgl_context_attributes_common.c | 6 | ||||
-rw-r--r-- | tools/shared.py | 30 |
29 files changed, 367 insertions, 152 deletions
@@ -114,3 +114,4 @@ a license to everyone to use it as detailed in LICENSE.) * Vasilis Kalintiris <ehostunreach@gmail.com> * Adam C. Clifton <adam@hulkamaniac.com> * Volo Zyko <volo.zyko@gmail.com> +* Andre Weissflog <floooh@gmail.com> @@ -10,7 +10,40 @@ Not all changes are documented here. In particular, new features, user-oriented Current trunk code ------------------ - To see a list of commits in the active development branch 'incoming', which have not yet been packaged in a release, see - https://github.com/kripken/emscripten/compare/1.7.8...incoming + https://github.com/kripken/emscripten/compare/1.8.2...incoming + +v1.8.2: 1/4/2013 +------------------ + - Fixed glGetFramebufferAttachmentParameteriv and an issue with glGetXXX when the returned value was null. + - Full list of changes: https://github.com/kripken/emscripten/compare/1.8.1...1.8.2 + +v1.8.1: 1/3/2013 +------------------ + - Added support for WebGL hardware instancing extension. + - Improved fastcomp native LLVM backend support. + - Added support for #include filename.js to JS libraries. + - Deprecated --compression emcc command line parameter that manually compressed output JS files, due to performance issues. Instead, it is best to rely on the web server to serve compressed JS files. + - Full list of changes: https://github.com/kripken/emscripten/compare/1.8.0...1.8.1 + +v1.8.0: 12/28/2013 +------------------ + - Fix two issues with function outliner and relooper. + - Full list of changes: https://github.com/kripken/emscripten/compare/1.7.9...1.8.0 + +v1.7.9: 12/27/2013 +------------------ + - Added new command line parameter --em-config that allows specifying a custom location for the .emscripten configuration file. + - Reintroduced relaxed asm.js heap sizes, which no longer need to be power of 2, but a multiple of 16MB is sufficient. + - Added emrun command line tool that allows launching .html pages from command line on desktop and Android as if they were native applications. See https://groups.google.com/forum/#!topic/emscripten-discuss/t2juu3q1H8E . Adds --emrun compiler link flag. + - Began initial work on the "fastcomp" compiler toolchain, a rewrite of the previous JS LLVM AST parsing and codegen via a native LLVM backend. + - Added --exclude-file command line flag to emcc and a matching --exclude command line flag to file packager, which allows specifying files and directories that should be excluded while packaging a VFS data blob. + - Improved GLES2 and EGL support libraries to be more spec-conformant. + - Optimized legacy GL emulation code path. Added new GL_FFP_ONLY optimization path to fixed function pipeline emulation. + - Added new core functions emscripten_log() and emscripten_get_callstack() that allow printing out log messages with demangled and source-mapped callstack information. + - Improved BSD Sockets support. Implemented getprotobyname() for BSD Sockets library. + - Fixed issues with simd support. + - Various bugfixes: #1573, #1846, #1886, #1908, #1918, #1930, #1931, #1942, #1948, .. + - Full list of changes: https://github.com/kripken/emscripten/compare/1.7.8...1.7.9 v1.7.8: 11/19/2013 ------------------ diff --git a/cmake/Platform/Emscripten.cmake b/cmake/Platform/Emscripten.cmake index 1b0c66b4..4f434d14 100644 --- a/cmake/Platform/Emscripten.cmake +++ b/cmake/Platform/Emscripten.cmake @@ -124,22 +124,22 @@ SET(APPLE) set(CMAKE_C_SIZEOF_DATA_PTR 4) set(CMAKE_CXX_SIZEOF_DATA_PTR 4) -set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG" CACHE STRING "Emscripten-overridden CMAKE_C_FLAGS_RELEASE") -set(CMAKE_C_FLAGS_MINSIZEREL "-DNDEBUG" CACHE STRING "Emscripten-overridden CMAKE_C_FLAGS_MINSIZEREL") -set(CMAKE_C_FLAGS_RELWITHDEBINFO "" CACHE STRING "Emscripten-overridden CMAKE_C_FLAGS_RELWITHDEBINFO") -set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG" CACHE STRING "Emscripten-overridden CMAKE_CXX_FLAGS_RELEASE") -set(CMAKE_CXX_FLAGS_MINSIZEREL "-DNDEBUG" CACHE STRING "Emscripten-overridden CMAKE_CXX_FLAGS_MINSIZEREL") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "" CACHE STRING "Emscripten-overridden CMAKE_CXX_FLAGS_RELWITHDEBINFO") +set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O2" CACHE STRING "Emscripten-overridden CMAKE_C_FLAGS_RELEASE") +set(CMAKE_C_FLAGS_MINSIZEREL "-DNDEBUG -O2" CACHE STRING "Emscripten-overridden CMAKE_C_FLAGS_MINSIZEREL") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2" CACHE STRING "Emscripten-overridden CMAKE_C_FLAGS_RELWITHDEBINFO") +set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O2" CACHE STRING "Emscripten-overridden CMAKE_CXX_FLAGS_RELEASE") +set(CMAKE_CXX_FLAGS_MINSIZEREL "-DNDEBUG -O2" CACHE STRING "Emscripten-overridden CMAKE_CXX_FLAGS_MINSIZEREL") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2" CACHE STRING "Emscripten-overridden CMAKE_CXX_FLAGS_RELWITHDEBINFO") set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-O2" CACHE STRING "Emscripten-overridden CMAKE_EXE_LINKER_FLAGS_RELEASE") set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-O2" CACHE STRING "Emscripten-overridden CMAKE_EXE_LINKER_FLAGS_MINSIZEREL") -set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "-O2" CACHE STRING "Emscripten-overridden CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO") +set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "Emscripten-overridden CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO") set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "-O2" CACHE STRING "Emscripten-overridden CMAKE_SHARED_LINKER_FLAGS_RELEASE") set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "-O2" CACHE STRING "Emscripten-overridden CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL") -set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "-O2" CACHE STRING "Emscripten-overridden CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO") +set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "Emscripten-overridden CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO") set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "-O2" CACHE STRING "Emscripten-overridden CMAKE_MODULE_LINKER_FLAGS_RELEASE") set(CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL "-O2" CACHE STRING "Emscripten-overridden CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL") -set(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "-O2" CACHE STRING "Emscripten-overridden CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO") +set(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "Emscripten-overridden CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO") function(em_validate_asmjs_after_build target) add_custom_command(TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E echo Validating build output for asm.js... COMMAND "python" ARGS "${EMSCRIPTEN_ROOT_PATH}/tools/validate_asmjs.py" "$<TARGET_FILE:${target}>") @@ -348,7 +348,9 @@ Options that are modified or new in %s include: --embed-file and --preload-file wildcard is supported - --compression <codec> Compress both the compiled code and embedded/ + --compression <codec> **THIS OPTION IS DEPRECATED** + + Compress both the compiled code and embedded/ preloaded files. <codec> should be a triple, <native_encoder>,<js_decoder>,<js_name> @@ -922,6 +924,7 @@ try: newargs[i] = '' newargs[i+1] = '' elif newargs[i].startswith('--compression'): + logging.warning('--compression is deprecated. Instead, it is recommended you use native gzip compression in your webserver') check_bad_eq(newargs[i]) parts = newargs[i+1].split(',') assert len(parts) == 3, '--compression requires specifying native_encoder,js_decoder,js_name - see emcc --help. got: %s' % newargs[i+1] @@ -1187,7 +1190,9 @@ try: logging.warning('disabling asm.js since embind is not ready for it yet') shared.Settings.ASM_JS = 0 - if os.environ.get('EMCC_FAST_COMPILER'): + fastcomp = os.environ.get('EMCC_FAST_COMPILER') == '1' + + if fastcomp: shared.Settings.ASM_JS = 1 if shared.Settings.DISABLE_EXCEPTION_CATCHING == 0: logging.warning('disabling exception catching since not supported in fastcomp yet') @@ -1205,10 +1210,14 @@ try: assert shared.Settings.NAMED_GLOBALS == 0, 'named globals not supported in fastcomp' assert shared.Settings.PGO == 0, 'pgo not supported in fastcomp' assert shared.Settings.TARGET_LE32 == 1, 'fastcomp requires le32' + assert shared.Settings.USE_TYPED_ARRAYS == 2, 'fastcomp assumes ta2' assert not bind, 'embind not supported in fastcomp yet' + if jcache: + logging.warning('jcache is not supported in fastcomp (you should not need it anyhow), disabling') + jcache = False if shared.Settings.ASM_JS: - assert opt_level >= 1 or os.environ.get('EMCC_FAST_COMPILER'), 'asm.js requires -O1 or above' + assert opt_level >= 1 or fastcomp, 'asm.js requires -O1 or above' if bind: shared.Settings.RESERVED_FUNCTION_POINTERS = max(shared.Settings.RESERVED_FUNCTION_POINTERS, 10) @@ -1220,16 +1229,6 @@ try: shared.Settings.CORRECT_OVERFLOWS = 1 assert not shared.Settings.PGO, 'cannot run PGO in ASM_JS mode' - heap = 4096 - while heap < shared.Settings.TOTAL_MEMORY: - if heap < 16*1024*1024: - heap *= 2 - else: - heap += 16*1024*1024 - if heap != shared.Settings.TOTAL_MEMORY: - logging.warning('increasing TOTAL_MEMORY to %d to be more reasonable for asm.js' % heap) - shared.Settings.TOTAL_MEMORY = heap - if shared.Settings.CORRECT_SIGNS >= 2 or shared.Settings.CORRECT_OVERFLOWS >= 2 or shared.Settings.CORRECT_ROUNDINGS >= 2: debug_level = 4 # must keep debug info to do line-by-line operations @@ -1745,22 +1744,25 @@ try: # At minimum remove dead functions etc., this potentially saves a lot in the size of the generated code (and the time to compile it) link_opts += shared.Building.get_safe_internalize() + ['-globaldce'] - # Simplify LLVM bitcode for fastcomp - if os.environ.get('EMCC_FAST_COMPILER') and not AUTODEBUG: - link_opts += ['-pnacl-abi-simplify-preopt', '-pnacl-abi-simplify-postopt'] - if (not save_bc and not os.environ.get('EMCC_FAST_COMPILER')) or AUTODEBUG: + if (not save_bc and not fastcomp) or AUTODEBUG: # let llvm opt directly emit ll, to skip writing and reading all the bitcode link_opts += ['-S'] shared.Building.llvm_opt(final, link_opts, final + '.link.ll') final = final + '.link.ll' if DEBUG: save_intermediate('linktime', 'll') else: + if fastcomp and not save_bc: + # Simplify LLVM bitcode for fastcomp + link_opts += ['-pnacl-abi-simplify-preopt', '-pnacl-abi-simplify-postopt'] shared.Building.llvm_opt(final, link_opts) if DEBUG: save_intermediate('linktime', 'bc') - - if save_bc: - shutil.copyfile(final, save_bc) + if save_bc: + shutil.copyfile(final, save_bc) + if fastcomp: + shared.Building.llvm_opt(final, ['-pnacl-abi-simplify-preopt', '-pnacl-abi-simplify-postopt'], final + '.adsimp.bc') + final += '.adsimp.bc' + if DEBUG: save_intermediate('adsimp', 'bc') # Prepare .ll for Emscripten if not LEAVE_INPUTS_RAW: @@ -1777,7 +1779,7 @@ try: if DEBUG: save_intermediate('autodebug', 'll') # Simplify bitcode after autodebug - if os.environ.get('EMCC_FAST_COMPILER') and (AUTODEBUG or LEAVE_INPUTS_RAW): + if fastcomp and (AUTODEBUG or LEAVE_INPUTS_RAW): shared.Building.llvm_opt(final, ['-pnacl-abi-simplify-preopt', '-pnacl-abi-simplify-postopt'], final + '.adsimp.bc') final += '.adsimp.bc' if DEBUG: save_intermediate('adsimp', 'bc') @@ -1972,6 +1974,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 = '''<script async type="text/javascript" src="%s"></script>''' % base_js_target html.write(shell.replace('{{{ SCRIPT }}}', script_tag)) else: @@ -492,15 +492,18 @@ def win_print_gpu_info(): print "GPU"+str(i)+ ": " + gpus[i] + " with " + gpu_memory[i] + " MBs of VRAM" def linux_print_gpu_info(): - glxinfo = subprocess.check_output('glxinfo') - for line in glxinfo.split("\n"): - if "OpenGL vendor string:" in line: - gl_vendor = line[len("OpenGL vendor string:"):].strip() - if "OpenGL version string:" in line: - gl_version = line[len("OpenGL version string:"):].strip() - if "OpenGL renderer string:" in line: - gl_renderer = line[len("OpenGL renderer string:"):].strip() - logi('GPU: ' + gl_vendor + ' ' + gl_renderer + ', GL version ' + gl_version) + try: + glxinfo = subprocess.check_output('glxinfo') + for line in glxinfo.split("\n"): + if "OpenGL vendor string:" in line: + gl_vendor = line[len("OpenGL vendor string:"):].strip() + if "OpenGL version string:" in line: + gl_version = line[len("OpenGL version string:"):].strip() + if "OpenGL renderer string:" in line: + gl_renderer = line[len("OpenGL renderer string:"):].strip() + logi('GPU: ' + gl_vendor + ' ' + gl_renderer + ', GL version ' + gl_version) + except: + pass def osx_print_gpu_info(): try: @@ -722,11 +725,12 @@ def find_browser(name): ('firefox_beta', os.path.expanduser('~/firefox_beta/firefox')), ('firefox_aurora', os.path.expanduser('~/firefox_aurora/firefox')), ('firefox_nightly', os.path.expanduser('~/firefox_nightly/firefox')), - ('chrome', which('google-chrome-stable'))] + ('chrome', which('google-chrome-stable')), + ('chrome', which('google-chrome'))] for (alias, browser_exe) in browser_locations: if name == alias: - if os.path.isfile(browser_exe): + if browser_exe is not None and os.path.isfile(browser_exe): return [browser_exe] return None # Could not find the browser diff --git a/src/intertyper.js b/src/intertyper.js index b34d0c08..10822e48 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -241,7 +241,7 @@ function intertyper(lines, sidePass, baseLineNums) { if (mainPass && /^}.*/.test(line)) { inFunction = false; if (mainPass) { - var func = funcHeaderHandler({ tokens: tokenize(currFunctionLines[0], currFunctionLineNum) }); + var func = funcHeaderHandler({ tokens: tokenize(currFunctionLines[0]) }); if (SKIP_STACK_IN_SMALL && /emscripten_autodebug/.exec(func.ident)) { warnOnce('Disabling SKIP_STACK_IN_SMALL because we are apparently processing autodebugger data'); diff --git a/src/jsifier.js b/src/jsifier.js index 6b831b04..8de20c80 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -6,7 +6,6 @@ // Handy sets var STRUCT_LIST = set('struct', 'list'); -var UNDERSCORE_OPENPARENS = set('_', '('); var RELOOP_IGNORED_LASTS = set('return', 'unreachable', 'resume'); var addedLibraryItems = {}; @@ -19,7 +18,7 @@ var INDENTATION = ' '; var functionStubSigs = {}; // JSifier -function JSify(data, functionsOnly, givenFunctions) { +function JSify(data, functionsOnly) { //B.start('jsifier'); var mainPass = !functionsOnly; @@ -96,19 +95,6 @@ function JSify(data, functionsOnly, givenFunctions) { // Functions - Functions.currExternalFunctions = !mainPass ? givenFunctions.currExternalFunctions : {}; - - data.functionStubs.forEach(function(func) { - // Don't overwrite stubs that have more info. - if (!Functions.currExternalFunctions.hasOwnProperty(func.ident) || - !Functions.currExternalFunctions[func.ident].numParams === undefined) { - Functions.currExternalFunctions[func.ident] = { - hasVarArgs: func.hasVarArgs, - numParams: func.params && func.params.length - }; - } - }); - if (phase == 'funcs') { // || phase == 'pre') { // pre has function shells, just to defined implementedFunctions var MAX_BATCH_FUNC_LINES = 1000; while (data.unparsedFunctions.length > 0) { @@ -123,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..) @@ -639,8 +625,8 @@ function JSify(data, functionsOnly, givenFunctions) { } } - if (CLOSURE_ANNOTATIONS) func.JS += '/** @type {number} */'; if (!ASM_JS) { + if (CLOSURE_ANNOTATIONS) func.JS += '/** @type {number} */'; func.JS += INDENTATION + 'var label=0;\n'; } @@ -892,8 +878,8 @@ function JSify(data, functionsOnly, givenFunctions) { function makeAssign(item) { var valueJS = item.JS; item.JS = ''; - if (CLOSURE_ANNOTATIONS) item.JS += '/** @type {number} */ '; if (!ASM_JS || item.intertype != 'alloca' || item.funcData.variables[item.assignTo].impl == VAR_EMULATED) { // asm only needs non-allocas + if (CLOSURE_ANNOTATIONS) item.JS += '/** @type {number} */ '; item.JS += ((ASM_JS || item.overrideSSA) ? '' : 'var ') + toNiceIdent(item.assignTo); } var value = parseNumerical(valueJS); @@ -1810,7 +1796,7 @@ function JSify(data, functionsOnly, givenFunctions) { } }); } - JSify(globalsData, true, Functions); + JSify(globalsData, true); globalsData = null; data.unparsedGlobalss = null; @@ -1824,7 +1810,7 @@ function JSify(data, functionsOnly, givenFunctions) { print('staticSealed = true; // seal the static portion of memory\n'); print('STACK_MAX = STACK_BASE + ' + TOTAL_STACK + ';\n'); print('DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX);\n'); - print('assert(DYNAMIC_BASE < TOTAL_MEMORY); // Stack must fit in TOTAL_MEMORY; allocations from here on may enlarge TOTAL_MEMORY\n'); + print('assert(DYNAMIC_BASE < TOTAL_MEMORY, "TOTAL_MEMORY not big enough for stack");\n'); } if (asmLibraryFunctions.length > 0) { diff --git a/src/library.js b/src/library.js index fc731e01..354e5549 100644 --- a/src/library.js +++ b/src/library.js @@ -8858,7 +8858,8 @@ LibraryManager.library = { } } str += ')'; - args = args.callee.caller.arguments; + var caller = args.callee.caller; + args = caller ? caller.arguments : []; if (first) str = ''; return [args, funcname, str]; diff --git a/src/library_browser.js b/src/library_browser.js index b368c6ac..e0f53052 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_gl.js b/src/library_gl.js index efe3b868..075d7cb5 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -268,11 +268,27 @@ var LibraryGL = { return; case "object": if (result === null) { - GL.recordError(0x0500); // GL_INVALID_ENUM + // null is a valid result for some (e.g., which buffer is bound - perhaps nothing is bound), but otherwise + // can mean an invalid name_, which we need to report as an error + switch(name_) { + case 0x8894: // ARRAY_BUFFER_BINDING + case 0x8B8D: // CURRENT_PROGRAM + case 0x8895: // ELEMENT_ARRAY_BUFFER_BINDING + case 0x8CA6: // FRAMEBUFFER_BINDING + case 0x8CA7: // RENDERBUFFER_BINDING + case 0x8069: // TEXTURE_BINDING_2D + case 0x8514: { // TEXTURE_BINDING_CUBE_MAP + ret = 0; + break; + } + default: { + GL.recordError(0x0500); // GL_INVALID_ENUM #if GL_ASSERTIONS - Module.printErr('GL_INVALID_ENUM in glGet' + type + 'v(' + name_ + ') and it returns null!'); + Module.printErr('GL_INVALID_ENUM in glGet' + type + 'v(' + name_ + ') and it returns null!'); #endif - return; + return; + } + } } else if (result instanceof Float32Array || result instanceof Uint32Array || result instanceof Int32Array || @@ -1688,7 +1704,7 @@ var LibraryGL = { glGetFramebufferAttachmentParameteriv__sig: 'viiii', glGetFramebufferAttachmentParameteriv: function(target, attachment, pname, params) { var result = Module.ctx.getFramebufferAttachmentParameter(target, attachment, pname); - {{{ makeSetValue('params', '0', 'params', 'i32') }}}; + {{{ makeSetValue('params', '0', 'result', 'i32') }}}; }, glIsFramebuffer__sig: 'ii', @@ -1919,6 +1935,13 @@ var LibraryGL = { return id; }; + function ensurePrecision(source) { + if (!/precision +(low|medium|high)p +float *;/.test(source)) { + source = 'precision mediump float;\n' + source; + } + return source; + } + var glShaderSource = _glShaderSource; _glShaderSource = function _glShaderSource(shader, count, string, length) { var source = GL.getSource(shader, count, string, length); @@ -1992,6 +2015,7 @@ var LibraryGL = { source = 'varying float v_fogFragCoord; \n' + source.replace(/gl_FogFragCoord/g, 'v_fogFragCoord'); } + source = ensurePrecision(source); } else { // Fragment shader for (var i = 0; i < GL.immediate.MAX_TEXTURES; i++) { var old = source; @@ -2023,7 +2047,7 @@ var LibraryGL = { source = 'varying float v_fogFragCoord; \n' + source.replace(/gl_FogFragCoord/g, 'v_fogFragCoord'); } - source = 'precision mediump float;\n' + source; + source = ensurePrecision(source); } #if GL_DEBUG GL.shaderSources[shader] = source; @@ -4973,7 +4997,7 @@ var LibraryGL = { GL.instancedArraysExt.vertexAttribDivisorANGLE(index, divisor); }, - glDrawArraysInstanced_sig: 'viiii', + glDrawArraysInstanced__sig: 'viiii', glDrawArraysInstanced: function(mode, first, count, primcount) { #if GL_ASSERTIONS assert(GL.instancedArraysExt, 'Must have ANGLE_instanced_arrays extension to use WebGL instancing'); @@ -4981,7 +5005,7 @@ var LibraryGL = { GL.instancedArraysExt.drawArraysInstancedANGLE(mode, first, count, primcount); }, - glDrawElementsInstanced_sig: 'viiiii', + glDrawElementsInstanced__sig: 'viiiii', glDrawElementsInstanced: function(mode, count, type, indices, primcount) { #if GL_ASSERTIONS assert(GL.instancedArraysExt, 'Must have ANGLE_instanced_arrays extension to use WebGL instancing'); diff --git a/src/library_glut.js b/src/library_glut.js index ba4d75ab..76a52b73 100644 --- a/src/library_glut.js +++ b/src/library_glut.js @@ -126,6 +126,8 @@ var LibraryGLUT = { return keycode - 106 + 42; // *,+-./ TODO handle shift? switch (keycode) { + case 9: // tab key + case 13: // return key case 27: // escape case 32: // space case 61: // equal diff --git a/src/library_sdl.js b/src/library_sdl.js index 1c1e8107..fc38dd1c 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/parseTools.js b/src/parseTools.js index ff981264..22e9b94c 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -16,6 +16,7 @@ function processMacros(text) { // Simple #if/else/endif preprocessing for a file. Checks if the // ident checked is true in our global. +// Also handles #include x.js (similar to C #include <file>) function preprocess(text) { var lines = text.split('\n'); var ret = ''; @@ -30,25 +31,30 @@ function preprocess(text) { ret += line + '\n'; } } else { - if (line[1] && line[1] == 'i') { // if - var parts = line.split(' '); - var ident = parts[1]; - var op = parts[2]; - var value = parts[3]; - if (op) { - if (op === '==') { - showStack.push(ident in this && this[ident] == value); - } else if (op === '!=') { - showStack.push(!(ident in this && this[ident] == value)); + if (line[1] == 'i') { + if (line[2] == 'f') { // if + var parts = line.split(' '); + var ident = parts[1]; + var op = parts[2]; + var value = parts[3]; + if (op) { + if (op === '==') { + showStack.push(ident in this && this[ident] == value); + } else if (op === '!=') { + showStack.push(!(ident in this && this[ident] == value)); + } else { + error('unsupported preprecessor op ' + op); + } } else { - error('unsupported preprecessor op ' + op); + showStack.push(ident in this && this[ident] > 0); } - } else { - showStack.push(ident in this && this[ident] > 0); + } else if (line[2] == 'n') { // include + var included = read(line.substr(line.indexOf(' ')+1)); + ret += '\n' + preprocess(included) + '\n' } - } else if (line[2] && line[2] == 'l') { // else + } else if (line[2] == 'l') { // else showStack.push(!showStack.pop()); - } else if (line[2] && line[2] == 'n') { // endif + } else if (line[2] == 'n') { // endif showStack.pop(); } else { throw "Unclear preprocessor command: " + line; diff --git a/src/preamble.js b/src/preamble.js index 832ec2c3..f9fccdf6 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -866,6 +866,21 @@ var TOTAL_STACK = Module['TOTAL_STACK'] || {{{ TOTAL_STACK }}}; var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || {{{ TOTAL_MEMORY }}}; var FAST_MEMORY = Module['FAST_MEMORY'] || {{{ FAST_MEMORY }}}; +#if ASM_JS +var totalMemory = 4096; +while (totalMemory < TOTAL_MEMORY || totalMemory < 2*TOTAL_STACK) { + if (totalMemory < 16*1024*1024) { + totalMemory *= 2; + } else { + totalMemory += 16*1024*1024 + } +} +if (totalM |