aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jsifier.js2
-rw-r--r--src/library.js43
-rw-r--r--src/preamble.js25
-rw-r--r--src/proxyClient.js54
-rw-r--r--src/runtime.js22
-rw-r--r--src/settings.js11
-rw-r--r--src/utility.js6
7 files changed, 129 insertions, 34 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index 35846d39..c1ca893b 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1419,7 +1419,7 @@ function JSify(data, functionsOnly) {
// store current list offset in tempInt, advance list offset by STACK_ALIGN, return list entry stored at tempInt
return '(tempInt=' + makeGetValue(ident, Runtime.QUANTUM_SIZE, '*') + ',' +
- makeSetValue(ident, Runtime.QUANTUM_SIZE, 'tempInt + ' + move, '*', null, null, null, null, ',') + ',' +
+ makeSetValue(ident, Runtime.QUANTUM_SIZE, asmCoercion('tempInt + ' + move, 'i32'), '*', null, null, null, null, ',') + ',' +
makeGetValue(makeGetValue(ident, 0, '*'), 'tempInt', item.type) + ')';
}
diff --git a/src/library.js b/src/library.js
index f69b52e5..c1eb2219 100644
--- a/src/library.js
+++ b/src/library.js
@@ -9051,6 +9051,49 @@ LibraryManager.library = {
_emscripten_log_js(flags, str);
},
+ emscripten_get_compiler_setting: function(name) {
+ name = Pointer_stringify(name);
+
+ var ret = Runtime.getCompilerSetting(name);
+ if (typeof ret === 'number') return ret;
+
+ if (!_emscripten_get_compiler_setting.cache) _emscripten_get_compiler_setting.cache = {};
+ var cache = _emscripten_get_compiler_setting.cache;
+ var fullname = name + '__str';
+ var fullret = cache[fullname];
+ if (fullret) return fullret;
+ return cache[fullname] = allocate(intArrayFromString(ret + ''), 'i8', ALLOC_NORMAL);
+ },
+
+#if ASM_JS
+#if ALLOW_MEMORY_GROWTH
+ emscripten_replace_memory__asm: true, // this is used inside the asm module
+ emscripten_replace_memory__sig: 'viiiiiiii', // bogus
+ emscripten_replace_memory: function(_HEAP8, _HEAP16, _HEAP32, _HEAPU8, _HEAPU16, _HEAPU32, _HEAPF32, _HEAPF64) {
+ _HEAP8 = _HEAP8; // fake asm coercions
+ _HEAP16 = _HEAP16;
+ _HEAP32 = _HEAP32;
+ _HEAPU8 = _HEAPU8;
+ _HEAPU16 = _HEAPU16;
+ _HEAPU32 = _HEAPU32;
+ _HEAPF32 = _HEAPF32;
+ _HEAPF64 = _HEAPF64;
+ HEAP8 = _HEAP8; // replace the memory views
+ HEAP16 = _HEAP16;
+ HEAP32 = _HEAP32;
+ HEAPU8 = _HEAPU8;
+ HEAPU16 = _HEAPU16;
+ HEAPU32 = _HEAPU32;
+ HEAPF32 = _HEAPF32;
+ HEAPF64 = _HEAPF64;
+ },
+ // this function is inside the asm block, but prevents validation as asm.js
+ // the codebase still benefits from being in the general asm.js shape,
+ // but should not declare itself as validating (which is prevented in ASM_JS == 2).
+ {{{ (assert(ASM_JS === 2), DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.push('emscripten_replace_memory'), '') }}}
+#endif
+#endif
+
//============================
// emscripten vector ops
//============================
diff --git a/src/preamble.js b/src/preamble.js
index 5038e9c4..4f715167 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -860,33 +860,19 @@ var DYNAMIC_BASE = 0, DYNAMICTOP = 0; // dynamic area handled by sbrk
#if USE_TYPED_ARRAYS
function enlargeMemory() {
#if ALLOW_MEMORY_GROWTH == 0
-#if ASM_JS == 0
abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL_MEMORY + ', (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.');
#else
- abort('Cannot enlarge memory arrays in asm.js. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL_MEMORY + ', or (2) set Module.TOTAL_MEMORY before the program runs.');
-#endif
-#else
// TOTAL_MEMORY is the current size of the actual array, and DYNAMICTOP is the new top.
#if ASSERTIONS
- Module.printErr('Warning: Enlarging memory arrays, this is not fast, and ALLOW_MEMORY_GROWTH is not fully tested with all optimizations on! ' + [DYNAMICTOP, TOTAL_MEMORY]); // We perform safe elimination instead of elimination in this mode, but if you see this error, try to disable it and other optimizations entirely
+ Module.printErr('Warning: Enlarging memory arrays, this is not fast! ' + [DYNAMICTOP, TOTAL_MEMORY]);
assert(DYNAMICTOP >= TOTAL_MEMORY);
assert(TOTAL_MEMORY > 4); // So the loop below will not be infinite
#endif
- while (TOTAL_MEMORY <= DYNAMICTOP) { // Simple heuristic. Override enlargeMemory() if your program has something more optimal for it
+
+ while (TOTAL_MEMORY <= DYNAMICTOP) { // Simple heuristic.
TOTAL_MEMORY = alignMemoryPage(2*TOTAL_MEMORY);
}
assert(TOTAL_MEMORY <= Math.pow(2, 30)); // 2^30==1GB is a practical maximum - 2^31 is already close to possible negative numbers etc.
-#if USE_TYPED_ARRAYS == 1
- var oldIHEAP = IHEAP;
- Module['HEAP'] = Module['IHEAP'] = HEAP = IHEAP = new Int32Array(TOTAL_MEMORY);
- IHEAP.set(oldIHEAP);
- IHEAPU = new Uint32Array(IHEAP.buffer);
-#if USE_FHEAP
- var oldFHEAP = FHEAP;
- Module['FHEAP'] = FHEAP = new Float64Array(TOTAL_MEMORY);
- FHEAP.set(oldFHEAP);
-#endif
-#endif
#if USE_TYPED_ARRAYS == 2
var oldHEAP8 = HEAP8;
var buffer = new ArrayBuffer(TOTAL_MEMORY);
@@ -899,6 +885,11 @@ function enlargeMemory() {
Module['HEAPF32'] = HEAPF32 = new Float32Array(buffer);
Module['HEAPF64'] = HEAPF64 = new Float64Array(buffer);
HEAP8.set(oldHEAP8);
+#else
+ abort('cannot enlarge memory arrays in non-ta2 modes');
+#endif
+#if ASM_JS
+ _emscripten_replace_memory(HEAP8, HEAP16, HEAP32, HEAPU8, HEAPU16, HEAPU32, HEAPF32, HEAPF64);
#endif
#endif
}
diff --git a/src/proxyClient.js b/src/proxyClient.js
index 8f4ad7a6..2d1c76fe 100644
--- a/src/proxyClient.js
+++ b/src/proxyClient.js
@@ -3,9 +3,39 @@
Module.ctx = Module.canvas.getContext('2d');
+// render
+
+var renderFrameData = null;
+
+function renderFrame() {
+ var dst = Module.canvasData.data;
+ if (dst.set) {
+ dst.set(renderFrameData);
+ } else {
+ for (var i = 0; i < renderFrameData.length; i++) {
+ dst[i] = renderFrameData[i];
+ }
+ }
+ Module.ctx.putImageData(Module.canvasData, 0, 0);
+ renderFrameData = null;
+}
+
+window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
+ window.webkitRequestAnimationFrame || window.msRequestAnimationFrame ||
+ renderFrame;
+
+// end render
+
var worker = new Worker('{{{ filename }}}.js');
+var workerResponded = false;
+
worker.onmessage = function worker_onmessage(event) {
+ if (!workerResponded) {
+ workerResponded = true;
+ if (Module.setStatus) Module.setStatus('');
+ }
+
var data = event.data;
switch (data.target) {
case 'stdout': {
@@ -26,20 +56,18 @@ worker.onmessage = function worker_onmessage(event) {
Module.canvas.width = data.width;
Module.canvas.height = data.height;
Module.canvasData = Module.ctx.getImageData(0, 0, data.width, data.height);
- postMessage({ target: 'canvas', boundingClientRect: Module.canvas.getBoundingClientRect() });
+ worker.postMessage({ target: 'canvas', boundingClientRect: cloneObject(Module.canvas.getBoundingClientRect()) });
break;
}
case 'render': {
- var src = data.image.data;
- var dst = Module.canvasData.data;
- if (dst.set) {
- dst.set(src);
+ if (renderFrameData) {
+ // previous image was not rendered yet, just update image
+ renderFrameData = data.image.data;
} else {
- for (var i = 0; i < src.length; i++) {
- dst[i] = src[i];
- }
+ // previous image was rendered so update image and request another frame
+ renderFrameData = data.image.data;
+ window.requestAnimationFrame(renderFrame);
}
- Module.ctx.putImageData(Module.canvasData, 0, 0);
break;
}
default: throw 'eh?';
@@ -50,7 +78,7 @@ worker.onmessage = function worker_onmessage(event) {
}
};
-function cloneEvent(event) {
+function cloneObject(event) {
var ret = {};
for (var x in event) {
if (x == x.toUpperCase()) continue;
@@ -62,20 +90,20 @@ function cloneEvent(event) {
['keydown', 'keyup', 'keypress', 'blur', 'visibilitychange'].forEach(function(event) {
document.addEventListener(event, function(event) {
- worker.postMessage({ target: 'document', event: cloneEvent(event) });
+ worker.postMessage({ target: 'document', event: cloneObject(event) });
event.preventDefault();
});
});
['unload'].forEach(function(event) {
window.addEventListener(event, function(event) {
- worker.postMessage({ target: 'window', event: cloneEvent(event) });
+ worker.postMessage({ target: 'window', event: cloneObject(event) });
});
});
['mousedown', 'mouseup', 'mousemove', 'DOMMouseScroll', 'mousewheel', 'mouseout'].forEach(function(event) {
Module.canvas.addEventListener(event, function(event) {
- worker.postMessage({ target: 'canvas', event: cloneEvent(event) });
+ worker.postMessage({ target: 'canvas', event: cloneObject(event) });
event.preventDefault();
}, true);
});
diff --git a/src/runtime.js b/src/runtime.js
index a9265e70..0c724e50 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -487,6 +487,19 @@ var Runtime = {
}
},
+#if RETAIN_COMPILER_SETTINGS
+ compilerSettings: {},
+#endif
+
+ getCompilerSetting: function(name) {
+#if RETAIN_COMPILER_SETTINGS == 0
+ throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work';
+#else
+ if (!(name in Runtime.compilerSettings)) return 'invalid compiler setting: ' + name;
+ return Runtime.compilerSettings[name];
+#endif
+ },
+
#if RUNTIME_DEBUG
debug: true, // Switch to false at runtime to disable logging at the right times
@@ -612,3 +625,12 @@ function reSign(value, bits, ignore) {
// Then 'dynamic' memory for sbrk.
Runtime.GLOBAL_BASE = Runtime.alignMemory(1);
+if (RETAIN_COMPILER_SETTINGS) {
+ var blacklist = set('RELOOPER', 'STRUCT_INFO');
+ for (var x in this) {
+ try {
+ if (x[0] !== '_' && !(x in blacklist) && x == x.toUpperCase() && (typeof this[x] === 'number' || typeof this[x] === 'string' || this.isArray())) Runtime.compilerSettings[x] = this[x];
+ } catch(e){}
+ }
+}
+
diff --git a/src/settings.js b/src/settings.js
index 1db91dca..c8114059 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -315,6 +315,17 @@ var EXPORT_ALL = 0; // If true, we export all the symbols. Note that this does *
// still eliminate functions as dead. This just exports them on the Module object.
var EXPORT_BINDINGS = 0; // Export all bindings generator functions (prefixed with emscripten_bind_). This
// is necessary to use the bindings generator with asm.js
+var RETAIN_COMPILER_SETTINGS = 0; // Remembers the values of these settings, and makes them accessible
+ // through Runtime.getCompilerSetting and emscripten_get_compiler_setting.
+ // To see what is retained, look for compilerSettings in the generated code.
+
+
+var EMSCRIPTEN_VERSION = ''; // this will contain the emscripten version. you should not modify it. This
+ // and the following few settings are useful in combination with
+ // RETAIN_COMPILER_SETTINGS
+var OPT_LEVEL = 0; // this will contain the optimization level (-Ox). you should not modify it.
+var DEBUG_LEVEL = 0; // this will contain the debug level (-gx). you should not modify it.
+
// JS library functions (C functions implemented in JS)
// that we include by default. If you want to make sure
diff --git a/src/utility.js b/src/utility.js
index 178c596b..54cc2d69 100644
--- a/src/utility.js
+++ b/src/utility.js
@@ -200,11 +200,11 @@ function dprint() {
printErr(text);
}
-var PROF_ORIGIN = Date.now();
-var PROF_TIME = PROF_ORIGIN;
+var _PROF_ORIGIN = Date.now();
+var _PROF_TIME = _PROF_ORIGIN;
function PROF(pass) {
if (!pass) {
- dprint("Profiling: " + ((Date.now() - PROF_TIME)/1000) + ' seconds, total: ' + ((Date.now() - PROF_ORIGIN)/1000));
+ dprint("Profiling: " + ((Date.now() - _PROF_TIME)/1000) + ' seconds, total: ' + ((Date.now() - _PROF_ORIGIN)/1000));
}
PROF_TIME = Date.now();
}