diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/jsifier.js | 2 | ||||
-rw-r--r-- | src/library.js | 43 | ||||
-rw-r--r-- | src/preamble.js | 25 | ||||
-rw-r--r-- | src/proxyClient.js | 54 | ||||
-rw-r--r-- | src/runtime.js | 22 | ||||
-rw-r--r-- | src/settings.js | 11 | ||||
-rw-r--r-- | src/utility.js | 6 |
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(); } |