aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jsifier.js2
-rw-r--r--src/library.js5
-rw-r--r--src/library_browser.js33
-rw-r--r--src/library_gc.js2
-rw-r--r--src/library_glut.js10
-rw-r--r--src/library_sdl.js2
-rw-r--r--src/parseTools.js30
-rw-r--r--src/postamble.js2
-rw-r--r--src/preamble.js2
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