diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/jsifier.js | 2 | ||||
-rw-r--r-- | src/library.js | 5 | ||||
-rw-r--r-- | src/library_browser.js | 33 | ||||
-rw-r--r-- | src/library_gc.js | 2 | ||||
-rw-r--r-- | src/library_glut.js | 10 | ||||
-rw-r--r-- | src/library_sdl.js | 2 | ||||
-rw-r--r-- | src/parseTools.js | 30 | ||||
-rw-r--r-- | src/postamble.js | 2 | ||||
-rw-r--r-- | src/preamble.js | 2 |
9 files changed, 60 insertions, 28 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index 8ab96a25..2c83d036 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -1357,7 +1357,7 @@ function JSify(data, functionsOnly, givenFunctions) { var ignoreFunctionIndexizing = []; var useJSArgs = (simpleIdent + '__jsargs') in LibraryManager.library; var hasVarArgs = isVarArgsFunctionType(type); - var normalArgs = (hasVarArgs && !useJSArgs) ? countNormalArgs(type) : -1; + var normalArgs = (hasVarArgs && !useJSArgs) ? countNormalArgs(type, null, true) : -1; var byPointer = getVarData(funcData, ident); var byPointerForced = false; diff --git a/src/library.js b/src/library.js index 04976b92..d897556f 100644 --- a/src/library.js +++ b/src/library.js @@ -6186,8 +6186,9 @@ LibraryManager.library = { clock_gettime__deps: ['__timespec_struct_layout'], clock_gettime: function(clk_id, tp) { // int clock_gettime(clockid_t clk_id, struct timespec *tp); - {{{ makeSetValue('tp', '___timespec_struct_layout.tv_sec', '0', 'i32') }}} - {{{ makeSetValue('tp', '___timespec_struct_layout.tv_nsec', '0', 'i32') }}} + var now = Date.now(); + {{{ makeSetValue('tp', '___timespec_struct_layout.tv_sec', 'Math.floor(now/1000)', 'i32') }}}; // seconds + {{{ makeSetValue('tp', '___timespec_struct_layout.tv_nsec', '0', 'i32') }}}; // nanoseconds - not supported return 0; }, clock_settime: function(clk_id, tp) { diff --git a/src/library_browser.js b/src/library_browser.js index 0ed04e19..2e6c9150 100644 --- a/src/library_browser.js +++ b/src/library_browser.js @@ -184,7 +184,7 @@ mergeInto(LibraryManager.library, { }; audio.src = url; // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror - setTimeout(function() { + Browser.safeSetTimeout(function() { finish(audio); // try to use it even though it is not necessarily ready to play }, 10000); } else { @@ -361,6 +361,30 @@ mergeInto(LibraryManager.library, { window.requestAnimationFrame(func); }, + // generic abort-aware wrapper for an async callback + safeCallback: function(func) { + return function() { + if (!ABORT) return func.apply(null, arguments); + }; + }, + + // abort-aware versions + safeRequestAnimationFrame: function(func) { + Browser.requestAnimationFrame(function() { + if (!ABORT) func(); + }); + }, + safeSetTimeout: function(func, timeout) { + setTimeout(function() { + if (!ABORT) func(); + }, timeout); + }, + safeSetInterval: function(func, timeout) { + setInterval(function() { + if (!ABORT) func(); + }, timeout); + }, + getMovementX: function(event) { return event['movementX'] || event['mozMovementX'] || @@ -612,7 +636,7 @@ mergeInto(LibraryManager.library, { Module['noExitRuntime'] = true; // TODO: cache these to avoid generating garbage - setTimeout(function() { + Browser.safeSetTimeout(function() { _emscripten_run_script(script); }, millis); }, @@ -621,6 +645,7 @@ mergeInto(LibraryManager.library, { Module['noExitRuntime'] = true; Browser.mainLoop.runner = function() { + if (ABORT) return; if (Browser.mainLoop.queue.length > 0) { var start = Date.now(); var blocker = Browser.mainLoop.queue.shift(); @@ -723,9 +748,9 @@ mergeInto(LibraryManager.library, { } if (millis >= 0) { - setTimeout(wrapper, millis); + Browser.safeSetTimeout(wrapper, millis); } else { - Browser.requestAnimationFrame(wrapper); + Browser.safeRequestAnimationFrame(wrapper); } }, diff --git a/src/library_gc.js b/src/library_gc.js index 2a164250..b3dae0e9 100644 --- a/src/library_gc.js +++ b/src/library_gc.js @@ -26,7 +26,7 @@ if (GC_SUPPORT) { _GC_finalizer_notifier = _malloc(4); setValue(_GC_finalizer_notifier, 0, 'i32'); if (ENVIRONMENT_IS_WEB) { - setInterval(function() { + Browser.safeSetInterval(function() { GC.maybeCollect(); }, 1000); } else { diff --git a/src/library_glut.js b/src/library_glut.js index 35348028..38cfe55b 100644 --- a/src/library_glut.js +++ b/src/library_glut.js @@ -322,16 +322,17 @@ var LibraryGLUT = { var callback = function() { if (GLUT.idleFunc) { Runtime.dynCall('v', GLUT.idleFunc); - window.setTimeout(callback, 0); + Browser.safeSetTimeout(callback, 0); } } - if (!GLUT.idleFunc) - window.setTimeout(callback, 0); + if (!GLUT.idleFunc) { + Browser.safeSetTimeout(callback, 0); + } GLUT.idleFunc = func; }, glutTimerFunc: function(msec, func, value) { - window.setTimeout(function() { Runtime.dynCall('vi', func, [value]); }, msec); + Browser.safeSetTimeout(function() { Runtime.dynCall('vi', func, [value]); }, msec); }, glutDisplayFunc: function(func) { @@ -419,6 +420,7 @@ var LibraryGLUT = { glutPostRedisplay: function() { if (GLUT.displayFunc) { Browser.requestAnimationFrame(function() { + if (ABORT) return; Runtime.dynCall('v', GLUT.displayFunc); }); } diff --git a/src/library_sdl.js b/src/library_sdl.js index a5080a99..d31c37f5 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1197,7 +1197,7 @@ var LibrarySDL = { SDL_PauseAudio: function(pauseOn) { if (SDL.audio.paused !== pauseOn) { - SDL.audio.timer = pauseOn ? SDL.audio.timer && clearInterval(SDL.audio.timer) : setInterval(SDL.audio.caller, 1/35); + SDL.audio.timer = pauseOn ? SDL.audio.timer && clearInterval(SDL.audio.timer) : Browser.safeSetInterval(SDL.audio.caller, 1/35); } SDL.audio.paused = pauseOn; }, diff --git a/src/parseTools.js b/src/parseTools.js index f30883b5..45046558 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -129,9 +129,13 @@ function isPointerType(type) { return type[type.length-1] == '*'; } +function isArrayType(type) { + return /^\[\d+\ x\ (.*)\]/.test(type); +} + function isStructType(type) { if (isPointerType(type)) return false; - if (/^\[\d+\ x\ (.*)\]/.test(type)) return true; // [15 x ?] blocks. Like structs + if (isArrayType(type)) return true; if (/<?{ ?[^}]* ?}>?/.test(type)) return true; // { i32, i8 } etc. - anonymous struct types // See comment in isStructPointerType() return type[0] == '%'; @@ -286,18 +290,18 @@ function isVarArgsFunctionType(type) { return type.substr(-varArgsSuffix.length) == varArgsSuffix; } -function getNumVars(type) { // how many variables are needed to represent this type +function getNumLegalizedVars(type) { // how many legalized variables are needed to represent this type if (type in Runtime.FLOAT_TYPES) return 1; return Math.max(getNumIntChunks(type), 1); } -function countNormalArgs(type, out) { +function countNormalArgs(type, out, legalized) { out = out || {}; if (!isFunctionType(type, out)) return -1; var ret = 0; if (out.segments) { for (var i = 0; i < out.segments.length; i++) { - ret += getNumVars(out.segments[i][0].text); + ret += legalized ? getNumLegalizedVars(out.segments[i][0].text) : 1; } } if (isVarArgsFunctionType(type)) ret--; @@ -1754,10 +1758,11 @@ function getGetElementPtrIndexes(item) { indexes.push(getFastValue(Runtime.getNativeTypeSize(type), '*', offset, 'i32')); } } - item.params.slice(2, item.params.length).forEach(function(arg) { + item.params.slice(2, item.params.length).forEach(function(arg, i) { var curr = arg; // TODO: If index is constant, optimize var typeData = Types.types[type]; + assert(typeData || i == item.params.length - 3); // can be null, when we get to the end (a basic type) if (isStructType(type) && typeData.needsFlattening) { if (typeData.flatFactor) { indexes.push(getFastValue(curr, '*', typeData.flatFactor, 'i32')); @@ -1773,16 +1778,15 @@ function getGetElementPtrIndexes(item) { indexes.push(curr); } } - if (!isNumber(curr) || parseInt(curr) < 0) { - // We have a *variable* to index with, or a negative number. In both - // cases, in theory we might need to do something dynamic here. FIXME? - // But, most likely all the possible types are the same, so do that case here now... - for (var i = 1; i < typeData.fields.length; i++) { - assert(typeData.fields[0] === typeData.fields[i]); + if (typeData) { + if (isArrayType(type)) { + type = typeData.fields[0]; // all the same, so accept even out-of-bounds this way + } else { + assert(isNumber(curr)); // cannot be dynamic + type = typeData.fields[curr]; } - curr = 0; + assert(type); } - type = typeData && typeData.fields[curr] ? typeData.fields[curr] : ''; }); var ret = getFastValues(indexes, '+', 'i32'); diff --git a/src/postamble.js b/src/postamble.js index d0b737f8..49fd9b3e 100644 --- a/src/postamble.js +++ b/src/postamble.js @@ -104,7 +104,7 @@ function run(args) { setTimeout(function() { Module['setStatus'](''); }, 1); - doRun(); + if (!ABORT) doRun(); }, 1); return 0; } else { diff --git a/src/preamble.js b/src/preamble.js index 659b3869..35dfeba9 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -231,7 +231,7 @@ var setjmpId = 1; // Used in setjmp/longjmp var setjmpLabels = {}; #endif -var ABORT = false; +var ABORT = false; // whether we are quitting the application. no code should run after this. set in exit() and abort() var undef = 0; // tempInt is used for 32-bit signed values or smaller. tempBigInt is used |