From e7ae82583954c111118c3801bd3198e01332478f Mon Sep 17 00:00:00 2001
From: Harald Reingruber
Date: Thu, 12 May 2016 11:01:57 +0200
Subject: [PATCH 001/102] fixes wheelDelta for MSIE
---
src/library_html5.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/library_html5.js b/src/library_html5.js
index 9b18f38fbbbf8..43a3efab544b8 100644
--- a/src/library_html5.js
+++ b/src/library_html5.js
@@ -307,7 +307,7 @@ var LibraryJSEvents = {
var e = event || window.event;
JSEvents.fillMouseEventData(JSEvents.wheelEvent, e, target);
{{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaX, 'e["wheelDeltaX"]', 'double') }}};
- {{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaY, '-e["wheelDeltaY"] /* Invert to unify direction with the DOM Level 3 wheel event. */', 'double') }}};
+ {{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaY, '-(e["wheelDeltaY"] ? e["wheelDeltaY"] : e["wheelDelta"]) /* 1. Invert to unify direction with the DOM Level 3 wheel event. 2. MSIE doesn't provide wheelDeltaY, so wheelDelta is used as a fallback. */', 'double') }}};
{{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaZ, '0 /* Not available */', 'double') }}};
{{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaMode, '0 /* DOM_DELTA_PIXEL */', 'i32') }}};
var shouldCancel = Runtime.dynCall('iiii', callbackfunc, [eventTypeId, JSEvents.wheelEvent, userData]);
From 759beea47e8d1dd84c39be0f30ea2ff1b5e43c94 Mon Sep 17 00:00:00 2001
From: Harald Reingruber
Date: Fri, 13 May 2016 10:41:48 +0200
Subject: [PATCH 002/102] removed accidentally added closing quote in comment.
---
src/library_html5.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/library_html5.js b/src/library_html5.js
index 43a3efab544b8..42bc3842eaeb6 100644
--- a/src/library_html5.js
+++ b/src/library_html5.js
@@ -307,7 +307,7 @@ var LibraryJSEvents = {
var e = event || window.event;
JSEvents.fillMouseEventData(JSEvents.wheelEvent, e, target);
{{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaX, 'e["wheelDeltaX"]', 'double') }}};
- {{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaY, '-(e["wheelDeltaY"] ? e["wheelDeltaY"] : e["wheelDelta"]) /* 1. Invert to unify direction with the DOM Level 3 wheel event. 2. MSIE doesn't provide wheelDeltaY, so wheelDelta is used as a fallback. */', 'double') }}};
+ {{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaY, '-(e["wheelDeltaY"] ? e["wheelDeltaY"] : e["wheelDelta"]) /* 1. Invert to unify direction with the DOM Level 3 wheel event. 2. MSIE does not provide wheelDeltaY, so wheelDelta is used as a fallback. */', 'double') }}};
{{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaZ, '0 /* Not available */', 'double') }}};
{{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaMode, '0 /* DOM_DELTA_PIXEL */', 'i32') }}};
var shouldCancel = Runtime.dynCall('iiii', callbackfunc, [eventTypeId, JSEvents.wheelEvent, userData]);
From ff58311baa59001f4e7286546d2f5bdd40f08ef3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?=
Date: Fri, 13 May 2016 11:57:42 +0300
Subject: [PATCH 003/102] Rename "requestFullScreen" to "requestFullscreen" and
"cancelFullScreen" to "exitFullscreen" to strictly adhere to the same
function naming as the Fullscreen API spec. Rename internal APIs to use lower
case 's' as well for 'fullscreen' where applicable. Remove a bunch of
capitalizations for symbol names that no browser ever implemented, e.g. afaik
'mozFullscreenElement' never existed, but was always 'mozFullScreenElement'.
Relates to #4310.
---
src/headless.js | 6 +-
src/headlessCanvas.js | 2 +-
src/library_browser.js | 80 ++++++++++---------
src/library_glfw.js | 29 +++++--
src/library_glut.js | 49 +++++++-----
src/library_html5.js | 2 +-
src/library_sdl.js | 14 ++--
src/shell.html | 2 +-
src/shell_minimal.html | 2 +-
tests/canvas_style_proxy_shell.html | 2 +-
tests/embind/shell.html | 2 +-
.../test_pthread_mandelbrot_shell.html | 2 +-
tests/sdl_canvas_size.html | 2 +-
tests/test_fflush.html | 2 +-
tests/test_html5_fullscreen.html | 2 +-
tests/webgl_destroy_context_shell.html | 2 +-
16 files changed, 116 insertions(+), 84 deletions(-)
diff --git a/src/headless.js b/src/headless.js
index d329eb2ac98c8..0a8b2218949f1 100644
--- a/src/headless.js
+++ b/src/headless.js
@@ -145,8 +145,8 @@ var document = {
case 'div': {
return {
appendChild: function() {},
- requestFullScreen: function() {
- return document.getElementById('canvas').requestFullScreen();
+ requestFullscreen: function() {
+ return document.getElementById('canvas').requestFullscreen();
},
};
}
@@ -177,7 +177,7 @@ var document = {
appendChild: function(){},
},
exitPointerLock: function(){},
- cancelFullScreen: function(){},
+ exitFullscreen: function(){},
};
var alert = function(x) {
print(x);
diff --git a/src/headlessCanvas.js b/src/headlessCanvas.js
index 25f7052e1f1f7..64d5ae2539703 100644
--- a/src/headlessCanvas.js
+++ b/src/headlessCanvas.js
@@ -607,7 +607,7 @@ function headlessCanvas() {
eventListeners: {},
addEventListener: function(){},
removeEventListener: function(){},
- requestFullScreen: function() {
+ requestFullscreen: function() {
document.fullscreenElement = document.getElementById('canvas');
window.setTimeout(function() {
document.callEventListeners('fullscreenchange');
diff --git a/src/library_browser.js b/src/library_browser.js
index b610d133601d9..7712215850a64 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -3,7 +3,8 @@
// Utilities for browser environments
var LibraryBrowser = {
$Browser__deps: ['emscripten_set_main_loop', 'emscripten_set_main_loop_timing'],
- $Browser__postset: 'Module["requestFullScreen"] = function Module_requestFullScreen(lockPointer, resizeCanvas, vrDevice) { Browser.requestFullScreen(lockPointer, resizeCanvas, vrDevice) };\n' + // exports
+ $Browser__postset: 'Module["requestFullScreen"] = function Module_requestFullScreen(lockPointer, resizeCanvas, vrDevice) { Module.printErr("Module.requestFullScreen is deprecated. Please call Module.requestFullscreen instead."); Module["requestFullScreen"] = Module["requestFullscreen"]; Browser.requestFullScreen(lockPointer, resizeCanvas, vrDevice) };\n' + // exports
+ 'Module["requestFullscreen"] = function Module_requestFullscreen(lockPointer, resizeCanvas, vrDevice) { Browser.requestFullscreen(lockPointer, resizeCanvas, vrDevice) };\n' + // exports
'Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) };\n' +
'Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };\n' +
'Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() };\n' +
@@ -74,7 +75,7 @@ var LibraryBrowser = {
if (Module['postMainLoop']) Module['postMainLoop']();
}
},
- isFullScreen: false,
+ isFullscreen: false,
pointerLock: false,
moduleContextCreatedCallbacks: [],
workers: [],
@@ -313,10 +314,10 @@ var LibraryBrowser = {
destroyContext: function(canvas, useWebGL, setInModule) {},
- fullScreenHandlersInstalled: false,
+ fullscreenHandlersInstalled: false,
lockPointer: undefined,
resizeCanvas: undefined,
- requestFullScreen: function(lockPointer, resizeCanvas, vrDevice) {
+ requestFullscreen: function(lockPointer, resizeCanvas, vrDevice) {
Browser.lockPointer = lockPointer;
Browser.resizeCanvas = resizeCanvas;
Browser.vrDevice = vrDevice;
@@ -325,24 +326,22 @@ var LibraryBrowser = {
if (typeof Browser.vrDevice === 'undefined') Browser.vrDevice = null;
var canvas = Module['canvas'];
- function fullScreenChange() {
- Browser.isFullScreen = false;
+ function fullscreenChange() {
+ Browser.isFullscreen = false;
var canvasContainer = canvas.parentNode;
- if ((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
- document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
- document['fullScreenElement'] || document['fullscreenElement'] ||
- document['msFullScreenElement'] || document['msFullscreenElement'] ||
+ if ((document['fullscreenElement'] || document['mozFullScreenElement'] ||
+ document['msFullscreenElement'] || document['webkitFullscreenElement'] ||
document['webkitCurrentFullScreenElement']) === canvasContainer) {
- canvas.cancelFullScreen = document['cancelFullScreen'] ||
- document['mozCancelFullScreen'] ||
- document['webkitCancelFullScreen'] ||
- document['msExitFullscreen'] ||
- document['exitFullscreen'] ||
- function() {};
- canvas.cancelFullScreen = canvas.cancelFullScreen.bind(document);
+ canvas.exitFullscreen = document['exitFullscreen'] ||
+ document['cancelFullScreen'] ||
+ document['mozCancelFullScreen'] ||
+ document['msExitFullscreen'] ||
+ document['webkitCancelFullScreen'] ||
+ function() {};
+ canvas.exitFullscreen = canvas.exitFullscreen.bind(document);
if (Browser.lockPointer) canvas.requestPointerLock();
- Browser.isFullScreen = true;
- if (Browser.resizeCanvas) Browser.setFullScreenCanvasSize();
+ Browser.isFullscreen = true;
+ if (Browser.resizeCanvas) Browser.setFullscreenCanvasSize();
} else {
// remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
@@ -351,16 +350,17 @@ var LibraryBrowser = {
if (Browser.resizeCanvas) Browser.setWindowedCanvasSize();
}
- if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen);
+ if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullscreen);
+ if (Module['onFullscreen']) Module['onFullscreen'](Browser.isFullscreen);
Browser.updateCanvasDimensions(canvas);
}
- if (!Browser.fullScreenHandlersInstalled) {
- Browser.fullScreenHandlersInstalled = true;
- document.addEventListener('fullscreenchange', fullScreenChange, false);
- document.addEventListener('mozfullscreenchange', fullScreenChange, false);
- document.addEventListener('webkitfullscreenchange', fullScreenChange, false);
- document.addEventListener('MSFullscreenChange', fullScreenChange, false);
+ if (!Browser.fullscreenHandlersInstalled) {
+ Browser.fullscreenHandlersInstalled = true;
+ document.addEventListener('fullscreenchange', fullscreenChange, false);
+ document.addEventListener('mozfullscreenchange', fullscreenChange, false);
+ document.addEventListener('webkitfullscreenchange', fullscreenChange, false);
+ document.addEventListener('MSFullscreenChange', fullscreenChange, false);
}
// create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root
@@ -369,19 +369,27 @@ var LibraryBrowser = {
canvasContainer.appendChild(canvas);
// use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
- canvasContainer.requestFullScreen = canvasContainer['requestFullScreen'] ||
+ canvasContainer.requestFullscreen = canvasContainer['requestFullscreen'] ||
canvasContainer['mozRequestFullScreen'] ||
canvasContainer['msRequestFullscreen'] ||
- (canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null) ||
- (canvasContainer['webkitRequestFullscreen'] ? function() { canvasContainer['webkitRequestFullscreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null);
+ (canvasContainer['webkitRequestFullscreen'] ? function() { canvasContainer['webkitRequestFullscreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null) ||
+ (canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null);
if (vrDevice) {
- canvasContainer.requestFullScreen({ vrDisplay: vrDevice });
+ canvasContainer.requestFullscreen({ vrDisplay: vrDevice });
} else {
- canvasContainer.requestFullScreen();
+ canvasContainer.requestFullscreen();
}
},
+ requestFullScreen: function(lockPointer, resizeCanvas, vrDevice) {
+ Module.printErr('Browser.requestFullScreen() is deprecated. Please call Browser.requestFullscreen instead.');
+ Browser.requestFullScreen = function(lockPointer, resizeCanvas, vrDevice) {
+ return Browser.requestFullscreen(lockPointer, resizeCanvas, vrDevice);
+ }
+ return Browser.requestFullscreen(lockPointer, resizeCanvas, vrDevice);
+ },
+
nextRAF: 0,
fakeRequestAnimationFrame: function(func) {
@@ -653,7 +661,7 @@ var LibraryBrowser = {
windowedWidth: 0,
windowedHeight: 0,
- setFullScreenCanvasSize: function() {
+ setFullscreenCanvasSize: function() {
// check if SDL is available
if (typeof SDL != "undefined") {
var flags = {{{ makeGetValue('SDL.screen+Runtime.QUANTUM_SIZE*0', '0', 'i32', 0, 1) }}};
@@ -690,10 +698,8 @@ var LibraryBrowser = {
h = Math.round(w / Module['forcedAspectRatio']);
}
}
- if (((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
- document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
- document['fullScreenElement'] || document['fullscreenElement'] ||
- document['msFullScreenElement'] || document['msFullscreenElement'] ||
+ if ((document['fullscreenElement'] || document['mozFullScreenElement'] ||
+ document['msFullscreenElement'] || document['webkitFullscreenElement'] ||
document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
var factor = Math.min(screen.width / w, screen.height / h);
w = Math.round(w * factor);
@@ -1281,7 +1287,7 @@ var LibraryBrowser = {
var canvas = Module['canvas'];
{{{ makeSetValue('width', '0', 'canvas.width', 'i32') }}};
{{{ makeSetValue('height', '0', 'canvas.height', 'i32') }}};
- {{{ makeSetValue('isFullscreen', '0', 'Browser.isFullScreen ? 1 : 0', 'i32') }}};
+ {{{ makeSetValue('isFullscreen', '0', 'Browser.isFullscreen ? 1 : 0', 'i32') }}};
},
emscripten_create_worker: function(url) {
diff --git a/src/library_glfw.js b/src/library_glfw.js
index 1888550823752..bb4f12c755ed8 100644
--- a/src/library_glfw.js
+++ b/src/library_glfw.js
@@ -507,7 +507,7 @@ var LibraryGLFW = {
var resizeNeeded = true;
// If the client is requestiong fullscreen mode
- if (document["fullScreen"] || document["mozFullScreen"] || document["webkitIsFullScreen"]) {
+ if (document["fullscreen"] || document["fullScreen"] || document["mozFullScreen"] || document["webkitIsFullScreen"]) {
GLFW.active.storedX = GLFW.active.x;
GLFW.active.storedY = GLFW.active.y;
GLFW.active.storedWidth = GLFW.active.width;
@@ -568,16 +568,23 @@ var LibraryGLFW = {
#endif
},
- requestFullScreen: function() {
+ requestFullscreen: function() {
var RFS = Module["canvas"]['requestFullscreen'] ||
- Module["canvas"]['requestFullScreen'] ||
Module["canvas"]['mozRequestFullScreen'] ||
Module["canvas"]['webkitRequestFullScreen'] ||
(function() {});
RFS.apply(Module["canvas"], []);
},
- cancelFullScreen: function() {
+ requestFullScreen: function() {
+ Module.printErr('GLFW.requestFullScreen() is deprecated. Please call GLFW.requestFullscreen instead.');
+ GLFW.requestFullScreen = function() {
+ return GLFW.requestFullscreen();
+ }
+ return GLFW.requestFullscreen();
+ },
+
+ exitFullscreen: function() {
var CFS = document['exitFullscreen'] ||
document['cancelFullScreen'] ||
document['mozCancelFullScreen'] ||
@@ -586,6 +593,14 @@ var LibraryGLFW = {
CFS.apply(document, []);
},
+ cancelFullScreen: function() {
+ Module.printErr('GLFW.cancelFullScreen() is deprecated. Please call GLFW.exitFullscreen instead.');
+ GLFW.cancelFullScreen = function() {
+ return GLFW.exitFullscreen();
+ }
+ return GLFW.exitFullscreen();
+ },
+
getTime: function() {
return _emscripten_get_now() / 1000;
},
@@ -777,9 +792,9 @@ var LibraryGLFW = {
if (GLFW.active.id == win.id) {
if (width == screen.width && height == screen.height) {
- GLFW.requestFullScreen();
+ GLFW.requestFullscreen();
} else {
- GLFW.cancelFullScreen();
+ GLFW.cancelFullscreen();
Browser.setCanvasSize(width, height);
win.width = width;
win.height = height;
@@ -809,7 +824,7 @@ var LibraryGLFW = {
if (width <= 0 || height <= 0) return 0;
if (monitor) {
- GLFW.requestFullScreen();
+ GLFW.requestFullscreen();
} else {
Browser.setCanvasSize(width, height);
}
diff --git a/src/library_glut.js b/src/library_glut.js
index 387d0fd70ccdb..de76ba8cd8fe4 100644
--- a/src/library_glut.js
+++ b/src/library_glut.js
@@ -249,19 +249,19 @@ var LibraryGLUT = {
// TODO add fullscreen API ala:
// http://johndyer.name/native-fullscreen-javascript-api-plus-jquery-plugin/
- onFullScreenEventChange: function(event) {
+ onFullscreenEventChange: function(event) {
var width;
var height;
- if (document["fullScreen"] || document["mozFullScreen"] || document["webkitIsFullScreen"]) {
+ if (document["fullscreen"] || document["fullScreen"] || document["mozFullScreen"] || document["webkitIsFullScreen"]) {
width = screen["width"];
height = screen["height"];
} else {
width = GLUT.windowWidth;
height = GLUT.windowHeight;
// TODO set position
- document.removeEventListener('fullscreenchange', GLUT.onFullScreenEventChange, true);
- document.removeEventListener('mozfullscreenchange', GLUT.onFullScreenEventChange, true);
- document.removeEventListener('webkitfullscreenchange', GLUT.onFullScreenEventChange, true);
+ document.removeEventListener('fullscreenchange', GLUT.onFullscreenEventChange, true);
+ document.removeEventListener('mozfullscreenchange', GLUT.onFullscreenEventChange, true);
+ document.removeEventListener('webkitfullscreenchange', GLUT.onFullscreenEventChange, true);
}
Browser.setCanvasSize(width, height);
/* Can't call _glutReshapeWindow as that requests cancelling fullscreen. */
@@ -272,22 +272,33 @@ var LibraryGLUT = {
_glutPostRedisplay();
},
+ requestFullscreen: function() {
+ Browser.requestFullscreen(/*lockPointer=*/false, /*resieCanvas=*/false);
+ },
+
requestFullScreen: function() {
- var RFS = Module["canvas"]['requestFullscreen'] ||
- Module["canvas"]['requestFullScreen'] ||
- Module["canvas"]['mozRequestFullScreen'] ||
- Module["canvas"]['webkitRequestFullScreen'] ||
- (function() {});
- RFS.apply(Module["canvas"], []);
+ Module.printErr('GLUT.requestFullScreen() is deprecated. Please call GLUT.requestFullscreen instead.');
+ GLUT.requestFullScreen = function() {
+ return GLUT.requestFullscreen();
+ }
+ return GLUT.requestFullscreen();
},
- cancelFullScreen: function() {
+ exitFullscreen: function() {
var CFS = document['exitFullscreen'] ||
document['cancelFullScreen'] ||
document['mozCancelFullScreen'] ||
document['webkitCancelFullScreen'] ||
- (function() {});
+ (function() {});
CFS.apply(document, []);
+ },
+
+ cancelFullScreen: function() {
+ Module.printErr('GLUT.cancelFullScreen() is deprecated. Please call GLUT.exitFullscreen instead.');
+ GLUT.cancelFullScreen = function() {
+ return GLUT.exitFullscreen();
+ }
+ return GLUT.exitFullscreen();
}
},
@@ -530,7 +541,7 @@ var LibraryGLUT = {
glutReshapeWindow__deps: ['$GLUT', 'glutPostRedisplay'],
glutReshapeWindow: function(width, height) {
- GLUT.cancelFullScreen();
+ GLUT.exitFullscreen();
Browser.setCanvasSize(width, height);
if (GLUT.reshapeFunc) {
Runtime.dynCall('vii', GLUT.reshapeFunc, [width, height]);
@@ -540,7 +551,7 @@ var LibraryGLUT = {
glutPositionWindow__deps: ['$GLUT', 'glutPostRedisplay'],
glutPositionWindow: function(x, y) {
- GLUT.cancelFullScreen();
+ GLUT.exitFullscreen();
/* TODO */
_glutPostRedisplay();
},
@@ -551,10 +562,10 @@ var LibraryGLUT = {
GLUT.windowY = 0; // TODO
GLUT.windowWidth = Module['canvas'].width;
GLUT.windowHeight = Module['canvas'].height;
- document.addEventListener('fullscreenchange', GLUT.onFullScreenEventChange, true);
- document.addEventListener('mozfullscreenchange', GLUT.onFullScreenEventChange, true);
- document.addEventListener('webkitfullscreenchange', GLUT.onFullScreenEventChange, true);
- GLUT.requestFullScreen();
+ document.addEventListener('fullscreenchange', GLUT.onFullscreenEventChange, true);
+ document.addEventListener('mozfullscreenchange', GLUT.onFullscreenEventChange, true);
+ document.addEventListener('webkitfullscreenchange', GLUT.onFullscreenEventChange, true);
+ GLUT.requestFullscreen();
},
glutInitDisplayMode: function(mode) {
diff --git a/src/library_html5.js b/src/library_html5.js
index 9b18f38fbbbf8..21143a7731c6e 100644
--- a/src/library_html5.js
+++ b/src/library_html5.js
@@ -546,7 +546,7 @@ var LibraryJSEvents = {
},
fullscreenEnabled: function() {
- return document.fullscreenEnabled || document.mozFullscreenEnabled || document.mozFullScreenEnabled || document.webkitFullscreenEnabled || document.msFullscreenEnabled;
+ return document.fullscreenEnabled || document.mozFullScreenEnabled || document.webkitFullscreenEnabled || document.msFullscreenEnabled;
},
fillFullscreenChangeEventData: function(eventStruct, e) {
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 6a8688111ecaa..4abfe5ab927d4 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -706,7 +706,7 @@ var LibrarySDL = {
SDL.canRequestFullscreen = true;
} else if (event.type === 'keyup' || event.type === 'mouseup') {
if (SDL.isRequestingFullscreen) {
- Module['requestFullScreen'](true, true);
+ Module['requestFullscreen'](/*lockPointer=*/true, /*resizeCanvas=*/true);
SDL.isRequestingFullscreen = false;
}
SDL.canRequestFullscreen = false;
@@ -1739,7 +1739,7 @@ var LibrarySDL = {
SDL_ShowCursor: function(toggle) {
switch (toggle) {
case 0: // SDL_DISABLE
- if (Browser.isFullScreen) { // only try to lock the pointer when in full screen mode
+ if (Browser.isFullscreen) { // only try to lock the pointer when in full screen mode
Module['canvas'].requestPointerLock();
return 0;
} else { // else return SDL_ENABLE to indicate the failure
@@ -2094,8 +2094,8 @@ var LibrarySDL = {
SDL_WM_GrabInput: function() {},
SDL_WM_ToggleFullScreen: function(surf) {
- if (Browser.isFullScreen) {
- Module['canvas'].cancelFullScreen();
+ if (Browser.isFullscreen) {
+ Module['canvas'].exitFullscreen();
return 1;
} else {
if (!SDL.canRequestFullscreen) {
@@ -3207,7 +3207,7 @@ var LibrarySDL = {
SDL_DestroyRenderer: function(renderer) {},
SDL_GetWindowFlags: function(x, y) {
- if (Browser.isFullScreen) {
+ if (Browser.isFullscreen) {
return 1;
}
@@ -3244,8 +3244,8 @@ var LibrarySDL = {
SDL_LogSetOutputFunction: function(callback, userdata) {},
SDL_SetWindowFullscreen: function(window, fullscreen) {
- if (Browser.isFullScreen) {
- Module['canvas'].cancelFullScreen();
+ if (Browser.isFullscreen) {
+ Module['canvas'].exitFullscreen();
return 1;
} else {
return 0;
diff --git a/src/shell.html b/src/shell.html
index 00b4237d24d39..14f3de108e793 100644
--- a/src/shell.html
+++ b/src/shell.html
@@ -1201,7 +1201,7 @@
Resize canvas
Lock/hide mouse pointer
-
diff --git a/src/shell_minimal.html b/src/shell_minimal.html
index e085f006ff9f8..0ed8df6b93fce 100644
--- a/src/shell_minimal.html
+++ b/src/shell_minimal.html
@@ -61,7 +61,7 @@
Resize canvas
Lock/hide mouse pointer
-
diff --git a/tests/canvas_style_proxy_shell.html b/tests/canvas_style_proxy_shell.html
index 1f795e5d1ee49..498c0025b13e3 100644
--- a/tests/canvas_style_proxy_shell.html
+++ b/tests/canvas_style_proxy_shell.html
@@ -61,7 +61,7 @@
Resize canvas
Lock/hide mouse pointer
-
diff --git a/tests/embind/shell.html b/tests/embind/shell.html
index e9f102838190e..ed9533453d262 100644
--- a/tests/embind/shell.html
+++ b/tests/embind/shell.html
@@ -25,7 +25,7 @@
Resize canvas
Lock/hide mouse pointer
-
diff --git a/tests/pthread/test_pthread_mandelbrot_shell.html b/tests/pthread/test_pthread_mandelbrot_shell.html
index 3bffad411531f..c3ba95b09e18d 100644
--- a/tests/pthread/test_pthread_mandelbrot_shell.html
+++ b/tests/pthread/test_pthread_mandelbrot_shell.html
@@ -1197,7 +1197,7 @@
Resize canvas
Lock/hide mouse pointer
-
diff --git a/tests/sdl_canvas_size.html b/tests/sdl_canvas_size.html
index 7cecd119e6716..f3bd3f060c020 100644
--- a/tests/sdl_canvas_size.html
+++ b/tests/sdl_canvas_size.html
@@ -28,7 +28,7 @@
Resize canvas
Lock/hide mouse pointer
-
diff --git a/tests/test_fflush.html b/tests/test_fflush.html
index 810e2518e067c..bd4f6b2adbfc3 100644
--- a/tests/test_fflush.html
+++ b/tests/test_fflush.html
@@ -61,7 +61,7 @@
Resize canvas
Lock/hide mouse pointer
-
diff --git a/tests/test_html5_fullscreen.html b/tests/test_html5_fullscreen.html
index 9fcdcfc487b26..145620756f85d 100644
--- a/tests/test_html5_fullscreen.html
+++ b/tests/test_html5_fullscreen.html
@@ -61,7 +61,7 @@
Resize canvas
Lock/hide mouse pointer
-
diff --git a/tests/webgl_destroy_context_shell.html b/tests/webgl_destroy_context_shell.html
index cc4604ac87cbb..d19b092e4d619 100644
--- a/tests/webgl_destroy_context_shell.html
+++ b/tests/webgl_destroy_context_shell.html
@@ -61,7 +61,7 @@
Resize canvas
Lock/hide mouse pointer
-
From b42774fe9f74b21e3ceb646b95bdc49a614553c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?=
Date: Tue, 24 May 2016 23:43:57 +0300
Subject: [PATCH 004/102] Behavior change for setting black canvas background.
Instead of Emscripten Browser.createContext() hardcoding to set the style,
allow specifying the style in the CSS domain, where it's more flexible and
pages can do how they please. Relates to #4350 and #4194 and #3406.
---
src/library_browser.js | 2 --
src/shell.html | 2 +-
src/shell_minimal.html | 2 +-
tests/canvas_style_proxy_shell.html | 2 +-
tests/embind/shell.html | 2 +-
tests/pthread/test_pthread_mandelbrot_shell.html | 2 +-
tests/sdl_canvas_size.html | 2 +-
tests/test_fflush.html | 2 +-
tests/test_html5_fullscreen.html | 2 +-
tests/webgl_destroy_context_shell.html | 2 +-
10 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/src/library_browser.js b/src/library_browser.js
index b610d133601d9..a452d71cff84d 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -291,8 +291,6 @@ var LibraryBrowser = {
if (contextHandle) {
ctx = GL.getContext(contextHandle).GLctx;
}
- // Set the background of the WebGL canvas to black
- canvas.style.backgroundColor = "black";
} else {
ctx = canvas.getContext('2d');
}
diff --git a/src/shell.html b/src/shell.html
index 00b4237d24d39..da3a93caafd7d 100644
--- a/src/shell.html
+++ b/src/shell.html
@@ -15,7 +15,7 @@
div.emscripten { text-align: center; }
div.emscripten_border { border: 1px solid black; }
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
- canvas.emscripten { border: 0px none; }
+ canvas.emscripten { border: 0px none; background-color: black; }
#emscripten_logo {
display: inline-block;
diff --git a/src/shell_minimal.html b/src/shell_minimal.html
index e085f006ff9f8..01c3a63e92fc2 100644
--- a/src/shell_minimal.html
+++ b/src/shell_minimal.html
@@ -10,7 +10,7 @@
div.emscripten { text-align: center; }
div.emscripten_border { border: 1px solid black; }
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
- canvas.emscripten { border: 0px none; }
+ canvas.emscripten { border: 0px none; background-color: black; }
.spinner {
height: 50px;
diff --git a/tests/canvas_style_proxy_shell.html b/tests/canvas_style_proxy_shell.html
index 1f795e5d1ee49..d5b805b6956ae 100644
--- a/tests/canvas_style_proxy_shell.html
+++ b/tests/canvas_style_proxy_shell.html
@@ -10,7 +10,7 @@
div.emscripten { text-align: center; }
div.emscripten_border { border: 1px solid black; }
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
- canvas.emscripten { border: 0px none; }
+ canvas.emscripten { border: 0px none; background-color: black; }
.spinner {
height: 50px;
diff --git a/tests/embind/shell.html b/tests/embind/shell.html
index e9f102838190e..f68408f40836a 100644
--- a/tests/embind/shell.html
+++ b/tests/embind/shell.html
@@ -10,7 +10,7 @@
div.emscripten { text-align: center; }
div.emscripten_border { border: 1px solid black; }
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
- canvas.emscripten { border: 0px none; }
+ canvas.emscripten { border: 0px none; background-color: black; }
diff --git a/tests/pthread/test_pthread_mandelbrot_shell.html b/tests/pthread/test_pthread_mandelbrot_shell.html
index 3bffad411531f..078970e182847 100644
--- a/tests/pthread/test_pthread_mandelbrot_shell.html
+++ b/tests/pthread/test_pthread_mandelbrot_shell.html
@@ -15,7 +15,7 @@
div.emscripten { text-align: center; }
div.emscripten_border { border: 1px solid black; background: black;}
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
- canvas.emscripten { border: 0px none; }
+ canvas.emscripten { border: 0px none; background-color: black; }
#emscripten_logo {
display: inline-block;
diff --git a/tests/sdl_canvas_size.html b/tests/sdl_canvas_size.html
index 7cecd119e6716..c60ceaa9a7a18 100644
--- a/tests/sdl_canvas_size.html
+++ b/tests/sdl_canvas_size.html
@@ -10,7 +10,7 @@
div.emscripten { text-align: center; }
div.emscripten_border { border: 1px solid black; }
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
- canvas.emscripten { border: 0px none; }
+ canvas.emscripten { border: 0px none; background-color: black; }
diff --git a/tests/test_fflush.html b/tests/test_fflush.html
index 810e2518e067c..704b9d2b7118e 100644
--- a/tests/test_fflush.html
+++ b/tests/test_fflush.html
@@ -10,7 +10,7 @@
div.emscripten { text-align: center; }
div.emscripten_border { border: 1px solid black; }
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
- canvas.emscripten { border: 0px none; }
+ canvas.emscripten { border: 0px none; background-color: black; }
.spinner {
height: 50px;
diff --git a/tests/test_html5_fullscreen.html b/tests/test_html5_fullscreen.html
index 9fcdcfc487b26..46ff8d03526cc 100644
--- a/tests/test_html5_fullscreen.html
+++ b/tests/test_html5_fullscreen.html
@@ -10,7 +10,7 @@
div.emscripten { text-align: center; }
div.emscripten_border { border: 1px solid black; }
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
- canvas.emscripten { border: 0px none; }
+ canvas.emscripten { border: 0px none; background-color: black; }
.spinner {
height: 50px;
diff --git a/tests/webgl_destroy_context_shell.html b/tests/webgl_destroy_context_shell.html
index cc4604ac87cbb..ce62d7893274e 100644
--- a/tests/webgl_destroy_context_shell.html
+++ b/tests/webgl_destroy_context_shell.html
@@ -10,7 +10,7 @@
div.emscripten { text-align: center; }
div.emscripten_border { border: 1px solid black; }
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
- canvas.emscripten { border: 0px none; }
+ canvas.emscripten { border: 0px none; background-color: black; }
.spinner {
height: 50px;
From f0935fc0708debc74c9662f6d6f0b16f25044d7a Mon Sep 17 00:00:00 2001
From: cynecx
Date: Wed, 25 May 2016 00:34:38 +0200
Subject: [PATCH 005/102] [SOCKFS] handleMessage: More robust handling of empty
ArrayBuffers
---
src/library_sockfs.js | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/library_sockfs.js b/src/library_sockfs.js
index 67a21c654fd9f..8c0dc54816e0b 100644
--- a/src/library_sockfs.js
+++ b/src/library_sockfs.js
@@ -280,6 +280,13 @@ mergeInto(LibraryManager.library, {
function handleMessage(data) {
assert(typeof data !== 'string' && data.byteLength !== undefined); // must receive an ArrayBuffer
+
+ // An empty ArrayBuffer will emit a pseudo disconnect event
+ // as recv/recvmsg will return zero which indicates that a socket
+ // has performed a shutdown although the connection has not been disconnected yet.
+ if(data.byteLength == 0) {
+ return;
+ }
data = new Uint8Array(data); // make a typed array view on the array buffer
#if SOCKET_DEBUG
From 8cfc20a1ba3bd2b99cd32f703616a8476e967fff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9gis=20F=C3=A9n=C3=A9on?=
Date: Sun, 22 May 2016 10:58:54 +0200
Subject: [PATCH 006/102] Use WebGL context version to construct GL_VERSION
This actually fixes the GL_VERSION string that must be of the form "OpenGL ES N.M ..." (OpenGL ES 2 and 3 specifications sections 6.1.5/6.1.6 resp.).
The WebGL version information is returned in the vendor-specific information field.
---
src/library_gl.js | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/library_gl.js b/src/library_gl.js
index 68423fead3afe..2ef8a56b18e63 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -715,9 +715,20 @@ var LibraryGL = {
switch(name_) {
case 0x1F00 /* GL_VENDOR */:
case 0x1F01 /* GL_RENDERER */:
- case 0x1F02 /* GL_VERSION */:
ret = allocate(intArrayFromString(GLctx.getParameter(name_)), 'i8', ALLOC_NORMAL);
break;
+ case 0x1F02 /* GL_VERSION */:
+ var glVersion = GLctx.getParameter(GLctx.VERSION);
+ // return GLES version string corresponding to the version of the WebGL context
+#if USE_WEBGL2
+ if (GLctx.canvas.GLctxObject.version >= 2) glVersion = 'OpenGL ES 3.0 (' + glVersion + ')';
+ else
+#endif
+ {
+ glVersion = 'OpenGL ES 2.0 (' + glVersion + ')';
+ }
+ ret = allocate(intArrayFromString(glVersion), 'i8', ALLOC_NORMAL);
+ break;
case 0x1F03 /* GL_EXTENSIONS */:
var exts = GLctx.getSupportedExtensions();
var gl_exts = [];
From acfc76d4d873c789083feb047dda832c231cde2c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?=
Date: Fri, 27 May 2016 12:21:50 +0300
Subject: [PATCH 007/102] Restore stray opening parenthesis '(' in
src/library_browser.js.
---
src/library_browser.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/library_browser.js b/src/library_browser.js
index 8dd66c86b3ae3..d761f73412091 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -696,7 +696,7 @@ var LibraryBrowser = {
h = Math.round(w / Module['forcedAspectRatio']);
}
}
- if ((document['fullscreenElement'] || document['mozFullScreenElement'] ||
+ if (((document['fullscreenElement'] || document['mozFullScreenElement'] ||
document['msFullscreenElement'] || document['webkitFullscreenElement'] ||
document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
var factor = Math.min(screen.width / w, screen.height / h);
From f1ab53a869c44440f0c58a2d10d1ed252448fa1d Mon Sep 17 00:00:00 2001
From: Maher Sallam
Date: Fri, 27 May 2016 19:06:21 +0200
Subject: [PATCH 008/102] Add support for llvm.sin.f(32|64) intrinsics (#4353)
---
src/library.js | 2 ++
tests/core/test_llvm_intrinsics.in | 4 ++++
tests/core/test_llvm_intrinsics.out | 4 +++-
3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/library.js b/src/library.js
index 7b21ac415b687..fabc1b0a0caa2 100644
--- a/src/library.js
+++ b/src/library.js
@@ -1356,6 +1356,8 @@ LibraryManager.library = {
llvm_log_f64: 'Math_log',
llvm_exp_f32: 'Math_exp',
llvm_exp_f64: 'Math_exp',
+ llvm_sin_f32: 'Math_sin',
+ llvm_sin_f64: 'Math_sin',
llvm_trunc_f32: 'Math_trunc',
llvm_trunc_f64: 'Math_trunc',
llvm_floor_f32: 'Math_floor',
diff --git a/tests/core/test_llvm_intrinsics.in b/tests/core/test_llvm_intrinsics.in
index 04f60ed6648eb..8b59e3376e29b 100644
--- a/tests/core/test_llvm_intrinsics.in
+++ b/tests/core/test_llvm_intrinsics.in
@@ -17,6 +17,8 @@ extern float llvm_trunc_f32(float x);
extern double llvm_trunc_f64(double x);
extern float llvm_floor_f32(float x);
extern double llvm_floor_f64(double x);
+extern float llvm_sin_f32(float x);
+extern double llvm_sin_f64(double x);
}
int main(void) {
@@ -52,6 +54,8 @@ int main(void) {
printf("%d\n", (int)llvm_trunc_f64(-12.42));
printf("%d\n", (int)llvm_floor_f32(27.665f));
printf("%d\n", (int)llvm_floor_f64(-8.95));
+ printf("%.1f\n", llvm_sin_f32(90.0f * 3.14/180));
+ printf("%.1f\n", llvm_sin_f64(270.0 * 3.14/180));
return 0;
}
diff --git a/tests/core/test_llvm_intrinsics.out b/tests/core/test_llvm_intrinsics.out
index 5a137f8765ec4..39fa3392ce155 100644
--- a/tests/core/test_llvm_intrinsics.out
+++ b/tests/core/test_llvm_intrinsics.out
@@ -13,4 +13,6 @@ c5,de,15,8a
18
-12
27
--9
\ No newline at end of file
+-9
+1.0
+-1.0
\ No newline at end of file
From 1dd425352ff922878355c728044725b5b93c882c Mon Sep 17 00:00:00 2001
From: Alon Zakai
Date: Fri, 27 May 2016 10:17:25 -0700
Subject: [PATCH 009/102] some comments on including and exporting library
elements
---
src/settings.js | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/settings.js b/src/settings.js
index 0bc325bf21985..b6c6cbafef619 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -305,10 +305,14 @@ var ASYNCIFY_WHITELIST = ['qsort', // Functions in this list are never conside
'__fwritex',
'MUSL_vfprintf'];
-var EXPORTED_RUNTIME_METHODS = [ // Methods that are exported on Module. By default we export quite a bit, you can reduce this list to lower your code size,
+var EXPORTED_RUNTIME_METHODS = [ // Runtime elements that are exported on Module. By default we export quite a bit, you can reduce this list to lower your code size,
// especially when closure is run (exporting prevents closure from eliminating code)
// Note that methods on this list are only exported if they are included (either automatically from linking, or due to being
// in DEFAULT_LIBRARY_FUNCS_TO_INCLUDE)
+ // Note that the name may be slightly misleading, as this
+ // is for any JS library element, and not just
+ // methods. For example, we export the Runtime object
+ // by having "Runtime" in this list.
'FS_createFolder',
'FS_createPath',
'FS_createDataFile',
@@ -404,13 +408,17 @@ var OPT_LEVEL = 0; // this will contain the optimization level (-Ox).
var DEBUG_LEVEL = 0; // this will contain the debug level (-gx). you should not modify it.
-// JS library functions (C functions implemented in JS)
+// JS library elements (C functions implemented in JS)
// that we include by default. If you want to make sure
// something is included by the JS compiler, add it here.
// For example, if you do not use some emscripten_*
// C API call from C, but you want to call it from JS,
// add it here (and in EXPORTED FUNCTIONS with prefix
// "_", if you use closure compiler).
+// Note that the name may be slightly misleading, as this
+// is for any JS library element, and not just
+// functions. For example, you can include the Browser
+// object by adding "$Browser" to this list.
var DEFAULT_LIBRARY_FUNCS_TO_INCLUDE = ['memcpy', 'memset', 'malloc', 'free'];
var LIBRARY_DEPS_TO_AUTOEXPORT = ['memcpy']; // This list is also used to determine
From 7f89c8f864e5d87e3786df6d733f75bc3013e100 Mon Sep 17 00:00:00 2001
From: Alon Zakai
Date: Fri, 27 May 2016 17:23:57 -0700
Subject: [PATCH 010/102] fix test_llvm_intrinsics
---
tests/core/test_llvm_intrinsics.out | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tests/core/test_llvm_intrinsics.out b/tests/core/test_llvm_intrinsics.out
index 39fa3392ce155..342c61ded7c30 100644
--- a/tests/core/test_llvm_intrinsics.out
+++ b/tests/core/test_llvm_intrinsics.out
@@ -13,6 +13,6 @@ c5,de,15,8a
18
-12
27
--9
-1.0
--1.0
\ No newline at end of file
+-9
+1.0
+-1.0
From fcb9cb5b4eb3676147d20a62445de118b6fe4727 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9gis=20F=C3=A9n=C3=A9on?=
Date: Sun, 29 May 2016 13:33:35 +0200
Subject: [PATCH 011/102] Add GLES3 parameters GL_MAJOR_VERSION and
GL_MINOR_VERSION to glGet
---
src/library_gl.js | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/library_gl.js b/src/library_gl.js
index 2ef8a56b18e63..56678d27cc0af 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -810,6 +810,14 @@ var LibraryGL = {
var exts = GLctx.getSupportedExtensions();
ret = 2*exts.length; // each extension is duplicated, first in unprefixed WebGL form, and then a second time with "GL_" prefix.
break;
+ case 0x821B: // GL_MAJOR_VERSION
+ case 0x821C: // GL_MINOR_VERSION
+ if (GLctx.canvas.GLctxObject.version < 2) {
+ GL.recordError(0x0500); // GL_INVALID_ENUM
+ return;
+ }
+ ret = name_ == 0x821B ? 3 : 0; // return version 3.0
+ break;
#endif
}
From 2fa1f311b2e6307e161afab60a918b9fd045aca3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?=
Date: Mon, 30 May 2016 23:59:26 +0300
Subject: [PATCH 012/102] Make -s USE_PTHREADS=1 compatible with
--proxy-to-worker mode.
---
emcc.py | 3 ---
src/jsifier.js | 2 +-
src/library_pthread.js | 20 ++++++++-----------
src/preamble.js | 5 +++++
src/proxyClient.js | 1 +
src/proxyWorker.js | 23 +++++++++++++++++++---
tests/pthread/test_pthread_malloc_free.cpp | 1 +
tests/test_browser.py | 3 ++-
8 files changed, 38 insertions(+), 20 deletions(-)
diff --git a/emcc.py b/emcc.py
index 5cf9ee59d7995..c26feb7c06823 100755
--- a/emcc.py
+++ b/emcc.py
@@ -1124,9 +1124,6 @@ def check(input_file):
js_libraries.append(shared.path_from_root('src', 'library_pthread_stub.js'))
if shared.Settings.USE_PTHREADS:
- if shared.Settings.PROXY_TO_WORKER:
- logging.error('-s PROXY_TO_WORKER=1 is not yet supported with -s USE_PTHREADS=1!')
- exit(1)
if shared.Settings.LINKABLE:
logging.error('-s LINKABLE=1 is not supported with -s USE_PTHREADS=1!')
exit(1)
diff --git a/src/jsifier.js b/src/jsifier.js
index 281ac5df3e76c..4d6fcf36a9539 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -418,7 +418,7 @@ function JSify(data, functionsOnly) {
if (PROXY_TO_WORKER) {
print('if (ENVIRONMENT_IS_WORKER) {\n');
print(read('webGLWorker.js'));
- print(read('proxyWorker.js'));
+ print(processMacros(preprocess(read('proxyWorker.js'), 'proxyWorker.js')));
print('}');
}
if (DETERMINISTIC) {
diff --git a/src/library_pthread.js b/src/library_pthread.js
index 7888d2bdcbd62..b28fb8947efa0 100644
--- a/src/library_pthread.js
+++ b/src/library_pthread.js
@@ -292,7 +292,7 @@ var LibraryPThread = {
},
_kill_thread: function(pthread_ptr) {
- if (ENVIRONMENT_IS_WORKER || ENVIRONMENT_IS_PTHREAD) throw 'Internal Error! _kill_thread() can only ever be called from main JS thread!';
+ if (ENVIRONMENT_IS_PTHREAD) throw 'Internal Error! _kill_thread() can only ever be called from main application thread!';
if (!pthread_ptr) throw 'Internal Error! Null pthread_ptr in _kill_thread!';
{{{ makeSetValue('pthread_ptr', C_STRUCTS.pthread.self, 0, 'i32') }}};
var pthread = PThread.pthreads[pthread_ptr];
@@ -305,7 +305,7 @@ var LibraryPThread = {
},
_cleanup_thread: function(pthread_ptr) {
- if (ENVIRONMENT_IS_WORKER || ENVIRONMENT_IS_PTHREAD) throw 'Internal Error! _cleanup_thread() can only ever be called from main JS thread!';
+ if (ENVIRONMENT_IS_PTHREAD) throw 'Internal Error! _cleanup_thread() can only ever be called from main application thread!';
if (!pthread_ptr) throw 'Internal Error! Null pthread_ptr in _cleanup_thread!';
{{{ makeSetValue('pthread_ptr', C_STRUCTS.pthread.self, 0, 'i32') }}};
var pthread = PThread.pthreads[pthread_ptr];
@@ -317,14 +317,14 @@ var LibraryPThread = {
},
_cancel_thread: function(pthread_ptr) {
- if (ENVIRONMENT_IS_WORKER || ENVIRONMENT_IS_PTHREAD) throw 'Internal Error! _cancel_thread() can only ever be called from main JS thread!';
+ if (ENVIRONMENT_IS_PTHREAD) throw 'Internal Error! _cancel_thread() can only ever be called from main application thread!';
if (!pthread_ptr) throw 'Internal Error! Null pthread_ptr in _cancel_thread!';
var pthread = PThread.pthreads[pthread_ptr];
pthread.worker.postMessage({ cmd: 'cancel' });
},
_spawn_thread: function(threadParams) {
- if (ENVIRONMENT_IS_WORKER || ENVIRONMENT_IS_PTHREAD) throw 'Internal Error! _spawn_thread() can only ever be called from main JS thread!';
+ if (ENVIRONMENT_IS_PTHREAD) throw 'Internal Error! _spawn_thread() can only ever be called from main application thread!';
var worker = PThread.getNewWorker();
if (worker.pthread !== undefined) throw 'Internal error!';
@@ -406,11 +406,7 @@ var LibraryPThread = {
pthread_create__deps: ['_spawn_thread', 'pthread_getschedparam', 'pthread_self'],
pthread_create: function(pthread_ptr, attr, start_routine, arg) {
- // When running in PROXY_TO_WORKER=1 mode, the pthread creation needs to be forwarded to the main browser thread, and not the main C runtime thread,
- // so the following is valid only when in non-proxy-to-worker mode.
-#if !PROXY_TO_WORKER
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_sync_run_in_main_thread_4({{{ cDefine('EM_PROXIED_PTHREAD_CREATE') }}}, pthread_ptr, attr, start_routine, arg);
-#endif
if (typeof SharedArrayBuffer === 'undefined') {
Module['printErr']('Current environment does not support SharedArrayBuffer, pthreads are not available!');
@@ -475,7 +471,7 @@ var LibraryPThread = {
arg: arg,
};
- if (ENVIRONMENT_IS_WORKER) {
+ if (ENVIRONMENT_IS_PTHREAD) {
// The prepopulated pool of web workers that can host pthreads is stored in the main JS thread. Therefore if a
// pthread is attempting to spawn a new thread, the thread creation must be deferred to the main JS thread.
threadParams.cmd = 'spawnThread';
@@ -532,7 +528,7 @@ var LibraryPThread = {
if (status) {{{ makeSetValue('status', 0, 'threadExitCode', 'i32') }}};
Atomics.store(HEAPU32, (thread + {{{ C_STRUCTS.pthread.detached }}} ) >> 2, 1); // Mark the thread as detached.
- if (!ENVIRONMENT_IS_WORKER) __cleanup_thread(thread);
+ if (!ENVIRONMENT_IS_PTHREAD) __cleanup_thread(thread);
else postMessage({ cmd: 'cleanupThread', thread: thread});
return 0;
}
@@ -564,7 +560,7 @@ var LibraryPThread = {
return ERRNO_CODES.ESRCH;
}
if (signal != 0) {
- if (!ENVIRONMENT_IS_WORKER) __kill_thread(thread);
+ if (!ENVIRONMENT_IS_PTHREAD) __kill_thread(thread);
else postMessage({ cmd: 'killThread', thread: thread});
}
return 0;
@@ -586,7 +582,7 @@ var LibraryPThread = {
return ERRNO_CODES.ESRCH;
}
Atomics.compareExchange(HEAPU32, (thread + {{{ C_STRUCTS.pthread.threadStatus }}} ) >> 2, 0, 2); // Signal the thread that it needs to cancel itself.
- if (!ENVIRONMENT_IS_WORKER) __cancel_thread(thread);
+ if (!ENVIRONMENT_IS_PTHREAD) __cancel_thread(thread);
else postMessage({ cmd: 'cancelThread', thread: thread});
return 0;
},
diff --git a/src/preamble.js b/src/preamble.js
index a8525a6bf51a0..e0fb49c5a9070 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -1721,6 +1721,11 @@ function getUniqueRunDependency(id) {
}
function addRunDependency(id) {
+#if USE_PTHREADS
+ // We should never get here in pthreads (could no-op this out if called in pthreads, but that might indicate a bug in caller side,
+ // so good to be very explicit)
+ assert(!ENVIRONMENT_IS_PTHREAD);
+#endif
runDependencies++;
if (Module['monitorRunDependencies']) {
Module['monitorRunDependencies'](runDependencies);
diff --git a/src/proxyClient.js b/src/proxyClient.js
index 23e25d493cf56..8210c47b88536 100644
--- a/src/proxyClient.js
+++ b/src/proxyClient.js
@@ -108,6 +108,7 @@ setTimeout(function() {
height: Module.canvas.height,
boundingClientRect: cloneObject(Module.canvas.getBoundingClientRect()),
URL: document.URL,
+ currentScriptUrl: '{{{ filename }}}.js',
preMain: true });
}, 0); // delay til next frame, to make sure html is ready
diff --git a/src/proxyWorker.js b/src/proxyWorker.js
index baf7bfcf93c10..06ab0c9bdf3b4 100644
--- a/src/proxyWorker.js
+++ b/src/proxyWorker.js
@@ -370,8 +370,14 @@ Module['postMainLoop'] = function() {
// Wait to start running until we receive some info from the client
-addRunDependency('gl-prefetch');
-addRunDependency('worker-init');
+#if USE_PTHREADS
+if (!ENVIRONMENT_IS_PTHREAD) {
+#endif
+ addRunDependency('gl-prefetch');
+ addRunDependency('worker-init');
+#if USE_PTHREADS
+}
+#endif
// buffer messages until the program starts to run
@@ -391,7 +397,7 @@ function messageResender() {
}
}
-onmessage = function onmessage(message) {
+function onMessageFromMainEmscriptenThread(message) {
if (!calledMain && !message.data.preMain) {
if (!messageBuffer) {
messageBuffer = [];
@@ -460,6 +466,9 @@ onmessage = function onmessage(message) {
screen.height = Module.canvas.height_ = message.data.height;
Module.canvas.boundingClientRect = message.data.boundingClientRect;
document.URL = message.data.URL;
+#if USE_PTHREADS
+ currentScriptUrl = message.data.currentScriptUrl;
+#endif
window.fireEvent({ type: 'load' });
removeRunDependency('worker-init');
break;
@@ -476,6 +485,14 @@ onmessage = function onmessage(message) {
}
};
+#if USE_PTHREADS
+if (!ENVIRONMENT_IS_PTHREAD) {
+#endif
+ onmessage = onMessageFromMainEmscriptenThread;
+#if USE_PTHREADS
+}
+#endif
+
function postCustomMessage(data) {
postMessage({ target: 'custom', userData: data });
}
diff --git a/tests/pthread/test_pthread_malloc_free.cpp b/tests/pthread/test_pthread_malloc_free.cpp
index e86d2efe7ff8d..0fdb75c6564c2 100644
--- a/tests/pthread/test_pthread_malloc_free.cpp
+++ b/tests/pthread/test_pthread_malloc_free.cpp
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
#include
#define NUM_BLOCKS_TO_ALLOC 50000
diff --git a/tests/test_browser.py b/tests/test_browser.py
index 173f56c8f468c..e5a4a5964033f 100644
--- a/tests/test_browser.py
+++ b/tests/test_browser.py
@@ -2877,7 +2877,8 @@ def test_pthread_create(self):
# Test that a pthread can spawn another pthread of its own.
def test_pthread_create_pthread(self):
- self.btest(path_from_root('tests', 'pthread', 'test_pthread_create_pthread.cpp'), expected='1', args=['-O3', '-s', 'USE_PTHREADS=2', '--separate-asm', '-s', 'PTHREAD_POOL_SIZE=2', '-s', 'NO_EXIT_RUNTIME=1'], timeout=30)
+ for opt in [['-s', 'USE_PTHREADS=2', '--separate-asm'], ['-s', 'USE_PTHREADS=1', '--proxy-to-worker']]:
+ self.btest(path_from_root('tests', 'pthread', 'test_pthread_create_pthread.cpp'), expected='1', args=opt + ['-O3', '-s', 'PTHREAD_POOL_SIZE=2', '-s', 'NO_EXIT_RUNTIME=1'], timeout=30)
# Test another case of pthreads spawning pthreads, but this time the callers immediately join on the threads they created.
def test_pthread_nested_spawns(self):
From 0941e0187b4ae203a7d93d45b6aaf58f737b9614 Mon Sep 17 00:00:00 2001
From: Piotr Paczkowski
Date: Tue, 31 May 2016 21:26:30 +0200
Subject: [PATCH 013/102] Handle missing connection to IndexedDB (#4371)
Fixes problem when `req` is null.
---
src/library_idbfs.js | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/library_idbfs.js b/src/library_idbfs.js
index afb4d60609465..3b8970d577338 100644
--- a/src/library_idbfs.js
+++ b/src/library_idbfs.js
@@ -42,6 +42,9 @@ mergeInto(LibraryManager.library, {
} catch (e) {
return callback(e);
}
+ if (!req) {
+ return callback("Unable to connect to IndexedDB");
+ }
req.onupgradeneeded = function(e) {
var db = e.target.result;
var transaction = e.target.transaction;
From cc1464db1edb032815b681c4b96a647a0c1dc37a Mon Sep 17 00:00:00 2001
From: Alon Zakai
Date: Tue, 31 May 2016 13:59:36 -0700
Subject: [PATCH 014/102] wasm libc does not work with
MAIN_MODULE/INCLUDE_FULL_LIBRARY yet
---
emcc.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/emcc.py b/emcc.py
index 5cf9ee59d7995..d2979129141b1 100755
--- a/emcc.py
+++ b/emcc.py
@@ -1154,6 +1154,7 @@ def check(input_file):
assert not shared.Settings.SPLIT_MEMORY, 'WebAssembly does not support split memory'
if not shared.Settings.BINARYEN_METHOD:
shared.Settings.BINARYEN_METHOD = 'native-wasm,interpret-binary'
+ assert not shared.Settings.INCLUDE_FULL_LIBRARY, 'The WebAssembly libc overlaps with JS libs, so INCLUDE_FULL_LIBRARY does not just work (FIXME)'
if shared.Settings.CYBERDWARF:
newargs.append('-g')
From 25706c94cffc957f72fd7d4a902972be76734fe5 Mon Sep 17 00:00:00 2001
From: Alon Zakai
Date: Tue, 31 May 2016 14:00:04 -0700
Subject: [PATCH 015/102] add non-default-running binaryen modes, and disable
some tests for them that are not relevant
---
tests/test_core.py | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tests/test_core.py b/tests/test_core.py
index e93c16f9d194c..1be998be9214f 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -821,7 +821,7 @@ def test_math_lgamma(self):
self.do_run_from_file(src, output)
- if Settings.ALLOW_MEMORY_GROWTH == 0:
+ if Settings.ALLOW_MEMORY_GROWTH == 0 and not self.is_wasm():
print 'main module'
Settings.MAIN_MODULE = 1
self.do_run_from_file(src, output)
@@ -5470,7 +5470,7 @@ def test_atomic_cxx(self):
Building.COMPILER_TEST_OPTS += ['-std=c++11']
self.do_run_from_file(src, output)
- if Settings.ALLOW_MEMORY_GROWTH == 0:
+ if Settings.ALLOW_MEMORY_GROWTH == 0 and not self.is_wasm():
print 'main module'
Settings.MAIN_MODULE = 1
self.do_run_from_file(src, output)
@@ -8064,10 +8064,10 @@ def setUp(self):
asm2g = make_run("asm2g", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "ASSERTIONS=1", "-s", "SAFE_HEAP=1"])
asm2i = make_run("asm2i", compiler=CLANG, emcc_args=["-O2", '-s', 'EMTERPRETIFY=1'])
#asm2m = make_run("asm2m", compiler=CLANG, emcc_args=["-O2", "--memory-init-file", "0", "-s", "MEM_INIT_METHOD=2", "-s", "ASSERTIONS=1"])
-#binaryen0 = make_run("binaryen", compiler=CLANG, emcc_args=['-O0', '-s', 'BINARYEN=1', '-s', 'BINARYEN_METHOD="interpret-s-expr"'])
-#binaryen1 = make_run("binaryen", compiler=CLANG, emcc_args=['-O1', '-s', 'BINARYEN=1', '-s', 'BINARYEN_METHOD="interpret-s-expr"'])
-#binaryen2 = make_run("binaryen", compiler=CLANG, emcc_args=['-O2', '-s', 'BINARYEN=1', '-s', 'BINARYEN_METHOD="interpret-s-expr"'])
-#binaryen3 = make_run("binaryen", compiler=CLANG, emcc_args=['-O3', '-s', 'BINARYEN=1', '-s', 'BINARYEN_METHOD="interpret-s-expr"'])
+binaryen0 = make_run("binaryen0", compiler=CLANG, emcc_args=['-O0', '-s', 'BINARYEN=1', '-s', 'BINARYEN_METHOD="interpret-binary"'])
+binaryen1 = make_run("binaryen1", compiler=CLANG, emcc_args=['-O1', '-s', 'BINARYEN=1', '-s', 'BINARYEN_METHOD="interpret-binary"'])
+binaryen2 = make_run("binaryen2", compiler=CLANG, emcc_args=['-O2', '-s', 'BINARYEN=1', '-s', 'BINARYEN_METHOD="interpret-binary"'])
+binaryen3 = make_run("binaryen3", compiler=CLANG, emcc_args=['-O3', '-s', 'BINARYEN=1', '-s', 'BINARYEN_METHOD="interpret-binary"'])
#normalyen = make_run("normalyen", compiler=CLANG, emcc_args=['-O0', '-s', 'GLOBAL_BASE=1024']) # useful comparison to binaryen
#spidaryen = make_run("binaryen", compiler=CLANG, emcc_args=['-O0', '-s', 'BINARYEN=1', '-s', 'BINARYEN_SCRIPTS="spidermonkify.py"'])
From c27fda7e4f5ca3790b49f1c1a2a39fff9d5aff6d Mon Sep 17 00:00:00 2001
From: Alon Zakai
Date: Tue, 31 May 2016 14:16:30 -0700
Subject: [PATCH 016/102] if BINARYEN_ROOT is set in config file, it overrides,
even when not linking with ports
---
emcc.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/emcc.py b/emcc.py
index d2979129141b1..b2f591cfbe535 100755
--- a/emcc.py
+++ b/emcc.py
@@ -1155,6 +1155,12 @@ def check(input_file):
if not shared.Settings.BINARYEN_METHOD:
shared.Settings.BINARYEN_METHOD = 'native-wasm,interpret-binary'
assert not shared.Settings.INCLUDE_FULL_LIBRARY, 'The WebAssembly libc overlaps with JS libs, so INCLUDE_FULL_LIBRARY does not just work (FIXME)'
+ # if root was not specified in -s, it might be fixed in ~/.emscripten, copy from there
+ if not shared.Settings.BINARYEN_ROOT:
+ try:
+ shared.Settings.BINARYEN_ROOT = shared.BINARYEN_ROOT
+ except:
+ pass
if shared.Settings.CYBERDWARF:
newargs.append('-g')
From 7df4e6a43a3a59b668e7a35e51322ad01478c567 Mon Sep 17 00:00:00 2001
From: Alon Zakai
Date: Tue, 31 May 2016 15:36:20 -0700
Subject: [PATCH 017/102] more binaryen test modifications
---
tests/test_core.py | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/tests/test_core.py b/tests/test_core.py
index 1be998be9214f..c74f9b6bd528e 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -1261,7 +1261,7 @@ def test_exceptions(self):
Settings.EXCEPTION_DEBUG = 1
Settings.DISABLE_EXCEPTION_CATCHING = 0
- if '-O2' in self.emcc_args:
+ if '-O2' in self.emcc_args and not self.is_wasm():
self.emcc_args += ['--closure', '1'] # Use closure here for some additional coverage
src = '''
@@ -1418,13 +1418,14 @@ def test_exceptions_white_list(self):
disabled_size = len(open('src.cpp.o.js').read())
shutil.copyfile('src.cpp.o.js', 'disabled.js')
- print size, empty_size, fake_size, disabled_size
+ if not self.is_wasm():
+ print size, empty_size, fake_size, disabled_size
- assert size - empty_size > 0.0025*size, [empty_size, size] # big change when we disable entirely
- assert size - fake_size > 0.0025*size, [fake_size, size]
- assert abs(empty_size - fake_size) < 0.007*size, [empty_size, fake_size]
- assert empty_size - disabled_size < 0.007*size, [empty_size, disabled_size] # full disable removes a little bit more
- assert fake_size - disabled_size < 0.007*size, [disabled_size, fake_size]
+ assert size - empty_size > 0.0025*size, [empty_size, size] # big change when we disable entirely
+ assert size - fake_size > 0.0025*size, [fake_size, size]
+ assert abs(empty_size - fake_size) < 0.007*size, [empty_size, fake_size]
+ assert empty_size - disabled_size < 0.007*size, [empty_size, disabled_size] # full disable removes a little bit more
+ assert fake_size - disabled_size < 0.007*size, [disabled_size, fake_size]
def test_exceptions_white_list_2(self):
Settings.DISABLE_EXCEPTION_CATCHING = 2
@@ -4853,10 +4854,10 @@ def test_langinfo(self):
def test_files(self):
self.banned_js_engines = [SPIDERMONKEY_ENGINE] # closure can generate variables called 'gc', which pick up js shell stuff
- if '-O2' in self.emcc_args:
+ if '-O2' in self.emcc_args and not self.is_wasm():
self.emcc_args += ['--closure', '1'] # Use closure here, to test we don't break FS stuff
self.emcc_args = filter(lambda x: x != '-g', self.emcc_args) # ensure we test --closure 1 --memory-init-file 1 (-g would disable closure)
- elif '-O3' in self.emcc_args:
+ elif '-O3' in self.emcc_args and not self.is_wasm():
print 'closure 2'
self.emcc_args += ['--closure', '2'] # Use closure 2 here for some additional coverage
@@ -4893,8 +4894,12 @@ def process(filename):
print mode
self.emcc_args = orig_args + mode
try_delete(mem_file)
+
+ def clean(out, err):
+ return '\n'.join(filter(lambda line: 'binaryen' not in line, (out + err).split('\n')))
+
self.do_run(src, map(lambda x: x if 'SYSCALL_DEBUG=1' not in mode else ('syscall! 146,SYS_writev' if self.run_name == 'default' else 'syscall! 146'), ('size: 7\ndata: 100,-56,50,25,10,77,123\nloop: 100 -56 50 25 10 77 123 \ninput:hi there!\ntexto\n$\n5 : 10,30,20,11,88\nother=some data.\nseeked=me da.\nseeked=ata.\nseeked=ta.\nfscanfed: 10 - hello\n5 bytes to dev/null: 5\nok.\ntexte\n', 'size: 7\ndata: 100,-56,50,25,10,77,123\nloop: 100 -56 50 25 10 77 123 \ninput:hi there!\ntexto\ntexte\n$\n5 : 10,30,20,11,88\nother=some data.\nseeked=me da.\nseeked=ata.\nseeked=ta.\nfscanfed: 10 - hello\n5 bytes to dev/null: 5\nok.\n')),
- post_build=post, extra_emscripten_args=['-H', 'libc/fcntl.h'])
+ post_build=post, extra_emscripten_args=['-H', 'libc/fcntl.h'], output_nicerizer=clean)
if self.uses_memory_init_file():
assert os.path.exists(mem_file)
@@ -4926,7 +4931,7 @@ def process(filename):
}
'''
def clean(out, err):
- return '\n'.join(filter(lambda line: 'warning' not in line, (out + err).split('\n')))
+ return '\n'.join(filter(lambda line: 'warning' not in line and 'binaryen' not in line, (out + err).split('\n')))
self.do_run(src, ('got: 35\ngot: 45\ngot: 25\ngot: 15\n \nisatty? 0,0,1\n', 'got: 35\ngot: 45\ngot: 25\ngot: 15\nisatty? 0,0,1\n', 'isatty? 0,0,1\ngot: 35\ngot: 45\ngot: 25\ngot: 15\n'), post_build=post, output_nicerizer=clean)
def test_mount(self):
From eb1ac1a1ec7700da56d33d5749d9b8155619268d Mon Sep 17 00:00:00 2001
From: Alon Zakai
Date: Tue, 31 May 2016 15:44:15 -0700
Subject: [PATCH 018/102] disable more closure with binaryen, and add a warning
---
emcc.py | 2 ++
tests/test_core.py | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/emcc.py b/emcc.py
index b2f591cfbe535..395b015535cb9 100755
--- a/emcc.py
+++ b/emcc.py
@@ -1161,6 +1161,8 @@ def check(input_file):
shared.Settings.BINARYEN_ROOT = shared.BINARYEN_ROOT
except:
pass
+ if use_closure_compiler:
+ logging.warning('closure compiler is known to have issues with binaryen (FIXME)')
if shared.Settings.CYBERDWARF:
newargs.append('-g')
diff --git a/tests/test_core.py b/tests/test_core.py
index c74f9b6bd528e..cd02a2adb39a0 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -7163,7 +7163,7 @@ def process(filename):
'''
# XXX disable due to possible v8 bug -- self.do_run(src, '*166*\n*ok*', post_build=post)
- if '-O2' in self.emcc_args and 'ASM_JS=0' not in self.emcc_args: # without asm, closure minifies Math.imul badly
+ if '-O2' in self.emcc_args and 'ASM_JS=0' not in self.emcc_args and not self.is_wasm(): # without asm, closure minifies Math.imul badly
self.emcc_args += ['--closure', '1'] # Use closure here, to test we export things right
# Way 2: use CppHeaderParser
From d046dadc7925f7cf5886a04897c8144f058e20d0 Mon Sep 17 00:00:00 2001
From: Alon Zakai
Date: Tue, 31 May 2016 16:48:57 -0700
Subject: [PATCH 019/102] set a time limit on the stack overflow check in
test_webidl
---
tests/webidl/post.js | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tests/webidl/post.js b/tests/webidl/post.js
index c7b99a23b8e44..ecb8bfebc09a4 100644
--- a/tests/webidl/post.js
+++ b/tests/webidl/post.js
@@ -229,9 +229,12 @@ try {
// Check for overflowing the stack
+var before = Date.now();
+
for (var i = 0; i < 1000000; i++) {
var temp = new TheModule.StringUser('abc', 1);
TheModule.destroy(temp);
+ if (Date.now() - before >= 1000) break;
}
//
From 925cb0c9f117ac8fab3d34a89549cc22f0d7c5c3 Mon Sep 17 00:00:00 2001
From: Alon Zakai
Date: Tue, 31 May 2016 16:52:02 -0700
Subject: [PATCH 020/102] avoid closure in wasm on zlib
---
tests/test_core.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/test_core.py b/tests/test_core.py
index cd02a2adb39a0..0829183c1967c 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -6158,7 +6158,7 @@ def test_sqlite(self):
force_c=True)
def test_zlib(self):
- if '-O2' in self.emcc_args and 'ASM_JS=0' not in self.emcc_args: # without asm, closure minifies Math.imul badly
+ if '-O2' in self.emcc_args and 'ASM_JS=0' not in self.emcc_args and not self.is_wasm(): # without asm, closure minifies Math.imul badly
self.emcc_args += ['--closure', '1'] # Use closure here for some additional coverage
assert 'asm2g' in test_modes
From ec6dcf56532a2517ff344efbc6c4473cc8d02b24 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?=
Date: Wed, 1 Jun 2016 10:56:00 +0300
Subject: [PATCH 021/102] Document tool/file_packager.py --exclude command line
option.
---
tools/file_packager.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/file_packager.py b/tools/file_packager.py
index 4c5a7501df23e..42ea9aef5e73c 100644
--- a/tools/file_packager.py
+++ b/tools/file_packager.py
@@ -16,6 +16,9 @@
--preload ,
--embed See emcc --help for more details on those options.
+ --exclude E [F..] Specifies filename pattern matches to use for excluding given files from being added to the package.
+ See https://docs.python.org/2/library/fnmatch.html for syntax.
+
--no-closure In general, the file packager emits closure compiler-compatible code, which requires an eval().
With this flag passed, we avoid emitting the eval. emcc passes this flag by default whenever
it knows that closure is not run.
From 95124eae80469bd9aac5523e23b2ed14c3d7d5d3 Mon Sep 17 00:00:00 2001
From: Philip Bielby
Date: Wed, 1 Jun 2016 10:19:29 +0100
Subject: [PATCH 022/102] Add closure externs for SIMD.js
---
src/closure-externs.js | 655 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 655 insertions(+)
diff --git a/src/closure-externs.js b/src/closure-externs.js
index 492a634718e24..4eb4e3f873e73 100644
--- a/src/closure-externs.js
+++ b/src/closure-externs.js
@@ -193,3 +193,658 @@ Atomics.prototype.xor = function(typedArray, index, value) {};
Atomics.prototype.wait = function(typedArray, index, valuei, timeout) {};
Atomics.prototype.wake = function(typedArray, index, value) {};
Atomics.prototype.isLockFree = function(size) {};
+
+/**
+ * SIMD.js support (not in upstream closure yet).
+ */
+var SIMD;
+//Base objects
+SIMD.Float32x4;
+SIMD.Float64x2;
+SIMD.Int8x16;
+SIMD.Int16x8;
+SIMD.Int32x4;
+SIMD.Uint8x16;
+SIMD.Uint16x8;
+SIMD.Uint32x4;
+SIMD.Bool8x16;
+SIMD.Bool16x8;
+SIMD.Bool32x4;
+SIMD.Bool64x2;
+
+SIMD.Float32x4.abs = function() {};
+SIMD.Float64x2.abs = function() {};
+SIMD.Int8x16.abs = function() {};
+SIMD.Int16x8.abs = function() {};
+SIMD.Int32x4.abs = function() {};
+SIMD.Uint8x16.abs = function() {};
+SIMD.Uint16x8.abs = function() {};
+SIMD.Uint32x4.abs = function() {};
+SIMD.Bool8x16.abs = function() {};
+SIMD.Bool16x8.abs = function() {};
+SIMD.Bool32x4.abs = function() {};
+SIMD.Bool64x2.abs = function() {};
+
+SIMD.Float32x4.add = function() {};
+SIMD.Float64x2.add = function() {};
+SIMD.Int8x16.add = function() {};
+SIMD.Int16x8.add = function() {};
+SIMD.Int32x4.add = function() {};
+SIMD.Uint8x16.add = function() {};
+SIMD.Uint16x8.add = function() {};
+SIMD.Uint32x4.add = function() {};
+SIMD.Bool8x16.add = function() {};
+SIMD.Bool16x8.add = function() {};
+SIMD.Bool32x4.add = function() {};
+SIMD.Bool64x2.add = function() {};
+
+SIMD.Float32x4.addSaturate = function() {};
+SIMD.Float64x2.addSaturate = function() {};
+SIMD.Int8x16.addSaturate = function() {};
+SIMD.Int16x8.addSaturate = function() {};
+SIMD.Int32x4.addSaturate = function() {};
+SIMD.Uint8x16.addSaturate = function() {};
+SIMD.Uint16x8.addSaturate = function() {};
+SIMD.Uint32x4.addSaturate = function() {};
+SIMD.Bool8x16.addSaturate = function() {};
+SIMD.Bool16x8.addSaturate = function() {};
+SIMD.Bool32x4.addSaturate = function() {};
+SIMD.Bool64x2.addSaturate = function() {};
+
+SIMD.Float32x4.allTrue = function() {};
+SIMD.Float64x2.allTrue = function() {};
+SIMD.Int8x16.allTrue = function() {};
+SIMD.Int16x8.allTrue = function() {};
+SIMD.Int32x4.allTrue = function() {};
+SIMD.Uint8x16.allTrue = function() {};
+SIMD.Uint16x8.allTrue = function() {};
+SIMD.Uint32x4.allTrue = function() {};
+SIMD.Bool8x16.allTrue = function() {};
+SIMD.Bool16x8.allTrue = function() {};
+SIMD.Bool32x4.allTrue = function() {};
+SIMD.Bool64x2.allTrue = function() {};
+
+SIMD.Float32x4.and = function() {};
+SIMD.Float64x2.and = function() {};
+SIMD.Int8x16.and = function() {};
+SIMD.Int16x8.and = function() {};
+SIMD.Int32x4.and = function() {};
+SIMD.Uint8x16.and = function() {};
+SIMD.Uint16x8.and = function() {};
+SIMD.Uint32x4.and = function() {};
+SIMD.Bool8x16.and = function() {};
+SIMD.Bool16x8.and = function() {};
+SIMD.Bool32x4.and = function() {};
+SIMD.Bool64x2.and = function() {};
+
+SIMD.Float32x4.check = function() {};
+SIMD.Float64x2.check = function() {};
+SIMD.Int8x16.check = function() {};
+SIMD.Int16x8.check = function() {};
+SIMD.Int32x4.check = function() {};
+SIMD.Uint8x16.check = function() {};
+SIMD.Uint16x8.check = function() {};
+SIMD.Uint32x4.check = function() {};
+SIMD.Bool8x16.check = function() {};
+SIMD.Bool16x8.check = function() {};
+SIMD.Bool32x4.check = function() {};
+SIMD.Bool64x2.check = function() {};
+
+SIMD.Float32x4.div = function() {};
+SIMD.Float64x2.div = function() {};
+SIMD.Int8x16.div = function() {};
+SIMD.Int16x8.div = function() {};
+SIMD.Int32x4.div = function() {};
+SIMD.Uint8x16.div = function() {};
+SIMD.Uint16x8.div = function() {};
+SIMD.Uint32x4.div = function() {};
+SIMD.Bool8x16.div = function() {};
+SIMD.Bool16x8.div = function() {};
+SIMD.Bool32x4.div = function() {};
+SIMD.Bool64x2.div = function() {};
+
+SIMD.Float32x4.equal = function() {};
+SIMD.Float64x2.equal = function() {};
+SIMD.Int8x16.equal = function() {};
+SIMD.Int16x8.equal = function() {};
+SIMD.Int32x4.equal = function() {};
+SIMD.Uint8x16.equal = function() {};
+SIMD.Uint16x8.equal = function() {};
+SIMD.Uint32x4.equal = function() {};
+SIMD.Bool8x16.equal = function() {};
+SIMD.Bool16x8.equal = function() {};
+SIMD.Bool32x4.equal = function() {};
+SIMD.Bool64x2.equal = function() {};
+
+SIMD.Float32x4.extractLane = function() {};
+SIMD.Float64x2.extractLane = function() {};
+SIMD.Int8x16.extractLane = function() {};
+SIMD.Int16x8.extractLane = function() {};
+SIMD.Int32x4.extractLane = function() {};
+SIMD.Uint8x16.extractLane = function() {};
+SIMD.Uint16x8.extractLane = function() {};
+SIMD.Uint32x4.extractLane = function() {};
+SIMD.Bool8x16.extractLane = function() {};
+SIMD.Bool16x8.extractLane = function() {};
+SIMD.Bool32x4.extractLane = function() {};
+SIMD.Bool64x2.extractLane = function() {};
+
+SIMD.Float32x4.fromFloat32x4 = function() {};
+SIMD.Float64x2.fromFloat32x4 = function() {};
+SIMD.Int8x16.fromFloat32x4 = function() {};
+SIMD.Int16x8.fromFloat32x4 = function() {};
+SIMD.Int32x4.fromFloat32x4 = function() {};
+SIMD.Uint8x16.fromFloat32x4 = function() {};
+SIMD.Uint16x8.fromFloat32x4 = function() {};
+SIMD.Uint32x4.fromFloat32x4 = function() {};
+SIMD.Bool8x16.fromFloat32x4 = function() {};
+SIMD.Bool16x8.fromFloat32x4 = function() {};
+SIMD.Bool32x4.fromFloat32x4 = function() {};
+SIMD.Bool64x2.fromFloat32x4 = function() {};
+
+SIMD.Float32x4.fromFloat32x4Bits = function() {};
+SIMD.Float64x2.fromFloat32x4Bits = function() {};
+SIMD.Int8x16.fromFloat32x4Bits = function() {};
+SIMD.Int16x8.fromFloat32x4Bits = function() {};
+SIMD.Int32x4.fromFloat32x4Bits = function() {};
+SIMD.Uint8x16.fromFloat32x4Bits = function() {};
+SIMD.Uint16x8.fromFloat32x4Bits = function() {};
+SIMD.Uint32x4.fromFloat32x4Bits = function() {};
+SIMD.Bool8x16.fromFloat32x4Bits = function() {};
+SIMD.Bool16x8.fromFloat32x4Bits = function() {};
+SIMD.Bool32x4.fromFloat32x4Bits = function() {};
+SIMD.Bool64x2.fromFloat32x4Bits = function() {};
+
+SIMD.Float32x4.fromFloat64x2Bits = function() {};
+SIMD.Float64x2.fromFloat64x2Bits = function() {};
+SIMD.Int8x16.fromFloat64x2Bits = function() {};
+SIMD.Int16x8.fromFloat64x2Bits = function() {};
+SIMD.Int32x4.fromFloat64x2Bits = function() {};
+SIMD.Uint8x16.fromFloat64x2Bits = function() {};
+SIMD.Uint16x8.fromFloat64x2Bits = function() {};
+SIMD.Uint32x4.fromFloat64x2Bits = function() {};
+SIMD.Bool8x16.fromFloat64x2Bits = function() {};
+SIMD.Bool16x8.fromFloat64x2Bits = function() {};
+SIMD.Bool32x4.fromFloat64x2Bits = function() {};
+SIMD.Bool64x2.fromFloat64x2Bits = function() {};
+
+SIMD.Float32x4.fromInt16x8Bits = function() {};
+SIMD.Float64x2.fromInt16x8Bits = function() {};
+SIMD.Int8x16.fromInt16x8Bits = function() {};
+SIMD.Int16x8.fromInt16x8Bits = function() {};
+SIMD.Int32x4.fromInt16x8Bits = function() {};
+SIMD.Uint8x16.fromInt16x8Bits = function() {};
+SIMD.Uint16x8.fromInt16x8Bits = function() {};
+SIMD.Uint32x4.fromInt16x8Bits = function() {};
+SIMD.Bool8x16.fromInt16x8Bits = function() {};
+SIMD.Bool16x8.fromInt16x8Bits = function() {};
+SIMD.Bool32x4.fromInt16x8Bits = function() {};
+SIMD.Bool64x2.fromInt16x8Bits = function() {};
+
+SIMD.Float32x4.fromInt32x4 = function() {};
+SIMD.Float64x2.fromInt32x4 = function() {};
+SIMD.Int8x16.fromInt32x4 = function() {};
+SIMD.Int16x8.fromInt32x4 = function() {};
+SIMD.Int32x4.fromInt32x4 = function() {};
+SIMD.Uint8x16.fromInt32x4 = function() {};
+SIMD.Uint16x8.fromInt32x4 = function() {};
+SIMD.Uint32x4.fromInt32x4 = function() {};
+SIMD.Bool8x16.fromInt32x4 = function() {};
+SIMD.Bool16x8.fromInt32x4 = function() {};
+SIMD.Bool32x4.fromInt32x4 = function() {};
+SIMD.Bool64x2.fromInt32x4 = function() {};
+
+SIMD.Float32x4.fromInt32x4Bits = function() {};
+SIMD.Float64x2.fromInt32x4Bits = function() {};
+SIMD.Int8x16.fromInt32x4Bits = function() {};
+SIMD.Int16x8.fromInt32x4Bits = function() {};
+SIMD.Int32x4.fromInt32x4Bits = function() {};
+SIMD.Uint8x16.fromInt32x4Bits = function() {};
+SIMD.Uint16x8.fromInt32x4Bits = function() {};
+SIMD.Uint32x4.fromInt32x4Bits = function() {};
+SIMD.Bool8x16.fromInt32x4Bits = function() {};
+SIMD.Bool16x8.fromInt32x4Bits = function() {};
+SIMD.Bool32x4.fromInt32x4Bits = function() {};
+SIMD.Bool64x2.fromInt32x4Bits = function() {};
+
+SIMD.Float32x4.fromInt8x16Bits = function() {};
+SIMD.Float64x2.fromInt8x16Bits = function() {};
+SIMD.Int8x16.fromInt8x16Bits = function() {};
+SIMD.Int16x8.fromInt8x16Bits = function() {};
+SIMD.Int32x4.fromInt8x16Bits = function() {};
+SIMD.Uint8x16.fromInt8x16Bits = function() {};
+SIMD.Uint16x8.fromInt8x16Bits = function() {};
+SIMD.Uint32x4.fromInt8x16Bits = function() {};
+SIMD.Bool8x16.fromInt8x16Bits = function() {};
+SIMD.Bool16x8.fromInt8x16Bits = function() {};
+SIMD.Bool32x4.fromInt8x16Bits = function() {};
+SIMD.Bool64x2.fromInt8x16Bits = function() {};
+
+SIMD.Float32x4.fromUint16x8Bits = function() {};
+SIMD.Float64x2.fromUint16x8Bits = function() {};
+SIMD.Int8x16.fromUint16x8Bits = function() {};
+SIMD.Int16x8.fromUint16x8Bits = function() {};
+SIMD.Int32x4.fromUint16x8Bits = function() {};
+SIMD.Uint8x16.fromUint16x8Bits = function() {};
+SIMD.Uint16x8.fromUint16x8Bits = function() {};
+SIMD.Uint32x4.fromUint16x8Bits = function() {};
+SIMD.Bool8x16.fromUint16x8Bits = function() {};
+SIMD.Bool16x8.fromUint16x8Bits = function() {};
+SIMD.Bool32x4.fromUint16x8Bits = function() {};
+SIMD.Bool64x2.fromUint16x8Bits = function() {};
+
+SIMD.Float32x4.fromUint32x4 = function() {};
+SIMD.Float64x2.fromUint32x4 = function() {};
+SIMD.Int8x16.fromUint32x4 = function() {};
+SIMD.Int16x8.fromUint32x4 = function() {};
+SIMD.Int32x4.fromUint32x4 = function() {};
+SIMD.Uint8x16.fromUint32x4 = function() {};
+SIMD.Uint16x8.fromUint32x4 = function() {};
+SIMD.Uint32x4.fromUint32x4 = function() {};
+SIMD.Bool8x16.fromUint32x4 = function() {};
+SIMD.Bool16x8.fromUint32x4 = function() {};
+SIMD.Bool32x4.fromUint32x4 = function() {};
+SIMD.Bool64x2.fromUint32x4 = function() {};
+
+SIMD.Float32x4.fromUint32x4Bits = function() {};
+SIMD.Float64x2.fromUint32x4Bits = function() {};
+SIMD.Int8x16.fromUint32x4Bits = function() {};
+SIMD.Int16x8.fromUint32x4Bits = function() {};
+SIMD.Int32x4.fromUint32x4Bits = function() {};
+SIMD.Uint8x16.fromUint32x4Bits = function() {};
+SIMD.Uint16x8.fromUint32x4Bits = function() {};
+SIMD.Uint32x4.fromUint32x4Bits = function() {};
+SIMD.Bool8x16.fromUint32x4Bits = function() {};
+SIMD.Bool16x8.fromUint32x4Bits = function() {};
+SIMD.Bool32x4.fromUint32x4Bits = function() {};
+SIMD.Bool64x2.fromUint32x4Bits = function() {};
+
+SIMD.Float32x4.fromUint8x16Bits = function() {};
+SIMD.Float64x2.fromUint8x16Bits = function() {};
+SIMD.Int8x16.fromUint8x16Bits = function() {};
+SIMD.Int16x8.fromUint8x16Bits = function() {};
+SIMD.Int32x4.fromUint8x16Bits = function() {};
+SIMD.Uint8x16.fromUint8x16Bits = function() {};
+SIMD.Uint16x8.fromUint8x16Bits = function() {};
+SIMD.Uint32x4.fromUint8x16Bits = function() {};
+SIMD.Bool8x16.fromUint8x16Bits = function() {};
+SIMD.Bool16x8.fromUint8x16Bits = function() {};
+SIMD.Bool32x4.fromUint8x16Bits = function() {};
+SIMD.Bool64x2.fromUint8x16Bits = function() {};
+
+SIMD.Float32x4.greaterThan = function() {};
+SIMD.Float64x2.greaterThan = function() {};
+SIMD.Int8x16.greaterThan = function() {};
+SIMD.Int16x8.greaterThan = function() {};
+SIMD.Int32x4.greaterThan = function() {};
+SIMD.Uint8x16.greaterThan = function() {};
+SIMD.Uint16x8.greaterThan = function() {};
+SIMD.Uint32x4.greaterThan = function() {};
+SIMD.Bool8x16.greaterThan = function() {};
+SIMD.Bool16x8.greaterThan = function() {};
+SIMD.Bool32x4.greaterThan = function() {};
+SIMD.Bool64x2.greaterThan = function() {};
+
+SIMD.Float32x4.greaterThanOrEqual = function() {};
+SIMD.Float64x2.greaterThanOrEqual = function() {};
+SIMD.Int8x16.greaterThanOrEqual = function() {};
+SIMD.Int16x8.greaterThanOrEqual = function() {};
+SIMD.Int32x4.greaterThanOrEqual = function() {};
+SIMD.Uint8x16.greaterThanOrEqual = function() {};
+SIMD.Uint16x8.greaterThanOrEqual = function() {};
+SIMD.Uint32x4.greaterThanOrEqual = function() {};
+SIMD.Bool8x16.greaterThanOrEqual = function() {};
+SIMD.Bool16x8.greaterThanOrEqual = function() {};
+SIMD.Bool32x4.greaterThanOrEqual = function() {};
+SIMD.Bool64x2.greaterThanOrEqual = function() {};
+
+SIMD.Float32x4.lessThan = function() {};
+SIMD.Float64x2.lessThan = function() {};
+SIMD.Int8x16.lessThan = function() {};
+SIMD.Int16x8.lessThan = function() {};
+SIMD.Int32x4.lessThan = function() {};
+SIMD.Uint8x16.lessThan = function() {};
+SIMD.Uint16x8.lessThan = function() {};
+SIMD.Uint32x4.lessThan = function() {};
+SIMD.Bool8x16.lessThan = function() {};
+SIMD.Bool16x8.lessThan = function() {};
+SIMD.Bool32x4.lessThan = function() {};
+SIMD.Bool64x2.lessThan = function() {};
+
+SIMD.Float32x4.lessThanOrEqual = function() {};
+SIMD.Float64x2.lessThanOrEqual = function() {};
+SIMD.Int8x16.lessThanOrEqual = function() {};
+SIMD.Int16x8.lessThanOrEqual = function() {};
+SIMD.Int32x4.lessThanOrEqual = function() {};
+SIMD.Uint8x16.lessThanOrEqual = function() {};
+SIMD.Uint16x8.lessThanOrEqual = function() {};
+SIMD.Uint32x4.lessThanOrEqual = function() {};
+SIMD.Bool8x16.lessThanOrEqual = function() {};
+SIMD.Bool16x8.lessThanOrEqual = function() {};
+SIMD.Bool32x4.lessThanOrEqual = function() {};
+SIMD.Bool64x2.lessThanOrEqual = function() {};
+
+SIMD.Float32x4.load = function() {};
+SIMD.Float64x2.load = function() {};
+SIMD.Int8x16.load = function() {};
+SIMD.Int16x8.load = function() {};
+SIMD.Int32x4.load = function() {};
+SIMD.Uint8x16.load = function() {};
+SIMD.Uint16x8.load = function() {};
+SIMD.Uint32x4.load = function() {};
+SIMD.Bool8x16.load = function() {};
+SIMD.Bool16x8.load = function() {};
+SIMD.Bool32x4.load = function() {};
+SIMD.Bool64x2.load = function() {};
+
+SIMD.Float32x4.max = function() {};
+SIMD.Float64x2.max = function() {};
+SIMD.Int8x16.max = function() {};
+SIMD.Int16x8.max = function() {};
+SIMD.Int32x4.max = function() {};
+SIMD.Uint8x16.max = function() {};
+SIMD.Uint16x8.max = function() {};
+SIMD.Uint32x4.max = function() {};
+SIMD.Bool8x16.max = function() {};
+SIMD.Bool16x8.max = function() {};
+SIMD.Bool32x4.max = function() {};
+SIMD.Bool64x2.max = function() {};
+
+SIMD.Float32x4.maxNum = function() {};
+SIMD.Float64x2.maxNum = function() {};
+SIMD.Int8x16.maxNum = function() {};
+SIMD.Int16x8.maxNum = function() {};
+SIMD.Int32x4.maxNum = function() {};
+SIMD.Uint8x16.maxNum = function() {};
+SIMD.Uint16x8.maxNum = function() {};
+SIMD.Uint32x4.maxNum = function() {};
+SIMD.Bool8x16.maxNum = function() {};
+SIMD.Bool16x8.maxNum = function() {};
+SIMD.Bool32x4.maxNum = function() {};
+SIMD.Bool64x2.maxNum = function() {};
+
+SIMD.Float32x4.min = function() {};
+SIMD.Float64x2.min = function() {};
+SIMD.Int8x16.min = function() {};
+SIMD.Int16x8.min = function() {};
+SIMD.Int32x4.min = function() {};
+SIMD.Uint8x16.min = function() {};
+SIMD.Uint16x8.min = function() {};
+SIMD.Uint32x4.min = function() {};
+SIMD.Bool8x16.min = function() {};
+SIMD.Bool16x8.min = function() {};
+SIMD.Bool32x4.min = function() {};
+SIMD.Bool64x2.min = function() {};
+
+SIMD.Float32x4.minNum = function() {};
+SIMD.Float64x2.minNum = function() {};
+SIMD.Int8x16.minNum = function() {};
+SIMD.Int16x8.minNum = function() {};
+SIMD.Int32x4.minNum = function() {};
+SIMD.Uint8x16.minNum = function() {};
+SIMD.Uint16x8.minNum = function() {};
+SIMD.Uint32x4.minNum = function() {};
+SIMD.Bool8x16.minNum = function() {};
+SIMD.Bool16x8.minNum = function() {};
+SIMD.Bool32x4.minNum = function() {};
+SIMD.Bool64x2.minNum = function() {};
+
+SIMD.Float32x4.mul = function() {};
+SIMD.Float64x2.mul = function() {};
+SIMD.Int8x16.mul = function() {};
+SIMD.Int16x8.mul = function() {};
+SIMD.Int32x4.mul = function() {};
+SIMD.Uint8x16.mul = function() {};
+SIMD.Uint16x8.mul = function() {};
+SIMD.Uint32x4.mul = function() {};
+SIMD.Bool8x16.mul = function() {};
+SIMD.Bool16x8.mul = function() {};
+SIMD.Bool32x4.mul = function() {};
+SIMD.Bool64x2.mul = function() {};
+
+SIMD.Float32x4.neg = function() {};
+SIMD.Float64x2.neg = function() {};
+SIMD.Int8x16.neg = function() {};
+SIMD.Int16x8.neg = function() {};
+SIMD.Int32x4.neg = function() {};
+SIMD.Uint8x16.neg = function() {};
+SIMD.Uint16x8.neg = function() {};
+SIMD.Uint32x4.neg = function() {};
+SIMD.Bool8x16.neg = function() {};
+SIMD.Bool16x8.neg = function() {};
+SIMD.Bool32x4.neg = function() {};
+SIMD.Bool64x2.neg = function() {};
+
+SIMD.Float32x4.not = function() {};
+SIMD.Float64x2.not = function() {};
+SIMD.Int8x16.not = function() {};
+SIMD.Int16x8.not = function() {};
+SIMD.Int32x4.not = function() {};
+SIMD.Uint8x16.not = function() {};
+SIMD.Uint16x8.not = function() {};
+SIMD.Uint32x4.not = function() {};
+SIMD.Bool8x16.not = function() {};
+SIMD.Bool16x8.not = function() {};
+SIMD.Bool32x4.not = function() {};
+SIMD.Bool64x2.not = function() {};
+
+SIMD.Float32x4.notEqual = function() {};
+SIMD.Float64x2.notEqual = function() {};
+SIMD.Int8x16.notEqual = function() {};
+SIMD.Int16x8.notEqual = function() {};
+SIMD.Int32x4.notEqual = function() {};
+SIMD.Uint8x16.notEqual = function() {};
+SIMD.Uint16x8.notEqual = function() {};
+SIMD.Uint32x4.notEqual = function() {};
+SIMD.Bool8x16.notEqual = function() {};
+SIMD.Bool16x8.notEqual = function() {};
+SIMD.Bool32x4.notEqual = function() {};
+SIMD.Bool64x2.notEqual = function() {};
+
+SIMD.Float32x4.or = function() {};
+SIMD.Float64x2.or = function() {};
+SIMD.Int8x16.or = function() {};
+SIMD.Int16x8.or = function() {};
+SIMD.Int32x4.or = function() {};
+SIMD.Uint8x16.or = function() {};
+SIMD.Uint16x8.or = function() {};
+SIMD.Uint32x4.or = function() {};
+SIMD.Bool8x16.or = function() {};
+SIMD.Bool16x8.or = function() {};
+SIMD.Bool32x4.or = function() {};
+SIMD.Bool64x2.or = function() {};
+
+SIMD.Float32x4.prototype.toSource = function() {};
+SIMD.Float64x2.prototype.toSource = function() {};
+SIMD.Int8x16.prototype.toSource = function() {};
+SIMD.Int16x8.prototype.toSource = function() {};
+SIMD.Int32x4.prototype.toSource = function() {};
+SIMD.Uint8x16.prototype.toSource = function() {};
+SIMD.Uint16x8.prototype.toSource = function() {};
+SIMD.Uint32x4.prototype.toSource = function() {};
+SIMD.Bool8x16.prototype.toSource = function() {};
+SIMD.Bool16x8.prototype.toSource = function() {};
+SIMD.Bool32x4.prototype.toSource = function() {};
+SIMD.Bool64x2.prototype.toSource = function() {};
+
+SIMD.Float32x4.reciprocalApproximation = function() {};
+SIMD.Float64x2.reciprocalApproximation = function() {};
+SIMD.Int8x16.reciprocalApproximation = function() {};
+SIMD.Int16x8.reciprocalApproximation = function() {};
+SIMD.Int32x4.reciprocalApproximation = function() {};
+SIMD.Uint8x16.reciprocalApproximation = function() {};
+SIMD.Uint16x8.reciprocalApproximation = function() {};
+SIMD.Uint32x4.reciprocalApproximation = function() {};
+SIMD.Bool8x16.reciprocalApproximation = function() {};
+SIMD.Bool16x8.reciprocalApproximation = function() {};
+SIMD.Bool32x4.reciprocalApproximation = function() {};
+SIMD.Bool64x2.reciprocalApproximation = function() {};
+
+SIMD.Float32x4.reciprocalSqrtApproximation = function() {};
+SIMD.Float64x2.reciprocalSqrtApproximation = function() {};
+SIMD.Int8x16.reciprocalSqrtApproximation = function() {};
+SIMD.Int16x8.reciprocalSqrtApproximation = function() {};
+SIMD.Int32x4.reciprocalSqrtApproximation = function() {};
+SIMD.Uint8x16.reciprocalSqrtApproximation = function() {};
+SIMD.Uint16x8.reciprocalSqrtApproximation = function() {};
+SIMD.Uint32x4.reciprocalSqrtApproximation = function() {};
+SIMD.Bool8x16.reciprocalSqrtApproximation = function() {};
+SIMD.Bool16x8.reciprocalSqrtApproximation = function() {};
+SIMD.Bool32x4.reciprocalSqrtApproximation = function() {};
+SIMD.Bool64x2.reciprocalSqrtApproximation = function() {};
+
+SIMD.Float32x4.replaceLane = function() {};
+SIMD.Float64x2.replaceLane = function() {};
+SIMD.Int8x16.replaceLane = function() {};
+SIMD.Int16x8.replaceLane = function() {};
+SIMD.Int32x4.replaceLane = function() {};
+SIMD.Uint8x16.replaceLane = function() {};
+SIMD.Uint16x8.replaceLane = function() {};
+SIMD.Uint32x4.replaceLane = function() {};
+SIMD.Bool8x16.replaceLane = function() {};
+SIMD.Bool16x8.replaceLane = function() {};
+SIMD.Bool32x4.replaceLane = function() {};
+SIMD.Bool64x2.replaceLane = function() {};
+
+SIMD.Float32x4.select = function() {};
+SIMD.Float64x2.select = function() {};
+SIMD.Int8x16.select = function() {};
+SIMD.Int16x8.select = function() {};
+SIMD.Int32x4.select = function() {};
+SIMD.Uint8x16.select = function() {};
+SIMD.Uint16x8.select = function() {};
+SIMD.Uint32x4.select = function() {};
+SIMD.Bool8x16.select = function() {};
+SIMD.Bool16x8.select = function() {};
+SIMD.Bool32x4.select = function() {};
+SIMD.Bool64x2.select = function() {};
+
+SIMD.Float32x4.shiftLeftByScalar = function() {};
+SIMD.Float64x2.shiftLeftByScalar = function() {};
+SIMD.Int8x16.shiftLeftByScalar = function() {};
+SIMD.Int16x8.shiftLeftByScalar = function() {};
+SIMD.Int32x4.shiftLeftByScalar = function() {};
+SIMD.Uint8x16.shiftLeftByScalar = function() {};
+SIMD.Uint16x8.shiftLeftByScalar = function() {};
+SIMD.Uint32x4.shiftLeftByScalar = function() {};
+SIMD.Bool8x16.shiftLeftByScalar = function() {};
+SIMD.Bool16x8.shiftLeftByScalar = function() {};
+SIMD.Bool32x4.shiftLeftByScalar = function() {};
+SIMD.Bool64x2.shiftLeftByScalar = function() {};
+
+SIMD.Float32x4.shiftRightByScalar = function() {};
+SIMD.Float64x2.shiftRightByScalar = function() {};
+SIMD.Int8x16.shiftRightByScalar = function() {};
+SIMD.Int16x8.shiftRightByScalar = function() {};
+SIMD.Int32x4.shiftRightByScalar = function() {};
+SIMD.Uint8x16.shiftRightByScalar = function() {};
+SIMD.Uint16x8.shiftRightByScalar = function() {};
+SIMD.Uint32x4.shiftRightByScalar = function() {};
+SIMD.Bool8x16.shiftRightByScalar = function() {};
+SIMD.Bool16x8.shiftRightByScalar = function() {};
+SIMD.Bool32x4.shiftRightByScalar = function() {};
+SIMD.Bool64x2.shiftRightByScalar = function() {};
+
+SIMD.Float32x4.shuffle = function() {};
+SIMD.Float64x2.shuffle = function() {};
+SIMD.Int8x16.shuffle = function() {};
+SIMD.Int16x8.shuffle = function() {};
+SIMD.Int32x4.shuffle = function() {};
+SIMD.Uint8x16.shuffle = function() {};
+SIMD.Uint16x8.shuffle = function() {};
+SIMD.Uint32x4.shuffle = function() {};
+SIMD.Bool8x16.shuffle = function() {};
+SIMD.Bool16x8.shuffle = function() {};
+SIMD.Bool32x4.shuffle = function() {};
+SIMD.Bool64x2.shuffle = function() {};
+
+SIMD.Float32x4.splat = function() {};
+SIMD.Float64x2.splat = function() {};
+SIMD.Int8x16.splat = function() {};
+SIMD.Int16x8.splat = function() {};
+SIMD.Int32x4.splat = function() {};
+SIMD.Uint8x16.splat = function() {};
+SIMD.Uint16x8.splat = function() {};
+SIMD.Uint32x4.splat = function() {};
+SIMD.Bool8x16.splat = function() {};
+SIMD.Bool16x8.splat = function() {};
+SIMD.Bool32x4.splat = function() {};
+SIMD.Bool64x2.splat = function() {};
+
+SIMD.Float32x4.sqrt = function() {};
+SIMD.Float64x2.sqrt = function() {};
+SIMD.Int8x16.sqrt = function() {};
+SIMD.Int16x8.sqrt = function() {};
+SIMD.Int32x4.sqrt = function() {};
+SIMD.Uint8x16.sqrt = function() {};
+SIMD.Uint16x8.sqrt = function() {};
+SIMD.Uint32x4.sqrt = function() {};
+SIMD.Bool8x16.sqrt = function() {};
+SIMD.Bool16x8.sqrt = function() {};
+SIMD.Bool32x4.sqrt = function() {};
+SIMD.Bool64x2.sqrt = function() {};
+
+SIMD.Float32x4.store = function() {};
+SIMD.Float64x2.store = function() {};
+SIMD.Int8x16.store = function() {};
+SIMD.Int16x8.store = function() {};
+SIMD.Int32x4.store = function() {};
+SIMD.Uint8x16.store = function() {};
+SIMD.Uint16x8.store = function() {};
+SIMD.Uint32x4.store = function() {};
+SIMD.Bool8x16.store = function() {};
+SIMD.Bool16x8.store = function() {};
+SIMD.Bool32x4.store = function() {};
+SIMD.Bool64x2.store = function() {};
+
+SIMD.Float32x4.sub = function() {};
+SIMD.Float64x2.sub = function() {};
+SIMD.Int8x16.sub = function() {};
+SIMD.Int16x8.sub = function() {};
+SIMD.Int32x4.sub = function() {};
+SIMD.Uint8x16.sub = function() {};
+SIMD.Uint16x8.sub = function() {};
+SIMD.Uint32x4.sub = function() {};
+SIMD.Bool8x16.sub = function() {};
+SIMD.Bool16x8.sub = function() {};
+SIMD.Bool32x4.sub = function() {};
+SIMD.Bool64x2.sub = function() {};
+
+SIMD.Float32x4.subSaturate = function() {};
+SIMD.Float64x2.subSaturate = function() {};
+SIMD.Int8x16.subSaturate = function() {};
+SIMD.Int16x8.subSaturate = function() {};
+SIMD.Int32x4.subSaturate = function() {};
+SIMD.Uint8x16.subSaturate = function() {};
+SIMD.Uint16x8.subSaturate = function() {};
+SIMD.Uint32x4.subSaturate = function() {};
+SIMD.Bool8x16.subSaturate = function() {};
+SIMD.Bool16x8.subSaturate = function() {};
+SIMD.Bool32x4.subSaturate = function() {};
+SIMD.Bool64x2.subSaturate = function() {};
+
+SIMD.Float32x4.swizzle = function() {};
+SIMD.Float64x2.swizzle = function() {};
+SIMD.Int8x16.swizzle = function() {};
+SIMD.Int16x8.swizzle = function() {};
+SIMD.Int32x4.swizzle = function() {};
+SIMD.Uint8x16.swizzle = function() {};
+SIMD.Uint16x8.swizzle = function() {};
+SIMD.Uint32x4.swizzle = function() {};
+SIMD.Bool8x16.swizzle = function() {};
+SIMD.Bool16x8.swizzle = function() {};
+SIMD.Bool32x4.swizzle = function() {};
+SIMD.Bool64x2.swizzle = function() {};
+
+SIMD.Float32x4.xor = function() {};
+SIMD.Float64x2.xor = function() {};
+SIMD.Int8x16.xor = function() {};
+SIMD.Int16x8.xor = function() {};
+SIMD.Int32x4.xor = function() {};
+SIMD.Uint8x16.xor = function() {};
+SIMD.Uint16x8.xor = function() {};
+SIMD.Uint32x4.xor = function() {};
+SIMD.Bool8x16.xor = function() {};
+SIMD.Bool16x8.xor = function() {};
+SIMD.Bool32x4.xor = function() {};
+SIMD.Bool64x2.xor = function() {};
From fd8a1104e8894805674a4de55b8fd4ba84ea3e47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?=
Date: Thu, 2 Jun 2016 18:08:34 +0300
Subject: [PATCH 023/102] Fix GLFW regression from #4318 (no cancelFullscreen,
but exitFullscreen). Closes #4379.
---
src/library_glfw.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/library_glfw.js b/src/library_glfw.js
index bb4f12c755ed8..6451e42fefc9e 100644
--- a/src/library_glfw.js
+++ b/src/library_glfw.js
@@ -794,7 +794,7 @@ var LibraryGLFW = {
if (width == screen.width && height == screen.height) {
GLFW.requestFullscreen();
} else {
- GLFW.cancelFullscreen();
+ GLFW.exitFullscreen();
Browser.setCanvasSize(width, height);
win.width = width;
win.height = height;
From 1f997cc3e9bbb8c9da1a17af85a52228c358fecc Mon Sep 17 00:00:00 2001
From: Philip Bielby
Date: Thu, 2 Jun 2016 16:52:33 +0100
Subject: [PATCH 024/102] Allow glGetString to return values from the
WEBGL_debug_renderer_info extension
---
src/library_gl.js | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/library_gl.js b/src/library_gl.js
index 2ef8a56b18e63..e0980646dfdb3 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -715,6 +715,8 @@ var LibraryGL = {
switch(name_) {
case 0x1F00 /* GL_VENDOR */:
case 0x1F01 /* GL_RENDERER */:
+ case 0x9245 /* UNMASKED_VENDOR_WEBGL */:
+ case 0x9246 /* UNMASKED_RENDERER_WEBGL */:
ret = allocate(intArrayFromString(GLctx.getParameter(name_)), 'i8', ALLOC_NORMAL);
break;
case 0x1F02 /* GL_VERSION */:
From 84ac35ec8c23d24a4caf0cacad55c9d4fe893704 Mon Sep 17 00:00:00 2001
From: Derek Schuff
Date: Fri, 3 Jun 2016 13:22:40 -0700
Subject: [PATCH 025/102] Add udivmodti4 to wasm compiler-rt (#4386)
Other functions (divti3) refer to it, but it was missing.
---
.../lib/compiler-rt/lib/builtins/udivmodti4.c | 238 ++++++++++++++++++
tools/system_libs.py | 2 +-
2 files changed, 239 insertions(+), 1 deletion(-)
create mode 100644 system/lib/compiler-rt/lib/builtins/udivmodti4.c
diff --git a/system/lib/compiler-rt/lib/builtins/udivmodti4.c b/system/lib/compiler-rt/lib/builtins/udivmodti4.c
new file mode 100644
index 0000000000000..803168849c6c2
--- /dev/null
+++ b/system/lib/compiler-rt/lib/builtins/udivmodti4.c
@@ -0,0 +1,238 @@
+/* ===-- udivmodti4.c - Implement __udivmodti4 -----------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __udivmodti4 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+#ifdef CRT_HAS_128BIT
+
+/* Effects: if rem != 0, *rem = a % b
+ * Returns: a / b
+ */
+
+/* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */
+
+COMPILER_RT_ABI tu_int
+__udivmodti4(tu_int a, tu_int b, tu_int* rem)
+{
+ const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT;
+ const unsigned n_utword_bits = sizeof(tu_int) * CHAR_BIT;
+ utwords n;
+ n.all = a;
+ utwords d;
+ d.all = b;
+ utwords q;
+ utwords r;
+ unsigned sr;
+ /* special cases, X is unknown, K != 0 */
+ if (n.s.high == 0)
+ {
+ if (d.s.high == 0)
+ {
+ /* 0 X
+ * ---
+ * 0 X
+ */
+ if (rem)
+ *rem = n.s.low % d.s.low;
+ return n.s.low / d.s.low;
+ }
+ /* 0 X
+ * ---
+ * K X
+ */
+ if (rem)
+ *rem = n.s.low;
+ return 0;
+ }
+ /* n.s.high != 0 */
+ if (d.s.low == 0)
+ {
+ if (d.s.high == 0)
+ {
+ /* K X
+ * ---
+ * 0 0
+ */
+ if (rem)
+ *rem = n.s.high % d.s.low;
+ return n.s.high / d.s.low;
+ }
+ /* d.s.high != 0 */
+ if (n.s.low == 0)
+ {
+ /* K 0
+ * ---
+ * K 0
+ */
+ if (rem)
+ {
+ r.s.high = n.s.high % d.s.high;
+ r.s.low = 0;
+ *rem = r.all;
+ }
+ return n.s.high / d.s.high;
+ }
+ /* K K
+ * ---
+ * K 0
+ */
+ if ((d.s.high & (d.s.high - 1)) == 0) /* if d is a power of 2 */
+ {
+ if (rem)
+ {
+ r.s.low = n.s.low;
+ r.s.high = n.s.high & (d.s.high - 1);
+ *rem = r.all;
+ }
+ return n.s.high >> __builtin_ctzll(d.s.high);
+ }
+ /* K K
+ * ---
+ * K 0
+ */
+ sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high);
+ /* 0 <= sr <= n_udword_bits - 2 or sr large */
+ if (sr > n_udword_bits - 2)
+ {
+ if (rem)
+ *rem = n.all;
+ return 0;
+ }
+ ++sr;
+ /* 1 <= sr <= n_udword_bits - 1 */
+ /* q.all = n.all << (n_utword_bits - sr); */
+ q.s.low = 0;
+ q.s.high = n.s.low << (n_udword_bits - sr);
+ /* r.all = n.all >> sr; */
+ r.s.high = n.s.high >> sr;
+ r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
+ }
+ else /* d.s.low != 0 */
+ {
+ if (d.s.high == 0)
+ {
+ /* K X
+ * ---
+ * 0 K
+ */
+ if ((d.s.low & (d.s.low - 1)) == 0) /* if d is a power of 2 */
+ {
+ if (rem)
+ *rem = n.s.low & (d.s.low - 1);
+ if (d.s.low == 1)
+ return n.all;
+ sr = __builtin_ctzll(d.s.low);
+ q.s.high = n.s.high >> sr;
+ q.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
+ return q.all;
+ }
+ /* K X
+ * ---
+ * 0 K
+ */
+ sr = 1 + n_udword_bits + __builtin_clzll(d.s.low)
+ - __builtin_clzll(n.s.high);
+ /* 2 <= sr <= n_utword_bits - 1
+ * q.all = n.all << (n_utword_bits - sr);
+ * r.all = n.all >> sr;
+ */
+ if (sr == n_udword_bits)
+ {
+ q.s.low = 0;
+ q.s.high = n.s.low;
+ r.s.high = 0;
+ r.s.low = n.s.high;
+ }
+ else if (sr < n_udword_bits) // 2 <= sr <= n_udword_bits - 1
+ {
+ q.s.low = 0;
+ q.s.high = n.s.low << (n_udword_bits - sr);
+ r.s.high = n.s.high >> sr;
+ r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
+ }
+ else // n_udword_bits + 1 <= sr <= n_utword_bits - 1
+ {
+ q.s.low = n.s.low << (n_utword_bits - sr);
+ q.s.high = (n.s.high << (n_utword_bits - sr)) |
+ (n.s.low >> (sr - n_udword_bits));
+ r.s.high = 0;
+ r.s.low = n.s.high >> (sr - n_udword_bits);
+ }
+ }
+ else
+ {
+ /* K X
+ * ---
+ * K K
+ */
+ sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high);
+ /*0 <= sr <= n_udword_bits - 1 or sr large */
+ if (sr > n_udword_bits - 1)
+ {
+ if (rem)
+ *rem = n.all;
+ return 0;
+ }
+ ++sr;
+ /* 1 <= sr <= n_udword_bits
+ * q.all = n.all << (n_utword_bits - sr);
+ * r.all = n.all >> sr;
+ */
+ q.s.low = 0;
+ if (sr == n_udword_bits)
+ {
+ q.s.high = n.s.low;
+ r.s.high = 0;
+ r.s.low = n.s.high;
+ }
+ else
+ {
+ r.s.high = n.s.high >> sr;
+ r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
+ q.s.high = n.s.low << (n_udword_bits - sr);
+ }
+ }
+ }
+ /* Not a special case
+ * q and r are initialized with:
+ * q.all = n.all << (n_utword_bits - sr);
+ * r.all = n.all >> sr;
+ * 1 <= sr <= n_utword_bits - 1
+ */
+ su_int carry = 0;
+ for (; sr > 0; --sr)
+ {
+ /* r:q = ((r:q) << 1) | carry */
+ r.s.high = (r.s.high << 1) | (r.s.low >> (n_udword_bits - 1));
+ r.s.low = (r.s.low << 1) | (q.s.high >> (n_udword_bits - 1));
+ q.s.high = (q.s.high << 1) | (q.s.low >> (n_udword_bits - 1));
+ q.s.low = (q.s.low << 1) | carry;
+ /* carry = 0;
+ * if (r.all >= d.all)
+ * {
+ * r.all -= d.all;
+ * carry = 1;
+ * }
+ */
+ const ti_int s = (ti_int)(d.all - r.all - 1) >> (n_utword_bits - 1);
+ carry = s & 1;
+ r.all -= d.all & s;
+ }
+ q.all = (q.all << 1) | carry;
+ if (rem)
+ *rem = r.all;
+ return q.all;
+}
+
+#endif /* CRT_HAS_128BIT */
diff --git a/tools/system_libs.py b/tools/system_libs.py
index a994a474eab16..417e0414e674a 100644
--- a/tools/system_libs.py
+++ b/tools/system_libs.py
@@ -238,7 +238,7 @@ def create_dlmalloc_split(libname):
def create_wasm_compiler_rt(libname):
srcdir = shared.path_from_root('system', 'lib', 'compiler-rt', 'lib', 'builtins')
- filenames = ['addtf3.c', 'ashlti3.c', 'ashrti3.c', 'comparetf2.c', 'divtf3.c', 'divti3.c',
+ filenames = ['addtf3.c', 'ashlti3.c', 'ashrti3.c', 'comparetf2.c', 'divtf3.c', 'divti3.c', 'udivmodti4.c',
'extenddftf2.c', 'extendsftf2.c',
'fixdfti.c', 'fixsfti.c', 'fixtfdi.c', 'fixtfsi.c', 'fixtfti.c',
'fixunsdfti.c', 'fixunssfti.c', 'fixunstfdi.c', 'fixunstfsi.c', 'fixunstfti.c',
From b40d2ef8d15908a8c0e9d91164a477fd1200b849 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?=
Date: Tue, 7 Jun 2016 12:12:15 +0300
Subject: [PATCH 026/102] Fixed glFramebufferTextureLayer() WebGL2/GLES3
function which did not properly index to the textures array. Thanks to Marco
Trivellato for catching the issue!
---
src/library_gl.js | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/library_gl.js b/src/library_gl.js
index 2ef8a56b18e63..26d78379f5754 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -3583,6 +3583,16 @@ var LibraryGL = {
GL.textures[texture], level);
},
+#if USE_WEBGL2
+ glFramebufferTextureLayer__sig: 'viiiii',
+ glFramebufferTextureLayer: function(target, attachment, texture, level, layer) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.textures, texture, 'glFramebufferTextureLayer', 'texture');
+#endif
+ GLctx.framebufferTextureLayer(target, attachment, GL.textures[texture], level, layer);
+ },
+#endif
+
glGetFramebufferAttachmentParameteriv__sig: 'viiii',
glGetFramebufferAttachmentParameteriv: function(target, attachment, pname, params) {
var result = GLctx.getFramebufferAttachmentParameter(target, attachment, pname);
@@ -7345,7 +7355,6 @@ var LibraryGL = {
glRenderbufferStorageMultisample__sig: 'viiiii',
glCopyTexSubImage3D__sig: 'viiiiiiiii',
glClearBufferfi__sig: 'viifi',
- glFramebufferTextureLayer__sig: 'viiiii',
#endif
};
@@ -7366,7 +7375,7 @@ var glFuncs = [[0, 'finish flush'],
glFuncs[0][1] += ' endTransformFeedback pauseTransformFeedback resumeTransformFeedback';
glFuncs[1][1] += ' beginTransformFeedback readBuffer endQuery';
glFuncs[4][1] += ' clearBufferfi';
-glFuncs[5][1] += ' vertexAttribI4i vertexAttribI4ui copyBufferSubData texStorage2D renderbufferStorageMultisample framebufferTextureLayer';
+glFuncs[5][1] += ' vertexAttribI4i vertexAttribI4ui copyBufferSubData texStorage2D renderbufferStorageMultisample';
// TODO: Removed as a workaround, see https://bugzilla.mozilla.org/show_bug.cgi?id=1202427
//glFuncs[6][1] += ' drawRangeElements';
glFuncs[6][1] += ' texStorage3D';
From 2fbed5aba304797a179be9644be2c81c0cf1b363 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?=
Date: Fri, 10 Jun 2016 01:55:51 +0300
Subject: [PATCH 027/102] When crafting environment to run clang in on Windows
for native Windows builds, account for that Visual Studio might not be in
path, and add it manually.
---
tools/shared.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/shared.py b/tools/shared.py
index 070e61663fe0a..f86b40ee957be 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -676,6 +676,7 @@ def get_clang_native_env():
env['INCLUDE'] = os.path.join(visual_studio_2013_path, 'VC\\INCLUDE')
env['LIB'] = os.path.join(visual_studio_2013_path, 'VC\\LIB\\amd64') + ';' + os.path.join(windows_sdk_dir, 'lib\\winv6.3\\um\\x64')
+ env['PATH'] = env['PATH'] + ';' + os.path.join(visual_studio_2013_path, 'VC\\BIN')
# Current configuration above is all Visual Studio -specific, so on non-Windowses, no action needed.
From 2e56e7764fcfac0dc617723283cf064dd7115cbd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?=
Date: Thu, 9 Jun 2016 16:20:03 +0300
Subject: [PATCH 028/102] _mm_prefetch() should take in a const pointer.
---
system/include/emscripten/xmmintrin.h | 2 +-
tests/test_sse1.cpp | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/system/include/emscripten/xmmintrin.h b/system/include/emscripten/xmmintrin.h
index 6266dea13bd97..9b21252361abf 100644
--- a/system/include/emscripten/xmmintrin.h
+++ b/system/include/emscripten/xmmintrin.h
@@ -126,7 +126,7 @@ _mm_store_ps(float *__p, __m128 __a)
#define _MM_HINT_NTA 0
// No prefetch available, dummy it out.
static __inline__ void __attribute__((__always_inline__))
-_mm_prefetch(void *__p, int __i)
+_mm_prefetch(const void *__p, int __i)
{
((void)__p);
((void)__i);
diff --git a/tests/test_sse1.cpp b/tests/test_sse1.cpp
index ec04509e06525..5844201b0ee44 100644
--- a/tests/test_sse1.cpp
+++ b/tests/test_sse1.cpp
@@ -329,6 +329,9 @@ int main()
_mm_prefetch(dummyData, _MM_HINT_NTA);
_mm_sfence();
+ const char *ptr = (const char*)dummyData;
+ _mm_prefetch(ptr, _MM_HINT_T0);
+
// SSE1 Misc instructions:
#ifdef TEST_M64
/*M64*/Assert(_mm_movemask_pi8(m1) == 100); // Return int with eight lowest bits set depending on the highest bits of the 8 uint8 input channels of the m64.
From 2b8f3e04750de0f1758c467790890da46debd9be Mon Sep 17 00:00:00 2001
From: Alon Zakai
Date: Fri, 10 Jun 2016 11:39:39 -0700
Subject: [PATCH 029/102] we may call begin_catch on an exception more than
once; track which exceptions we decremented the count of uncaught on #4392
---
src/library.js | 9 +++++++--
tests/test_core.py | 24 ++++++++++++++++++++++++
2 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/src/library.js b/src/library.js
index fabc1b0a0caa2..bdc3e4c6f41e4 100644
--- a/src/library.js
+++ b/src/library.js
@@ -1035,7 +1035,8 @@ LibraryManager.library = {
adjusted: ptr,
type: type,
destructor: destructor,
- refcount: 0
+ refcount: 0,
+ caught: false
};
EXCEPTIONS.last = ptr;
if (!("uncaught_exception" in __ZSt18uncaught_exceptionv)) {
@@ -1076,7 +1077,11 @@ LibraryManager.library = {
},
__cxa_begin_catch__deps: ['_ZSt18uncaught_exceptionv', '$EXCEPTIONS'],
__cxa_begin_catch: function(ptr) {
- __ZSt18uncaught_exceptionv.uncaught_exception--;
+ var info = EXCEPTIONS.infos[ptr];
+ if (info && !info.caught) {
+ info.caught = true;
+ __ZSt18uncaught_exceptionv.uncaught_exception--;
+ }
EXCEPTIONS.caught.push(ptr);
#if EXCEPTION_DEBUG
Module.printErr('cxa_begin_catch ' + [ptr, 'stack', EXCEPTIONS.caught]);
diff --git a/tests/test_core.py b/tests/test_core.py
index 0829183c1967c..2f1c62526da1b 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -1473,6 +1473,30 @@ def test_exceptions_uncaught(self):
'''
self.do_run(src, 'success')
+ def test_exceptions_uncaught_2(self):
+ Settings.DISABLE_EXCEPTION_CATCHING = 0
+
+ src = r'''
+ #include
+ #include
+
+ int main() {
+ try {
+ throw std::exception();
+ } catch(std::exception) {
+ try {
+ throw;
+ } catch(std::exception) {}
+ }
+
+ if (std::uncaught_exception())
+ std::cout << "ERROR: uncaught_exception still set.";
+ else
+ std::cout << "OK";
+ }
+ '''
+ self.do_run(src, 'OK\n')
+
def test_exceptions_typed(self):
Settings.DISABLE_EXCEPTION_CATCHING = 0
self.emcc_args += ['-s', 'SAFE_HEAP=0'] # Throwing null will cause an ignorable null pointer access.
From 7ea0bf8d046faf0c8f067abbaec51907dcfd4dc4 Mon Sep 17 00:00:00 2001
From: Alon Zakai
Date: Fri, 10 Jun 2016 14:01:15 -0700
Subject: [PATCH 030/102] update binaryen tag to 10
---
tools/ports/binaryen.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/ports/binaryen.py b/tools/ports/binaryen.py
index 1b0b8b901ae15..d86565c9cdea6 100644
--- a/tools/ports/binaryen.py
+++ b/tools/ports/binaryen.py
@@ -1,6 +1,6 @@
import os, shutil, logging
-TAG = 'version_9'
+TAG = 'version_10'
def needed(settings, shared, ports):
if not settings.BINARYEN: return False
From 1b3e15dbde3e1623cefd66ee1b853953af551485 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?=
Date: Fri, 17 Jun 2016 15:09:00 +0100
Subject: [PATCH 031/102] Update the error message of little endian check to
avoid referring to typed arrays 2 mode, which is not relevant anymore. Also,
only write 0x000000FF to address 0 in the beginning of the main thread so
that the check has more power to detect memory corruption when pthread
workers are spawned.
---
src/preamble.js | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/preamble.js b/src/preamble.js
index e0fb49c5a9070..038eeedb559ea 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -1422,8 +1422,14 @@ function setF64(ptr, value) {
// Endianness check (note: assumes compiler arch was little-endian)
#if SAFE_SPLIT_MEMORY == 0
-HEAP32[0] = 255;
-if (HEAPU8[0] !== 255 || HEAPU8[3] !== 0) throw 'Typed arrays 2 must be run on a little-endian system';
+#if USE_PTHREADS
+if (!ENVIRONMENT_IS_PTHREAD) {
+#endif
+ HEAP32[0] = 255;
+#if USE_PTHREADS
+}
+#endif
+if (HEAPU8[0] !== 255 || HEAPU8[3] !== 0) throw 'Runtime error: either the current system is not little-endian, or it has corrupted its heap memory area (address zero)!';
#endif
Module['HEAP'] = HEAP;
From fdb2dca0829fd291de1453044b375ff7234cf4d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?=
Date: Sun, 19 Jun 2016 22:07:02 +0300
Subject: [PATCH 032/102] Implement a file-based lock mechanism to access the
Emscripten cache. Closes #3850. Also fix an issue from earlier commit where
at least on Windows, calling pool.terminate / pool.join might not succeed,
but instead throws an "Access is denied" exception.
---
tools/cache.py | 51 +--
tools/duplicate_function_eliminator.py | 7 +-
tools/filelock.py | 425 +++++++++++++++++++++++++
tools/js_optimizer.py | 7 +-
4 files changed, 466 insertions(+), 24 deletions(-)
create mode 100644 tools/filelock.py
diff --git a/tools/cache.py b/tools/cache.py
index d1e22fba31977..a67a8370ea62a 100644
--- a/tools/cache.py
+++ b/tools/cache.py
@@ -1,6 +1,5 @@
import os.path, sys, shutil, time, logging
-
-import tempfiles
+import tempfiles, filelock
# Permanent cache for dlmalloc and stdlibc++
class Cache:
@@ -17,15 +16,24 @@ def __init__(self, dirname=None, debug=False, use_subdir=True):
self.dirname = dirname
self.debug = debug
+ def reverse_chop(thestring, ending):
+ if thestring.endswith(ending):
+ return thestring[:-len(ending)]
+ return thestring
+
+ self.filelock = filelock.FileLock(reverse_chop(reverse_chop(self.dirname, '/'), '\\') + '.lock')
+
def ensure(self):
- shared.safe_ensure_dirs(self.dirname)
+ with self.filelock:
+ shared.safe_ensure_dirs(self.dirname)
def erase(self):
- tempfiles.try_delete(self.dirname)
- try:
- open(self.dirname + '__last_clear', 'w').write('last clear: ' + time.asctime() + '\n')
- except Exception, e:
- print >> sys.stderr, 'failed to save last clear time: ', e
+ with self.filelock:
+ tempfiles.try_delete(self.dirname)
+ try:
+ open(self.dirname + '__last_clear', 'w').write('last clear: ' + time.asctime() + '\n')
+ except Exception, e:
+ print >> sys.stderr, 'failed to save last clear time: ', e
def get_path(self, shortname):
return os.path.join(self.dirname, shortname)
@@ -35,18 +43,21 @@ def get_path(self, shortname):
def get(self, shortname, creator, extension='.bc', what=None, force=False):
if not shortname.endswith(extension): shortname += extension
cachename = os.path.join(self.dirname, shortname)
- if os.path.exists(cachename) and not force:
- return cachename
- if what is None:
- if shortname.endswith(('.bc', '.so', '.a')): what = 'system library'
- else: what = 'system asset'
- message = 'generating ' + what + ': ' + shortname + '...'
- logging.warn(message)
- self.ensure()
- temp = creator()
- if temp != cachename:
- shutil.copyfile(temp, cachename)
- logging.warn(' '*len(message) + 'ok')
+
+ with self.filelock:
+ if os.path.exists(cachename) and not force:
+ return cachename
+ if what is None:
+ if shortname.endswith(('.bc', '.so', '.a')): what = 'system library'
+ else: what = 'system asset'
+ message = 'generating ' + what + ': ' + shortname + '...'
+ logging.warn(message)
+ self.ensure()
+ temp = creator()
+ if temp != cachename:
+ shutil.copyfile(temp, cachename)
+ logging.warn(' '*len(message) + 'ok')
+
return cachename
# Given a set of functions of form (ident, text), and a preferred chunk size,
diff --git a/tools/duplicate_function_eliminator.py b/tools/duplicate_function_eliminator.py
index ae1387b9450be..f032b4f49c3ff 100644
--- a/tools/duplicate_function_eliminator.py
+++ b/tools/duplicate_function_eliminator.py
@@ -247,8 +247,11 @@ def write_chunk(chunk, i):
if DEBUG: print >> sys.stderr, 'splitting up js optimization into %d chunks, using %d cores (total: %.2f MB)' % (len(chunks), cores, total_size/(1024*1024.))
pool = multiprocessing.Pool(processes=cores)
filenames = pool.map(run_on_chunk, commands, chunksize=1)
- pool.terminate()
- pool.join()
+ try:
+ pool.terminate()
+ pool.join()
+ except Exception, e:
+ pass
else:
# We can't parallize, but still break into chunks to avoid uglify/node memory issues
if len(chunks) > 1 and DEBUG: print >> sys.stderr, 'splitting up js optimization into %d chunks' % (len(chunks))
diff --git a/tools/filelock.py b/tools/filelock.py
new file mode 100644
index 0000000000000..069d3d3feef7a
--- /dev/null
+++ b/tools/filelock.py
@@ -0,0 +1,425 @@
+#!/usr/bin/python2
+
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# For more information, please refer to
+
+# This software package was obtained from
+# https://github.com/benediktschmitt/py-filelock
+
+"""
+A platform independent file lock that supports the with-statement.
+"""
+
+
+# Modules
+# ------------------------------------------------
+import os
+import threading
+import time
+try:
+ import warnings
+except ImportError:
+ warnings = None
+
+try:
+ import msvcrt
+except ImportError:
+ msvcrt = None
+
+try:
+ import fcntl
+except ImportError:
+ fcntl = None
+
+import logging
+
+# Backward compatibility
+# ------------------------------------------------
+try:
+ TimeoutError
+except NameError:
+ TimeoutError = OSError
+
+
+# Data
+# ------------------------------------------------
+__all__ = [
+ "Timeout",
+ "BaseFileLock",
+ "WindowsFileLock",
+ "UnixFileLock",
+ "SoftFileLock",
+ "FileLock"
+]
+
+__version__ = "2.0.6"
+
+
+# Exceptions
+# ------------------------------------------------
+class Timeout(TimeoutError):
+ """
+ Raised when the lock could not be acquired in *timeout*
+ seconds.
+ """
+
+ def __init__(self, lock_file):
+ """
+ """
+ #: The path of the file lock.
+ self.lock_file = lock_file
+ return None
+
+ def __str__(self):
+ temp = "The file lock '{}' could not be acquired."\
+ .format(self.lock_file)
+ return temp
+
+
+# Classes
+# ------------------------------------------------
+class BaseFileLock(object):
+ """
+ Implements the base class of a file lock.
+ """
+
+ def __init__(self, lock_file, timeout = -1):
+ """
+ """
+ # The path to the lock file.
+ self._lock_file = lock_file
+
+ # The file descriptor for the *_lock_file* as it is returned by the
+ # os.open() function.
+ # This file lock is only NOT None, if the object currently holds the
+ # lock.
+ self._lock_file_fd = None
+
+ # The default timeout value.
+ self.timeout = timeout
+
+ # We use this lock primarily for the lock counter.
+ self._thread_lock = threading.Lock()
+
+ # The lock counter is used for implementing the nested locking
+ # mechanism. Whenever the lock is acquired, the counter is increased and
+ # the lock is only released, when this value is 0 again.
+ self._lock_counter = 0
+ return None
+
+ @property
+ def lock_file(self):
+ """
+ The path to the lock file.
+ """
+ return self._lock_file
+
+ @property
+ def timeout(self):
+ """
+ You can set a default timeout for the filelock. It will be used as
+ fallback value in the acquire method, if no timeout value (*None*) is
+ given.
+
+ If you want to disable the timeout, set it to a negative value.
+
+ A timeout of 0 means, that there is exactly one attempt to acquire the
+ file lock.
+
+ .. versionadded:: 2.0.0
+ """
+ return self._timeout
+
+ @timeout.setter
+ def timeout(self, value):
+ """
+ """
+ self._timeout = float(value)
+ return None
+
+ # Platform dependent locking
+ # --------------------------------------------
+
+ def _acquire(self):
+ """
+ Platform dependent. If the file lock could be
+ acquired, self._lock_file_fd holds the file descriptor
+ of the lock file.
+ """
+ raise NotImplementedError()
+
+ def _release(self):
+ """
+ Releases the lock and sets self._lock_file_fd to None.
+ """
+ raise NotImplementedError()
+
+ # Platform independent methods
+ # --------------------------------------------
+
+ @property
+ def is_locked(self):
+ """
+ True, if the object holds the file lock.
+
+ .. versionchanged:: 2.0.0
+
+ This was previously a method and is now a property.
+ """
+ return self._lock_file_fd is not None
+
+ def acquire(self, timeout=None, poll_intervall=0.05):
+ """
+ Acquires the file lock or fails with a :exc:`Timeout` error.
+
+ .. code-block:: python
+
+ # You can use this method in the context manager (recommended)
+ with lock.acquire():
+ pass
+
+ # Or you use an equal try-finally construct:
+ lock.acquire()
+ try:
+ pass
+ finally:
+ lock.release()
+
+ :arg float timeout:
+ The maximum time waited for the file lock.
+ If ``timeout <= 0``, there is no timeout and this method will
+ block until the lock could be acquired.
+ If ``timeout`` is None, the default :attr:`~timeout` is used.
+
+ :arg float poll_intervall:
+ We check once in *poll_intervall* seconds if we can acquire the
+ file lock.
+
+ :raises Timeout:
+ if the lock could not be acquired in *timeout* seconds.
+
+ .. versionchanged:: 2.0.0
+
+ This method returns now a *proxy* object instead of *self*,
+ so that it can be used in a with statement without side effects.
+ """
+ # Use the default timeout, if no timeout is provided.
+ if timeout is None:
+ timeout = self.timeout
+
+ # Increment the number right at the beginning.
+ # We can still undo it, if something fails.
+ with self._thread_lock:
+ self._lock_counter += 1
+
+ try:
+ start_time = time.time()
+ while True:
+ with self._thread_lock:
+ if not self.is_locked:
+ self._acquire()
+
+ if self.is_locked:
+ break
+ elif timeout >= 0 and time.time() - start_time > timeout:
+ raise Timeout(self._lock_file)
+ else:
+ time.sleep(poll_intervall)
+ except:
+ # Something did go wrong, so decrement the counter.
+ with self._thread_lock:
+ self._lock_counter = max(0, self._lock_counter - 1)
+
+ raise
+
+ # This class wraps the lock to make sure __enter__ is not called
+ # twiced when entering the with statement.
+ # If we would simply return *self*, the lock would be acquired again
+ # in the *__enter__* method of the BaseFileLock, but not released again
+ # automatically.
+ class ReturnProxy(object):
+
+ def __init__(self, lock):
+ self.lock = lock
+ return None
+
+ def __enter__(self):
+ return self.lock
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ self.lock.release()
+ return None
+
+ return ReturnProxy(lock = self)
+
+ def release(self, force = False):
+ """
+ Releases the file lock.
+
+ Please note, that the lock is only completly released, if the lock
+ counter is 0.
+
+ Also note, that the lock file itself is not automatically deleted.
+
+ :arg bool force:
+ If true, the lock counter is ignored and the lock is released in
+ every case.
+ """
+ with self._thread_lock:
+
+ if self.is_locked:
+ self._lock_counter -= 1
+
+ if self._lock_counter == 0 or force:
+ self._release()
+ self._lock_counter = 0
+ return None
+
+ def __enter__(self):
+ self.acquire()
+ return self
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ self.release()
+ return None
+
+ def __del__(self):
+ self.release(force = True)
+ return None
+
+
+# Windows locking mechanism
+# ~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class WindowsFileLock(BaseFileLock):
+ """
+ Uses the :func:`msvcrt.locking` function to hard lock the lock file on
+ windows systems.
+ """
+
+ def _acquire(self):
+ open_mode = os.O_RDWR | os.O_CREAT | os.O_TRUNC
+
+ try:
+ fd = os.open(self._lock_file, open_mode)
+ except OSError:
+ pass
+ else:
+ try:
+ msvcrt.locking(fd, msvcrt.LK_NBLCK, 1)
+ except (IOError, OSError):
+ os.close(fd)
+ else:
+ self._lock_file_fd = fd
+ return None
+
+ def _release(self):
+ fd = self._lock_file_fd
+ self._lock_file_fd = None
+ msvcrt.locking(fd, msvcrt.LK_UNLCK, 1)
+ os.close(fd)
+
+ try:
+ os.remove(self._lock_file)
+ # Probably another instance of the application
+ # that acquired the file lock.
+ except OSError:
+ pass
+ return None
+
+# Unix locking mechanism
+# ~~~~~~~~~~~~~~~~~~~~~~
+
+class UnixFileLock(BaseFileLock):
+ """
+ Uses the :func:`fcntl.flock` to hard lock the lock file on unix systems.
+ """
+
+ def _acquire(self):
+ open_mode = os.O_RDWR | os.O_CREAT | os.O_TRUNC
+ fd = os.open(self._lock_file, open_mode)
+
+ try:
+ fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
+ except (IOError, OSError):
+ os.close(fd)
+ else:
+ self._lock_file_fd = fd
+ return None
+
+ def _release(self):
+ fd = self._lock_file_fd
+ self._lock_file_fd = None
+ fcntl.flock(fd, fcntl.LOCK_UN)
+ os.close(fd)
+ return None
+
+# Soft lock
+# ~~~~~~~~~
+
+class SoftFileLock(BaseFileLock):
+ """
+ Simply watches the existence of the lock file.
+ """
+
+ def _acquire(self):
+ open_mode = os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_TRUNC
+ try:
+ fd = os.open(self._lock_file, open_mode)
+ except (IOError, OSError):
+ pass
+ else:
+ self._lock_file_fd = fd
+ return None
+
+ def _release(self):
+ os.close(self._lock_file_fd)
+ self._lock_file_fd = None
+
+ try:
+ os.remove(self._lock_file)
+ # The file is already deleted and that's what we want.
+ except OSError:
+ pass
+ return None
+
+
+# Platform filelock
+# ~~~~~~~~~~~~~~~~~
+
+#: Alias for the lock, which should be used for the current platform. On
+#: Windows, this is an alias for :class:`WindowsFileLock`, on Unix for
+#: :class:`UnixFileLock` and otherwise for :class:`SoftFileLock`.
+FileLock = None
+
+if msvcrt:
+ FileLock = WindowsFileLock
+elif fcntl:
+ FileLock = UnixFileLock
+else:
+ FileLock = SoftFileLock
+
+ if warnings is not None:
+ warnings.warn("only soft file lock is available")
diff --git a/tools/js_optimizer.py b/tools/js_optimizer.py
index 1fefa81164b49..58b8d3f65154d 100644
--- a/tools/js_optimizer.py
+++ b/tools/js_optimizer.py
@@ -444,8 +444,11 @@ def write_chunk(chunk, i):
if DEBUG: print >> sys.stderr, 'splitting up js optimization into %d chunks, using %d cores (total: %.2f MB)' % (len(chunks), cores, total_size/(1024*1024.))
pool = multiprocessing.Pool(processes=cores)
filenames = pool.map(run_on_chunk, commands, chunksize=1)
- pool.terminate()
- pool.join()
+ try:
+ pool.terminate()
+ pool.join()
+ except Exception, e:
+ pass
else:
# We can't parallize, but still break into chunks to avoid uglify/node memory issues
if len(chunks) > 1 and DEBUG: print >> sys.stderr, 'splitting up js optimization into %d chunks' % (len(chunks))
From e94457b518b5ce5c56255911110717fe3ae315ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?=
Date: Sun, 19 Jun 2016 22:24:54 +0300
Subject: [PATCH 033/102] Treat cache clear as a non-shared operation, so that
it can forcibly delete the cache lock file, in the case that a previous
forcibly killed process had left it lying around.
---
tools/cache.py | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/tools/cache.py b/tools/cache.py
index a67a8370ea62a..8fb54faefc009 100644
--- a/tools/cache.py
+++ b/tools/cache.py
@@ -21,19 +21,22 @@ def reverse_chop(thestring, ending):
return thestring[:-len(ending)]
return thestring
- self.filelock = filelock.FileLock(reverse_chop(reverse_chop(self.dirname, '/'), '\\') + '.lock')
+ self.filelock_name = reverse_chop(reverse_chop(self.dirname, '/'), '\\') + '.lock'
+ self.filelock = filelock.FileLock(self.filelock_name)
def ensure(self):
with self.filelock:
shared.safe_ensure_dirs(self.dirname)
def erase(self):
- with self.filelock:
- tempfiles.try_delete(self.dirname)
- try:
- open(self.dirname + '__last_clear', 'w').write('last clear: ' + time.asctime() + '\n')
- except Exception, e:
- print >> sys.stderr, 'failed to save last clear time: ', e
+ tempfiles.try_delete(self.dirname)
+ try:
+ open(self.dirname + '__last_clear', 'w').write('last clear: ' + time.asctime() + '\n')
+ except Exception, e:
+ print >> sys.stderr, 'failed to save last clear time: ', e
+ self.filelock = None
+ tempfiles.try_delete(self.filelock_name)
+ self.filelock = filelock.FileLock(self.filelock_name)
def get_path(self, shortname):
return os.path.join(self.dirname, shortname)
From d6f4a9a7e20287d80828233ad26aefc4244222a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?=
Date: Mon, 20 Jun 2016 18:10:12 +0300
Subject: [PATCH 034/102] Improve multithreaded Mandelbrot test to launch
correctly even if pthread pool is not used.
---
tests/pthread/test_pthread_mandelbrot.cpp | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/tests/pthread/test_pthread_mandelbrot.cpp b/tests/pthread/test_pthread_mandelbrot.cpp
index 7539003a1b1fb..5605279175ef8 100644
--- a/tests/pthread/test_pthread_mandelbrot.cpp
+++ b/tests/pthread/test_pthread_mandelbrot.cpp
@@ -281,6 +281,9 @@ pthread_t thread[MAX_NUM_THREADS];
double timeSpentInMandelbrot[MAX_NUM_THREADS] = {};
unsigned long long numIters[MAX_NUM_THREADS] = {};
+uint32_t numThreadsRunning = 0;
+uint32_t maxThreadsRunning = 1;
+
bool use_sse = true;
int tasksDone = 0;
@@ -289,6 +292,7 @@ int tasksPending[MAX_NUM_THREADS] = {};
void *mandelbrot_thread(void *arg)
{
int idx = (int)arg;
+ emscripten_atomic_add_u32(&numThreadsRunning, 1);
char threadName[32];
sprintf(threadName, "Worker %d", idx);
@@ -355,7 +359,7 @@ void register_tasks()
numTasks = EM_ASM_INT_V(return parseInt(document.getElementById('num_threads').value));
if (numTasks < 1) numTasks = 1;
- if (numTasks > MAX_NUM_THREADS) numTasks = MAX_NUM_THREADS;
+ if (numTasks > emscripten_num_logical_cores()) numTasks = emscripten_num_logical_cores();
// Register tasks.
emscripten_atomic_store_u32(&tasksDone, 0);
@@ -374,7 +378,7 @@ void wait_tasks()
// Wait for each task to finish.
for(;;)
{
- int td = tasksDone;
+ int td = emscripten_atomic_load_u32(&tasksDone);
if (td >= numTasks)
break;
emscripten_futex_wait(&tasksDone, td, 1);
@@ -385,6 +389,9 @@ void wait_tasks()
void main_tick()
{
+ const int threadsRunning = emscripten_atomic_load_u32(&numThreadsRunning);
+ if (threadsRunning < maxThreadsRunning) return;
+
wait_tasks();
numItersDoneOnCanvas += numItersPerFrame;
@@ -548,7 +555,8 @@ int main(int argc, char** argv)
outputImage[i] = 0x00000000;
#ifndef SINGLETHREADED
- for(int i = 0; i < MAX_NUM_THREADS; ++i)
+ maxThreadsRunning = emscripten_num_logical_cores() < MAX_NUM_THREADS ? emscripten_num_logical_cores() : MAX_NUM_THREADS;
+ for(int i = 0; i < maxThreadsRunning; ++i)
{
pthread_attr_t attr;
pthread_attr_init(&attr);
From 5f106af2d92aa6d42862bcd05fbf7cae9dc1f30e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?=
Date: Tue, 21 Jun 2016 14:53:18 +0300
Subject: [PATCH 035/102] Add -lpthread library to the list of default
libraries, since it is always present (either in full if -s USE_PTHREADS=1
was passed, or a stub if threading is not enabled)
---
emcc.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/emcc.py b/emcc.py
index 1a396a46005a4..38b5e5ae473e9 100755
--- a/emcc.py
+++ b/emcc.py
@@ -907,7 +907,7 @@ def detect_fixed_language_mode(args):
break
if found: break
if found: break
- if not found and lib not in ['GL', 'GLU', 'glut', 'm', 'c', 'SDL', 'stdc++']: # whitelist our default libraries
+ if not found and lib not in ['GL', 'GLU', 'glut', 'm', 'c', 'SDL', 'stdc++', 'pthread']: # whitelist our default libraries
logging.warning('emcc: cannot find library "%s"', lib)
# If not compiling to JS, then we are compiling to an intermediate bitcode objects or library, so
From 387a47ed28b5daf27895caf18bc296477ba57535 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9gis=20F=C3=A9n=C3=A9on?=
Date: Tue, 31 May 2016 13:03:19 +0200
Subject: [PATCH 036/102] Add support for 'pointerlockerror' event
This was missing from the HTML5 Pointerlock API.
---
site/source/docs/api_reference/html5.h.rst | 35 +++++++-
src/library_html5.js | 43 ++++++++++
src/struct_info.compiled.json | 2 +-
src/struct_info.json | 1 +
system/include/emscripten/html5.h | 4 +
tests/test_html5_pointerlockerror.c | 94 ++++++++++++++++++++++
tests/test_interactive.py | 3 +
7 files changed, 179 insertions(+), 3 deletions(-)
create mode 100644 tests/test_html5_pointerlockerror.c
diff --git a/site/source/docs/api_reference/html5.h.rst b/site/source/docs/api_reference/html5.h.rst
index 5a4079149347f..f30ddf978fff8 100644
--- a/site/source/docs/api_reference/html5.h.rst
+++ b/site/source/docs/api_reference/html5.h.rst
@@ -1246,8 +1246,11 @@ Defines
.. c:macro:: EMSCRIPTEN_EVENT_POINTERLOCKCHANGE
- Emscripten `pointerlockchange `_ events.
-
+ Emscripten `pointerlockchange `_ event.
+
+.. c:macro:: EMSCRIPTEN_EVENT_POINTERLOCKERROR
+
+ Emscripten `pointerlockerror `_ event.
Struct
------
@@ -1291,6 +1294,20 @@ Callback functions
:param void* userData: The ``userData`` originally passed to the registration function.
:returns: |callback-handler-return-value-doc|
:rtype: |EM_BOOL|
+
+.. c:type:: em_pointerlockerror_callback_func
+
+ Function pointer for the :c:func:`pointerlockerror event callback functions `, defined as:
+
+ .. code-block:: cpp
+
+ typedef EM_BOOL (*em_pointerlockerror_callback_func)(int eventType, const void *reserved, void *userData);
+
+ :param int eventType: The type of pointerlockerror event (:c:data:`EMSCRIPTEN_EVENT_POINTERLOCKERROR`).
+ :param const void* reserved: Reserved for future use; pass in 0.
+ :param void* userData: The ``userData`` originally passed to the registration function.
+ :returns: |callback-handler-return-value-doc|
+ :rtype: |EM_BOOL|
@@ -1313,6 +1330,20 @@ Functions
+.. c:function:: EMSCRIPTEN_RESULT emscripten_set_pointerlockerror_callback(const char *target, void *userData, EM_BOOL useCapture, em_pointerlockerror_callback_func callback)
+
+ Registers a callback function for receiving the `pointerlockerror `_ event.
+
+ :param target: |target-parameter-doc|
+ :type target: const char*
+ :param void* userData: |userData-parameter-doc|
+ :param EM_BOOL useCapture: |useCapture-parameter-doc|
+ :param em_pointerlockerror_callback_func callback: |callback-function-parameter-doc|
+ :returns: :c:data:`EMSCRIPTEN_RESULT_SUCCESS`, or one of the other result values.
+ :rtype: |EMSCRIPTEN_RESULT|
+
+
+
.. c:function:: EMSCRIPTEN_RESULT emscripten_get_pointerlock_status(EmscriptenPointerlockChangeEvent *pointerlockStatus)
Returns the current page pointerlock state.
diff --git a/src/library_html5.js b/src/library_html5.js
index 0aee5f13b8c3c..b7fc29135bd85 100644
--- a/src/library_html5.js
+++ b/src/library_html5.js
@@ -732,6 +732,33 @@ var LibraryJSEvents = {
JSEvents.registerOrRemoveHandler(eventHandler);
},
+ registerPointerlockErrorEventCallback: function(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString) {
+ if (!target) {
+ target = document; // Pointer lock events need to be captured from 'document' by default instead of 'window'
+ } else {
+ target = JSEvents.findEventTarget(target);
+ }
+
+ var handlerFunc = function(event) {
+ var e = event || window.event;
+
+ var shouldCancel = Runtime.dynCall('iiii', callbackfunc, [eventTypeId, 0, userData]);
+ if (shouldCancel) {
+ e.preventDefault();
+ }
+ };
+
+ var eventHandler = {
+ target: target,
+ allowsDeferredCalls: false,
+ eventTypeString: eventTypeString,
+ callbackfunc: callbackfunc,
+ handlerFunc: handlerFunc,
+ useCapture: useCapture
+ };
+ JSEvents.registerOrRemoveHandler(eventHandler);
+ },
+
requestPointerLock: function(target) {
if (target.requestPointerLock) {
target.requestPointerLock();
@@ -1545,6 +1572,22 @@ var LibraryJSEvents = {
return {{{ cDefine('EMSCRIPTEN_RESULT_SUCCESS') }}};
},
+ emscripten_set_pointerlockerror_callback: function(target, userData, useCapture, callbackfunc) {
+ if (!document.body.requestPointerLock && !document.body.mozRequestPointerLock && !document.body.webkitRequestPointerLock && !document.body.msRequestPointerLock) {
+ return {{{ cDefine('EMSCRIPTEN_RESULT_NOT_SUPPORTED') }}};
+ }
+ if (!target) target = document;
+ else {
+ target = JSEvents.findEventTarget(target);
+ if (!target) return {{{ cDefine('EMSCRIPTEN_RESULT_UNKNOWN_TARGET') }}};
+ }
+ JSEvents.registerPointerlockErrorEventCallback(target, userData, useCapture, callbackfunc, {{{ cDefine('EMSCRIPTEN_EVENT_POINTERLOCKERROR') }}}, "pointerlockerror");
+ JSEvents.registerPointerlockErrorEventCallback(target, userData, useCapture, callbackfunc, {{{ cDefine('EMSCRIPTEN_EVENT_POINTERLOCKERROR') }}}, "mozpointerlockerror");
+ JSEvents.registerPointerlockErrorEventCallback(target, userData, useCapture, callbackfunc, {{{ cDefine('EMSCRIPTEN_EVENT_POINTERLOCKERROR') }}}, "webkitpointerlockerror");
+ JSEvents.registerPointerlockErrorEventCallback(target, userData, useCapture, callbackfunc, {{{ cDefine('EMSCRIPTEN_EVENT_POINTERLOCKERROR') }}}, "mspointerlockerror");
+ return {{{ cDefine('EMSCRIPTEN_RESULT_SUCCESS') }}};
+ },
+
emscripten_get_pointerlock_status: function(pointerlockStatus) {
if (pointerlockStatus) JSEvents.fillPointerlockChangeEventData(pointerlockStatus);
if (!document.body.requestPointerLock && !document.body.mozRequestPointerLock && !document.body.webkitRequestPointerLock && !document.body.msRequestPointerLock) {
diff --git a/src/struct_info.compiled.json b/src/struct_info.compiled.json
index 09f47d8b882e0..24aafa09a9ba9 100644
--- a/src/struct_info.compiled.json
+++ b/src/struct_info.compiled.json
@@ -1 +1 @@
-{"structs":{"utsname":{"sysname":0,"nodename":65,"domainname":325,"machine":260,"version":195,"release":130,"__size__":390},"sockaddr":{"sa_data":2,"sa_family":0,"__size__":16},"addrinfo":{"ai_flags":0,"ai_next":28,"ai_canonname":24,"ai_socktype":8,"ai_addr":20,"ai_protocol":12,"ai_family":4,"ai_addrlen":16,"__size__":32},"timespec":{"tv_sec":0,"tv_nsec":4,"__size__":8},"utimbuf":{"modtime":4,"actime":0,"__size__":8},"EmscriptenVisibilityChangeEvent":{"hidden":0,"visibilityState":4,"__size__":8},"SDL_MouseButtonEvent":{"timestamp":4,"button":16,"state":17,"windowID":8,"which":12,"y":24,"x":20,"padding2":19,"type":0,"padding1":18,"__size__":28},"sockaddr_in":{"sin_port":2,"sin_addr":{"s_addr":4,"__size__":4},"sin_family":0,"sin_zero":8,"__size__":16},"pthread":{"tsd":116,"attr":120,"canceldisable":72,"threadStatus":0,"tsd_used":56,"pid":52,"stack":92,"cancelasync":76,"tid":48,"threadExitCode":4,"detached":80,"profilerBlock":20,"self":24,"stack_size":96,"__size__":216},"WebVRFieldOfView":{"leftDegrees":24,"upDegrees":0,"downDegrees":16,"rightDegrees":8,"__size__":32},"SDL_KeyboardEvent":{"repeat":9,"keysym":12,"state":8,"windowID":4,"__size__":28,"type":0,"padding3":11,"padding2":10},"SDL_MouseMotionEvent":{"yrel":32,"timestamp":4,"state":16,"windowID":8,"which":12,"xrel":28,"y":24,"x":20,"type":0,"__size__":36},"SDL_Rect":{"y":4,"x":0,"h":12,"w":8,"__size__":16},"itimerspec":{"it_interval":{"tv_sec":0,"tv_nsec":4,"__size__":8},"it_value":{"tv_sec":8,"tv_nsec":12,"__size__":8},"__size__":16},"iovec":{"iov_len":4,"iov_base":0,"__size__":8},"timezone":{"tz_dsttime":4,"tz_minuteswest":0,"__size__":8},"flock":{"l_whence":2,"l_type":0,"l_start":4,"__size__":16,"l_len":8,"l_pid":12},"EmscriptenOrientationChangeEvent":{"orientationIndex":0,"orientationAngle":4,"__size__":8},"EmscriptenMouseEvent":{"clientX":16,"clientY":20,"targetX":52,"buttons":42,"timestamp":0,"button":40,"targetY":56,"altKey":32,"canvasY":64,"metaKey":36,"movementX":44,"movementY":48,"shiftKey":28,"ctrlKey":24,"screenY":12,"screenX":8,"canvasX":60,"__size__":72},"SDL_ResizeEvent":{"h":8,"type":0,"w":4,"__size__":12},"tms":{"tms_stime":4,"tms_utime":0,"tms_cstime":12,"tms_cutime":8,"__size__":16},"SDL_Color":{"unused":3,"r":0,"b":2,"g":1,"__size__":4},"EmscriptenKeyboardEvent":{"code":32,"charValue":120,"locale":88,"shiftKey":72,"altKey":76,"which":160,"metaKey":80,"location":64,"key":0,"ctrlKey":68,"charCode":152,"keyCode":156,"repeat":84,"__size__":164},"rusage":{"ru_msgrcv":56,"ru_utime":{"tv_sec":0,"tv_usec":4,"__size__":8},"ru_isrss":28,"ru_stime":{"tv_sec":8,"tv_usec":12,"__size__":8},"ru_nsignals":60,"ru_nivcsw":68,"ru_msgsnd":52,"ru_nswap":40,"ru_minflt":32,"ru_nvcsw":64,"ru_ixrss":20,"ru_inblock":44,"ru_idrss":24,"ru_maxrss":16,"ru_oublock":48,"ru_majflt":36,"__size__":136},"div_t":{"quot":0,"rem":4,"__size__":8},"timeval":{"tv_sec":0,"tv_usec":4,"__size__":8},"rlimit":{"rlim_cur":0,"rlim_max":8,"__size__":16},"in6_addr":{"__in6_union":{"__s6_addr16":0,"__s6_addr":0,"__s6_addr32":0,"__size__":16},"__size__":16},"tm":{"tm_sec":0,"tm_hour":8,"tm_mday":12,"tm_isdst":32,"tm_year":20,"tm_zone":40,"tm_mon":16,"tm_yday":28,"tm_gmtoff":36,"tm_wday":24,"tm_min":4,"__size__":44},"EmscriptenWebGLContextAttributes":{"majorVersion":32,"stencil":8,"preserveDrawingBuffer":20,"failIfMajorPerformanceCaveat":28,"antialias":12,"depth":4,"minorVersion":36,"premultipliedAlpha":16,"enableExtensionsByDefault":40,"alpha":0,"preferLowPowerToHighPerformance":24,"__size__":44},"EmscriptenBatteryEvent":{"dischargingTime":8,"level":16,"charging":24,"chargingTime":0,"__size__":32},"protoent":{"p_aliases":4,"p_proto":8,"p_name":0,"__size__":12},"SDL_Surface":{"userdata":24,"locked":28,"clip_rect":36,"format":4,"h":12,"refcount":56,"map":52,"flags":0,"w":8,"pitch":16,"lock_data":32,"pixels":20,"__size__":60},"EmscriptenTouchEvent":{"touches":20,"shiftKey":8,"altKey":12,"metaKey":16,"ctrlKey":4,"__size__":1684,"numTouches":0},"dirent":{"d_name":11,"d_off":4,"d_ino":0,"d_reclen":8,"d_type":10,"__size__":268},"sockaddr_in6":{"sin6_family":0,"sin6_flowinfo":4,"sin6_scope_id":24,"sin6_addr":{"__in6_union":{"__s6_addr16":8,"__s6_addr":8,"__s6_addr32":8,"__size__":16},"__size__":16},"__size__":28,"sin6_port":2},"SDL_JoyAxisEvent":{"__size__":12,"type":0,"value":8,"which":4,"padding2":7,"padding1":6,"axis":5},"netent":{"n_name":0,"n_net":12,"n_addrtype":8,"n_aliases":4,"__size__":16},"SDL_PixelFormat":{"palette":4,"Gloss":29,"Bmask":20,"Bloss":30,"Rloss":28,"format":0,"Gshift":33,"Aloss":31,"BitsPerPixel":8,"refcount":36,"next":40,"padding":10,"Rmask":12,"Bshift":34,"Gmask":16,"BytesPerPixel":9,"Amask":24,"Rshift":32,"Ashift":35,"__size__":44},"SDL_JoyButtonEvent":{"type":0,"button":5,"state":6,"which":4,"padding1":7,"__size__":8},"EmscriptenPointerlockChangeEvent":{"id":132,"nodeName":4,"isActive":0,"__size__":260},"in_addr":{"s_addr":0,"__size__":4},"EmscriptenDeviceOrientationEvent":{"timestamp":0,"beta":16,"alpha":8,"__size__":40,"gamma":24,"absolute":32},"SDL_WindowEvent":{"data2":16,"type":0,"data1":12,"windowID":4,"__size__":20,"padding1":9,"event":8,"padding3":11,"padding2":10},"SDL_Keysym":{"scancode":0,"mod":8,"unicode":12,"sym":4,"__size__":16},"cmsghdr":{"cmsg_type":8,"cmsg_level":4,"cmsg_len":0,"__size__":12},"EmscriptenUiEvent":{"windowInnerWidth":12,"detail":0,"scrollLeft":32,"documentBodyClientHeight":8,"windowInnerHeight":16,"scrollTop":28,"windowOuterHeight":24,"windowOuterWidth":20,"documentBodyClientWidth":4,"__size__":36},"thread_profiler_block":{"threadStatus":0,"timeSpentInStatus":16,"currentStatusStartTime":8,"name":72,"__size__":104},"stat":{"st_rdev":28,"st_mtim":{"tv_sec":56,"tv_nsec":60,"__size__":8},"st_blocks":44,"st_atim":{"tv_sec":48,"tv_nsec":52,"__size__":8},"st_nlink":16,"__st_ino_truncated":8,"st_ctim":{"tv_sec":64,"tv_nsec":68,"__size__":8},"st_mode":12,"st_blksize":40,"__st_dev_padding":4,"st_dev":0,"st_size":36,"st_gid":24,"__st_rdev_padding":32,"st_uid":20,"st_ino":72,"__size__":76},"pollfd":{"fd":0,"events":4,"revents":6,"__size__":8},"WebVRPositionState":{"linearVelocity":{"y":56,"x":48,"z":64,"w":72,"__size__":32},"orientation":{"y":128,"x":120,"z":136,"w":144,"__size__":32},"timeStamp":0,"angularVelocity":{"y":160,"x":152,"z":168,"w":176,"__size__":32},"hasPosition":8,"angularAcceleration":{"y":192,"x":184,"z":200,"w":208,"__size__":32},"linearAcceleration":{"y":88,"x":80,"z":96,"w":104,"__size__":32},"hasOrientation":112,"position":{"y":24,"x":16,"z":32,"w":40,"__size__":32},"__size__":216},"SDL_TextInputEvent":{"text":8,"windowID":4,"type":0,"__size__":40},"EmscriptenTouchPoint":{"clientX":12,"clientY":16,"identifier":0,"targetX":36,"targetY":40,"isChanged":28,"canvasY":48,"canvasX":44,"pageX":20,"pageY":24,"screenY":8,"screenX":4,"onTarget":32,"__size__":52},"EmscriptenDeviceMotionEvent":{"timestamp":0,"accelerationIncludingGravityZ":48,"accelerationIncludingGravityX":32,"accelerationIncludingGravityY":40,"accelerationY":16,"accelerationX":8,"rotationRateBeta":64,"accelerationZ":24,"rotationRateGamma":72,"rotationRateAlpha":56,"__size__":80},"SDL_AudioSpec":{"padding":10,"userdata":20,"format":4,"channels":6,"callback":16,"samples":8,"freq":0,"size":12,"silence":7,"__size__":24},"hostent":{"h_addrtype":8,"h_addr_list":16,"h_name":0,"__size__":20,"h_aliases":4,"h_length":12},"SDL_MouseWheelEvent":{"timestamp":4,"windowID":8,"which":12,"y":20,"x":16,"type":0,"__size__":24},"EmscriptenFocusEvent":{"id":128,"nodeName":0,"__size__":256},"SDL_version":{"major":0,"patch":2,"minor":1,"__size__":3},"statvfs":{"f_bsize":0,"f_bavail":16,"f_fsid":32,"f_favail":28,"f_files":20,"f_frsize":4,"f_blocks":8,"f_ffree":24,"f_bfree":12,"f_flag":40,"f_namemax":44,"__size__":72},"linger":{"l_onoff":0,"l_linger":4,"__size__":8},"EmscriptenFullscreenChangeEvent":{"elementWidth":264,"screenWidth":272,"nodeName":8,"elementHeight":268,"fullscreenEnabled":4,"screenHeight":276,"isFullscreen":0,"id":136,"__size__":280},"EmscriptenWheelEvent":{"deltaX":72,"deltaY":80,"deltaZ":88,"deltaMode":96,"mouse":0,"__size__":104},"WebVRIntRect":{"y":4,"x":0,"height":12,"width":8,"__size__":16},"SDL_TouchFingerEvent":{"timestamp":4,"dy":36,"touchId":8,"pressure":40,"dx":32,"type":0,"y":28,"x":24,"fingerId":16,"__size__":48},"SDL_AudioCVT":{"len_ratio":32,"len_cvt":24,"rate_incr":8,"filters":40,"len":20,"needed":0,"filter_index":80,"src_format":4,"len_mult":28,"__size__":88,"buf":16,"dst_format":6},"WebVRPoint":{"y":8,"x":0,"z":16,"w":24,"__size__":32},"statfs":{"f_bsize":4,"f_bavail":16,"f_fsid":28,"f_files":20,"f_frsize":40,"f_namelen":36,"f_blocks":8,"f_ffree":24,"f_bfree":12,"f_flags":44,"__size__":64},"msghdr":{"msg_iov":8,"msg_iovlen":12,"msg_namelen":4,"msg_controllen":20,"msg_flags":24,"msg_name":0,"msg_control":16,"__size__":28},"EmscriptenGamepadEvent":{"index":1300,"analogButton":528,"timestamp":0,"numButtons":12,"mapping":1368,"digitalButton":1040,"connected":1296,"numAxes":8,"__size__":1432,"id":1304,"axis":16},"SDL_Palette":{"ncolors":0,"colors":4,"version":8,"refcount":12,"__size__":16},"EmscriptenFullscreenStrategy":{"canvasResizedCallbackUserData":16,"canvasResolutionScaleMode":4,"scaleMode":0,"canvasResizedCallback":12,"filteringMode":8,"__size__":20},"timeb":{"dstflag":8,"timezone":6,"time":0,"millitm":4,"__size__":12},"WebVREyeParameters":{"currentFieldOfView":{"leftDegrees":152,"upDegrees":128,"downDegrees":144,"rightDegrees":136,"__size__":32},"recommendedFieldOfView":{"leftDegrees":88,"upDegrees":64,"downDegrees":80,"rightDegrees":72,"__size__":32},"eyeTranslation":{"y":104,"x":96,"z":112,"w":120,"__size__":32},"renderRect":{"y":164,"x":160,"height":172,"width":168,"__size__":16},"minimumFieldOfView":{"leftDegrees":24,"upDegrees":0,"downDegrees":16,"rightDegrees":8,"__size__":32},"maximumFieldOfView":{"leftDegrees":56,"upDegrees":32,"downDegrees":48,"rightDegrees":40,"__size__":32},"__size__":176}},"defines":{"ETXTBSY":26,"EOF":-1,"EMSCRIPTEN_EVENT_MOUSEOVER":35,"ETOOMANYREFS":109,"ENAMETOOLONG":36,"ENOPKG":65,"UUID_TYPE_DCE_TIME":1,"_SC_XOPEN_LEGACY":129,"_SC_XOPEN_VERSION":89,"F_UNLCK":2,"_SC_BC_DIM_MAX":37,"EL3HLT":46,"S_IFDIR":16384,"EMSCRIPTEN_EVENT_KEYPRESS":1,"EINPROGRESS":115,"_SC_BARRIERS":133,"EMSCRIPTEN_EVENT_TOUCHMOVE":24,"SDL_AUDIO_ALLOW_FREQUENCY_CHANGE":1,"AUDIO_U8":8,"EAI_AGAIN":-3,"_PC_MAX_CANON":1,"ENOTSUP":95,"EFBIG":27,"O_CREAT":64,"_SC_2_PBS_LOCATE":170,"EM_PROXIED_SETENV":113,"_CS_POSIX_V6_LP64_OFF64_LIBS":1126,"ENOLINK":67,"ABDAY_7":131078,"ABDAY_6":131077,"ABDAY_5":131076,"ABDAY_4":131075,"ABDAY_3":131074,"ABDAY_2":131073,"ABDAY_1":131072,"EL3RST":47,"YESEXPR":327680,"_SC_V6_ILP32_OFFBIG":177,"SDL_MINOR_VERSION":3,"EM_PROXIED_CLEARENV":112,"_SC_MEMLOCK":17,"ENOTUNIQ":76,"EMSCRIPTEN_RESULT_FAILED":-6,"ABMON_1":131086,"ELNRNG":48,"UUID_VARIANT_MICROSOFT":2,"EMSCRIPTEN_EVENT_TOUCHSTART":22,"ENOANO":55,"EMSCRIPTEN_EVENT_FOCUSIN":14,"EMSCRIPTEN_EVENT_MOUSEUP":6,"ENOPROTOOPT":92,"POLLIN":1,"S_IALLUGO":4095,"_SC_THREAD_KEYS_MAX":74,"EM_THREAD_STATUS_WAITPROXY":5,"O_RDWR":2,"EREMCHG":78,"EMSCRIPTEN_EVENT_GAMEPADDISCONNECTED":27,"_SC_2_PBS":168,"_SC_TRACE_INHERIT":183,"_SC_REGEXP":155,"_CS_POSIX_V6_LP64_OFF64_CFLAGS":1124,"_SC_DELAYTIMER_MAX":26,"S_IWUGO":146,"S_IFREG":32768,"F_GETLK64":12,"O_DIRECTORY":65536,"EM_PROXIED_UTIMES":13,"POLLHUP":16,"S_IFMT":61440,"F_SETLK64":13,"_SC_XOPEN_CRYPT":92,"_SC_CLOCK_SELECTION":137,"_PC_CHOWN_RESTRICTED":6,"E2BIG":7,"ABMON_3":131088,"AM_STR":131110,"SDL_AUDIO_MASK_ENDIAN":4096,"ALT_DIGITS":131119,"EHOSTDOWN":112,"EBFONT":59,"ENOTEMPTY":39,"AUDIO_S16":32784,"TIOCGPGRP":21519,"EBUSY":16,"_SC_MQ_PRIO_MAX":28,"_SC_PAGE_SIZE":30,"EADDRINUSE":98,"ENOTSOCK":88,"PM_STR":131111,"O_WRONLY":1,"_SC_STREAM_MAX":5,"ABMON_9":131094,"ELIBACC":79,"S_IFIFO":4096,"EDQUOT":122,"EAI_SYSTEM":-11,"ENOENT":2,"_SC_TIMERS":11,"O_SYNC":1052672,"SEEK_END":2,"EM_THREAD_STATUS_FINISHED":6,"_PC_REC_MIN_XFER_SIZE":16,"_PC_PATH_MAX":4,"_SC_SPORADIC_SERVER":160,"ECOMM":70,"_SC_NPROCESSORS_ONLN":84,"_CS_POSIX_V6_LPBIG_OFFBIG_LIBS":1130,"_PC_MAX_INPUT":2,"_SC_VERSION":29,"_SC_XBS5_LPBIG_OFFBIG":128,"_SC_CLK_TCK":2,"ABMON_2":131087,"EXFULL":54,"ABMON_7":131092,"ABMON_6":131091,"ABMON_5":131090,"ABMON_4":131089,"ENOTDIR":20,"ABMON_8":131093,"_SC_AIO_MAX":24,"ERA":131116,"EM_PROXIED_UNSETENV":114,"_SC_THREAD_PRIO_INHERIT":80,"_PC_2_SYMLINKS":20,"_SC_XBS5_LP64_OFF64":127,"EMSCRIPTEN_EVENT_BATTERYLEVELCHANGE":30,"ENETRESET":102,"EAFNOSUPPORT":97,"MON_2":131099,"MON_3":131100,"MON_1":131098,"EMSCRIPTEN_EVENT_DEVICEORIENTATION":16,"MON_7":131104,"MON_4":131101,"MON_5":131102,"_SC_SPAWN":159,"MON_8":131105,"MON_9":131106,"_CS_POSIX_V6_ILP32_OFF32_LDFLAGS":1117,"S_IFSOCK":49152,"S_IRUGO":292,"SOCK_DGRAM":2,"POLLERR":8,"EINVAL":22,"_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS":1128,"POLLRDNORM":64,"AUDIO_F32SYS":33056,"_SC_TRACE_SYS_MAX":244,"AI_V4MAPPED":8,"AI_NUMERICHOST":4,"_CS_POSIX_V6_WIDTH_RESTRICTED_ENVS":1,"EHOSTUNREACH":113,"ENOCSI":50,"EPROTONOSUPPORT":93,"_SC_AIO_PRIO_DELTA_MAX":25,"_SC_MONOTONIC_CLOCK":149,"ETIME":62,"ENOTTY":25,"_SC_XOPEN_ENH_I18N":93,"EAI_SERVICE":-8,"EAGAIN":11,"F_SETLKW64":14,"EMSGSIZE":90,"ELIBEXEC":83,"_SC_MEMORY_PROTECTION":19,"EMSCRIPTEN_FULLSCREEN_SCALE_CENTER":3,"SDL_AUDIO_ALLOW_FORMAT_CHANGE":2,"ECANCELED":125,"_SC_SPIN_LOCKS":154,"_SC_XOPEN_SHM":94,"_PC_LINK_MAX":0,"TIOCSPGRP":21520,"EOPNOTSUPP":95,"EMSCRIPTEN_EVENT_MOUSEENTER":33,"EAI_FAIL":-4,"NOEXPR":327681,"_SC_FSYNC":15,"_SC_GETGR_R_SIZE_MAX":69,"EDESTADDRREQ":89,"EADDRNOTAVAIL":99,"AUDIO_S32SYS":32800,"_SC_TRACE_NAME_MAX":243,"_SC_BC_BASE_MAX":36,"EMSCRIPTEN_EVENT_CANVASRESIZED":37,"EPERM":1,"EAI_FAMILY":-6,"O_NOFOLLOW":131072,"SOCK_STREAM":1,"O_APPEND":1024,"_SC_XOPEN_STREAMS":246,"_SC_GETPW_R_SIZE_MAX":70,"MON_6":131103,"EPROTOTYPE":91,"_SC_CPUTIME":138,"EISCONN":106,"_SC_XBS5_ILP32_OFFBIG":126,"S_IFBLK":24576,"T_FMT_AMPM":131115,"EM_PROXIED_FPATHCONF":46,"F_SETLKW":14,"SDL_TOUCH_MOUSEID":-1,"EMSCRIPTEN_EVENT_SCROLL":11,"ELOOP":40,"_SC_OPEN_MAX":4,"_SC_2_FORT_RUN":50,"EMSCRIPTEN_EVENT_VISIBILITYCHANGE":21,"EREMOTE":66,"_SC_RE_DUP_MAX":44,"_SC_THREAD_PRIO_PROTECT":81,"_SC_2_PBS_CHECKPOINT":175,"_SC_2_PBS_TRACK":172,"MON_10":131107,"MON_11":131108,"MON_12":131109,"TCGETS":21505,"_SC_THREAD_PROCESS_SHARED":82,"AF_INET":2,"_SC_SHARED_MEMORY_OBJECTS":22,"F_GETFD":1,"EMSCRIPTEN_EVENT_DEVICEMOTION":17,"SDL_MIX_MAXVOLUME":128,"_PC_ALLOC_SIZE_MIN":18,"TCSETS":21506,"ELIBMAX":82,"_SC_READER_WRITER_LOCKS":153,"EMULTIHOP":72,"_SC_PHYS_PAGES":85,"_SC_MEMLOCK_RANGE":18,"_SC_PRIORITY_SCHEDULING":10,"T_FMT":131114,"AI_ALL":16,"_PC_VDISABLE":8,"THOUSEP":65537,"_SC_TRACE_EVENT_FILTER":182,"ERA_T_FMT":131121,"_SC_THREAD_ATTR_STACKADDR":77,"_SC_THREAD_THREADS_MAX":76,"_SC_LOGIN_NAME_MAX":71,"_SC_2_C_BIND":47,"_PC_NO_TRUNC":7,"ECONNABORTED":103,"EMSCRIPTEN_RESULT_SUCCESS":0,"_SC_SHELL":157,"EFAULT":14,"_SC_V6_LP64_OFF64":178,"_CS_GNU_LIBC_VERSION":2,"ENODATA":61,"_SC_SEM_VALUE_MAX":33,"_SC_MQ_OPEN_MAX":27,"AI_ADDRCONFIG":32,"_SC_HOST_NAME_MAX":180,"_SC_THREAD_STACK_MIN":75,"_SC_TIMEOUTS":164,"POLLOUT":4,"_SC_IPV6":235,"_SC_CHILD_MAX":1,"EDOM":33,"_SC_2_PBS_MESSAGE":171,"EILSEQ":84,"UUID_VARIANT_DCE":1,"_SC_2_C_DEV":48,"_SC_TIMER_MAX":35,"FP_ZERO":2,"EPFNOSUPPORT":96,"ENONET":64,"ECHRNG":44,"_SC_THREADS":67,"_SC_REALTIME_SIGNALS":9,"CLOCKS_PER_SEC":1000000,"ERA_D_T_FMT":131120,"ESRCH":3,"D_FMT":131113,"POLLPRI":2,"_PC_ASYNC_IO":10,"DAY_2":131080,"DAY_3":131081,"DAY_1":131079,"DAY_6":131084,"DAY_7":131085,"DAY_4":131082,"DAY_5":131083,"_SC_SYNCHRONIZED_IO":14,"EL2HLT":51,"EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF":1,"IPPROTO_UDP":17,"_SC_MAPPED_FILES":16,"EL2NSYNC":45,"_SC_NGROUPS_MAX":3,"ENOMSG":42,"EISDIR":21,"_SC_SEMAPHORES":21,"AI_NUMERICSERV":1024,"EDEADLOCK":35,"EMSCRIPTEN_EVENT_WEBGLCONTEXTLOST":31,"EMSCRIPTEN_EVENT_BATTERYCHARGINGCHANGE":29,"AUDIO_F32LSB":33056,"_SC_COLL_WEIGHTS_MAX":40,"SO_ERROR":4,"ECONNRESET":104,"AT_SYMLINK_NOFOLLOW":256,"_SC_TRACE_LOG":184,"AUDIO_U16LSB":16,"ESTRPIPE":86,"ESHUTDOWN":108,"_PC_SOCK_MAXBUF":12,"_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS":1129,"EDEADLK":35,"_CS_POSIX_V6_ILP32_OFF32_CFLAGS":1116,"EBADRQC":56,"_SC_THREAD_DESTRUCTOR_ITERATIONS":73,"_SC_TYPED_MEMORY_OBJECTS":165,"_SC_TRACE_EVENT_NAME_MAX":242,"_SC_BC_STRING_MAX":39,"_SC_2_SW_DEV":51,"FP_NAN":0,"F_SETOWN":8,"EMSCRIPTEN_EVENT_RESIZE":10,"_SC_ARG_MAX":0,"_SC_THREAD_PRIORITY_SCHEDULING":79,"F_GETLK":12,"EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF":2,"FIONREAD":21531,"_SC_THREAD_CPUTIME":139,"EMSCRIPTEN_EVENT_POINTERLOCKCHANGE":20,"EM_THREAD_STATUS_NOTSTARTED":0,"_CS_POSIX_V6_ILP32_OFF32_LIBS":1118,"EUNATCH":49,"AUDIO_S8":32776,"AUDIO_S32LSB":32800,"SDL_AUDIO_MASK_BITSIZE":255,"ERA_D_FMT":131118,"AUDIO_F32MSB":37152,"_CS_POSIX_V6_LP64_OFF64_LDFLAGS":1125,"FP_INFINITE":1,"ECHILD":10,"EAI_MEMORY":-10,"O_TRUNC":512,"ETIMEDOUT":110,"EALREADY":114,"ENXIO":6,"NI_NUMERICHOST":1,"EMFILE":24,"F_GETOWN":9,"EMLINK":31,"F_SETFD":2,"ENFILE":23,"EM_PROXIED_SYSCONF":72,"EM_PROXIED_GETENV":111,"SDL_MAJOR_VERSION":1,"ENOMEM":12,"ENOSR":63,"SDL_AUDIO_ALLOW_ANY_CHANGE":7,"EOWNERDEAD":130,"_PC_PRIO_IO":11,"ELIBSCN":81,"_SC_V6_LPBIG_OFFBIG":179,"EM_PROXIED_CHROOT":37,"EMSCRIPTEN_EVENT_CLICK":4,"EPIPE":32,"_SC_EXPR_NEST_MAX":42,"_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS":1120,"EBADSLT":57,"AUDIO_S16MSB":36880,"S_ISVTX":512,"EMSCRIPTEN_RESULT_DEFERRED":1,"EMSCRIPTEN_RESULT_UNKNOWN_TARGET":-4,"S_IRWXUGO":511,"EM_PROXIED_TZSET":119,"_CS_GNU_LIBPTHREAD_VERSION":3,"_PC_REC_MAX_XFER_SIZE":15,"UUID_VARIANT_OTHER":3,"EMSCRIPTEN_EVENT_WEBGLCONTEXTRESTORED":32,"EM_PROXIED_PTHREAD_CREATE":137,"EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT":0,"RADIXCHAR":65536,"AF_UNSPEC":0,"ENOSTR":60,"W_OK":2,"AUDIO_S32":32800,"EACCES":13,"R_OK":4,"S_IRWXO":7,"_SC_V6_ILP32_OFF32":176,"EMSCRIPTEN_EVENT_FULLSCREENCHANGE":19,"EIO":5,"EMSCRIPTEN_RESULT_NOT_SUPPORTED":-1,"EM_PROXIED_CONFSTR":68,"_SC_SIGQUEUE_MAX":34,"EWOULDBLOCK":11,"AUDIO_U16SYS":16,"EMSCRIPTEN_EVENT_FOCUSOUT":15,"EAI_OVERFLOW":-12,"SDL_AUDIO_MASK_DATATYPE":256,"MAP_PRIVATE":2,"_SC_TZNAME_MAX":6,"_CS_PATH":0,"SEEK_SET":0,"EBADE":52,"EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED":-2,"INT_MAX":2147483647,"EMSCRIPTEN_EVENT_KEYDOWN":2,"EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH":1,"_SC_MESSAGE_PASSING":20,"_SC_THREAD_SAFE_FUNCTIONS":68,"_SC_SYMLOOP_MAX":173,"_PC_NAME_MAX":3,"O_EXCL":128,"_SC_TRACE_USER_EVENT_MAX":245,"_PC_REC_XFER_ALIGN":17,"EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT":0,"_SC_RAW_SOCKETS":236,"_SC_2_UPE":97,"EMSCRIPTEN_RESULT_NO_DATA":-7,"EMSCRIPTEN_EVENT_BLUR":12,"_SC_RTSIG_MAX":31,"ESOCKTNOSUPPORT":94,"_SC_PRIORITIZED_IO":13,"_SC_XOPEN_UNIX":91,"CODESET":14,"IPPROTO_TCP":6,"_PC_REC_INCR_XFER_SIZE":14,"F_SETLK":13,"_PC_FILESIZEBITS":13,"_SC_XBS5_ILP32_OFF32":125,"RAND_MAX":2147483647,"EM_PROXIED_SYSCALL":138,"ENOLCK":37,"EM_PROXIED_PUTENV":115,"AUDIO_U16":16,"EMSCRIPTEN_EVENT_MOUSELEAVE":34,"EMSCRIPTEN_EVENT_MOUSEOUT":36,"_SC_2_VERSION":46,"_PC_SYNC_IO":9,"EEXIST":17,"FP_NORMAL":4,"O_RDONLY":0,"_SC_SEM_NSEMS_MAX":32,"_SC_IOV_MAX":60,"EPROTO":71,"_SC_TRACE":181,"ESRMNT":69,"_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS":1121,"SDL_PIXELFORMAT_RGBA8888":-2042224636,"INADDR_LOOPBACK":2130706433,"EXDEV":18,"EM_THREAD_STATUS_RUNNING":1,"EMSCRIPTEN_EVENT_BEFOREUNLOAD":28,"EM_THREAD_STATUS_WAITFUTEX":3,"EMSCRIPTEN_RESULT_INVALID_TARGET":-3,"_SC_THREAD_SPORADIC_SERVER":161,"F_SETFL":4,"AI_PASSIVE":1,"ELIBBAD":80,"_SC_LINE_MAX":43,"D_T_FMT":131112,"ERANGE":34,"ESTALE":116,"F_DUPFD":0,"AUDIO_F32":33056,"CLOCK_MONOTONIC":1,"EMSCRIPTEN_EVENT_GAMEPADCONNECTED":26,"F_GETOWN_EX":16,"_SC_ASYNCHRONOUS_IO":12,"ENOTRECOVERABLE":131,"ENOBUFS":105,"EIDRM":43,"EMSCRIPTEN_EVENT_ORIENTATIONCHANGE":18,"CRNCYSTR":262159,"EINTR":4,"EADV":68,"ENOSYS":38,"_CS_POSIX_V6_ILP32_OFFBIG_LIBS":1122,"EM_PROXIED_UTIME":12,"F_GETFL":3,"S_IXUGO":73,"_SC_2_FORT_DEV":49,"SDL_COMPILEDVERSION":1300,"EBADMSG":74,"EUSERS":87,"CLOCK_REALTIME":0,"ENODEV":19,"AF_INET6":10,"_SC_ATEXIT_MAX":87,"_SC_SAVED_IDS":8,"SOL_SOCKET":1,"S_IFLNK":40960,"AUDIO_S16LSB":32784,"POLLNVAL":32,"EMSCRIPTEN_EVENT_TOUCHCANCEL":25,"EMSCRIPTEN_RESULT_INVALID_PARAM":-5,"EMSCRIPTEN_EVENT_MOUSEDOWN":5,"EM_THREAD_STATUS_SLEEPING":2,"_SC_JOB_CONTROL":7,"NI_NAMEREQD":8,"EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT":2,"EMSCRIPTEN_EVENT_MOUSEMOVE":8,"UUID_TYPE_DCE_RANDOM":4,"ENOTCONN":107,"_SC_ADVISORY_INFO":132,"ENETUNREACH":101,"_SC_XOPEN_REALTIME_THREADS":131,"_SC_2_LOCALEDEF":52,"_PC_SYMLINK_MAX":19,"X_OK":1,"EMSCRIPTEN_EVENT_KEYUP":3,"AI_CANONNAME":2,"UUID_VARIANT_NCS":0,"ESPIPE":29,"AUDIO_S32MSB":36896,"EMSCRIPTEN_EVENT_WHEEL":9,"SDL_AUDIO_ALLOW_CHANNELS_CHANGE":4,"_SC_XOPEN_REALTIME":130,"EAI_NONAME":-2,"_PC_PIPE_BUF":5,"EROFS":30,"EM_PROXIED_ATEXIT":110,"ECONNREFUSED":111,"_SC_2_PBS_ACCOUNTING":169,"EMSCRIPTEN_EVENT_FOCUS":13,"AUDIO_S16SYS":32784,"ENETDOWN":100,"ENOEXEC":8,"ENOSPC":28,"EBADF":9,"EAI_SOCKTYPE":-7,"EDOTDOT":73,"_SC_THREAD_ATTR_STACKSIZE":78,"EBADFD":77,"O_ACCMODE":2097155,"EBADR":53,"EM_PROXIED_SBRK":73,"S_IFCHR":8192,"SDL_PATCHLEVEL":0,"ABMON_12":131097,"PTHREAD_KEYS_MAX":128,"ENOMEDIUM":123,"EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE":0,"AUDIO_U16MSB":4112,"EMSCRIPTEN_FULLSCREEN_FILTERING_BILINEAR":2,"_SC_2_CHAR_TERM":95,"EMSCRIPTEN_EVENT_TOUCHEND":23,"_SC_AIO_LISTIO_MAX":23,"_SC_BC_SCALE_MAX":38,"ENOTBLK":15,"EAI_BADFLAGS":-1,"EOVERFLOW":75,"EMSCRIPTEN_EVENT_DBLCLICK":7,"SDL_AUDIO_MASK_SIGNED":32768,"EMSCRIPTEN_FULLSCREEN_FILTERING_NEAREST":1,"ABMON_11":131096,"ABMON_10":131095,"AT_FDCWD":-100,"_SC_TTY_NAME_MAX":72}}
\ No newline at end of file
+{"structs":{"utsname":{"sysname":0,"nodename":65,"domainname":325,"machine":260,"version":195,"release":130,"__size__":390},"sockaddr":{"sa_data":2,"sa_family":0,"__size__":16},"addrinfo":{"ai_flags":0,"ai_next":28,"ai_canonname":24,"ai_socktype":8,"ai_addr":20,"ai_protocol":12,"ai_family":4,"ai_addrlen":16,"__size__":32},"timespec":{"tv_sec":0,"tv_nsec":4,"__size__":8},"utimbuf":{"modtime":4,"actime":0,"__size__":8},"EmscriptenVisibilityChangeEvent":{"hidden":0,"visibilityState":4,"__size__":8},"SDL_MouseButtonEvent":{"timestamp":4,"button":16,"state":17,"windowID":8,"which":12,"y":24,"x":20,"padding2":19,"type":0,"padding1":18,"__size__":28},"sockaddr_in":{"sin_port":2,"sin_addr":{"s_addr":4,"__size__":4},"sin_family":0,"sin_zero":8,"__size__":16},"pthread":{"tsd":116,"attr":120,"canceldisable":72,"threadStatus":0,"tsd_used":56,"pid":52,"stack":92,"cancelasync":76,"tid":48,"threadExitCode":4,"detached":80,"profilerBlock":20,"self":24,"stack_size":96,"__size__":216},"WebVRFieldOfView":{"leftDegrees":24,"upDegrees":0,"downDegrees":16,"rightDegrees":8,"__size__":32},"SDL_KeyboardEvent":{"repeat":9,"keysym":12,"state":8,"windowID":4,"__size__":28,"type":0,"padding3":11,"padding2":10},"SDL_MouseMotionEvent":{"yrel":32,"timestamp":4,"state":16,"windowID":8,"which":12,"xrel":28,"y":24,"x":20,"type":0,"__size__":36},"SDL_Rect":{"y":4,"x":0,"h":12,"w":8,"__size__":16},"itimerspec":{"it_interval":{"tv_sec":0,"tv_nsec":4,"__size__":8},"it_value":{"tv_sec":8,"tv_nsec":12,"__size__":8},"__size__":16},"iovec":{"iov_len":4,"iov_base":0,"__size__":8},"timezone":{"tz_dsttime":4,"tz_minuteswest":0,"__size__":8},"flock":{"l_whence":2,"l_type":0,"l_start":4,"__size__":16,"l_len":8,"l_pid":12},"EmscriptenOrientationChangeEvent":{"orientationIndex":0,"orientationAngle":4,"__size__":8},"EmscriptenMouseEvent":{"clientX":16,"clientY":20,"targetX":52,"buttons":42,"timestamp":0,"button":40,"targetY":56,"altKey":32,"canvasY":64,"metaKey":36,"movementX":44,"movementY":48,"shiftKey":28,"ctrlKey":24,"screenY":12,"screenX":8,"canvasX":60,"__size__":72},"SDL_ResizeEvent":{"h":8,"type":0,"w":4,"__size__":12},"tms":{"tms_stime":4,"tms_utime":0,"tms_cstime":12,"tms_cutime":8,"__size__":16},"SDL_Color":{"unused":3,"r":0,"b":2,"g":1,"__size__":4},"EmscriptenKeyboardEvent":{"code":32,"charValue":120,"locale":88,"shiftKey":72,"altKey":76,"which":160,"metaKey":80,"location":64,"key":0,"ctrlKey":68,"charCode":152,"keyCode":156,"repeat":84,"__size__":164},"rusage":{"ru_msgrcv":56,"ru_utime":{"tv_sec":0,"tv_usec":4,"__size__":8},"ru_isrss":28,"ru_stime":{"tv_sec":8,"tv_usec":12,"__size__":8},"ru_nsignals":60,"ru_nivcsw":68,"ru_msgsnd":52,"ru_nswap":40,"ru_minflt":32,"ru_nvcsw":64,"ru_ixrss":20,"ru_inblock":44,"ru_idrss":24,"ru_maxrss":16,"ru_oublock":48,"ru_majflt":36,"__size__":136},"div_t":{"quot":0,"rem":4,"__size__":8},"timeval":{"tv_sec":0,"tv_usec":4,"__size__":8},"rlimit":{"rlim_cur":0,"rlim_max":8,"__size__":16},"in6_addr":{"__in6_union":{"__s6_addr16":0,"__s6_addr":0,"__s6_addr32":0,"__size__":16},"__size__":16},"tm":{"tm_sec":0,"tm_hour":8,"tm_mday":12,"tm_isdst":32,"tm_year":20,"tm_zone":40,"tm_mon":16,"tm_yday":28,"tm_gmtoff":36,"tm_wday":24,"tm_min":4,"__size__":44},"EmscriptenWebGLContextAttributes":{"majorVersion":32,"stencil":8,"preserveDrawingBuffer":20,"failIfMajorPerformanceCaveat":28,"antialias":12,"depth":4,"minorVersion":36,"premultipliedAlpha":16,"enableExtensionsByDefault":40,"alpha":0,"preferLowPowerToHighPerformance":24,"__size__":44},"EmscriptenBatteryEvent":{"dischargingTime":8,"level":16,"charging":24,"chargingTime":0,"__size__":32},"protoent":{"p_aliases":4,"p_proto":8,"p_name":0,"__size__":12},"SDL_Surface":{"userdata":24,"locked":28,"clip_rect":36,"format":4,"h":12,"refcount":56,"map":52,"flags":0,"w":8,"pitch":16,"lock_data":32,"pixels":20,"__size__":60},"EmscriptenTouchEvent":{"touches":20,"shiftKey":8,"altKey":12,"metaKey":16,"ctrlKey":4,"__size__":1684,"numTouches":0},"dirent":{"d_name":11,"d_off":4,"d_ino":0,"d_reclen":8,"d_type":10,"__size__":268},"sockaddr_in6":{"sin6_family":0,"sin6_flowinfo":4,"sin6_scope_id":24,"sin6_addr":{"__in6_union":{"__s6_addr16":8,"__s6_addr":8,"__s6_addr32":8,"__size__":16},"__size__":16},"__size__":28,"sin6_port":2},"SDL_JoyAxisEvent":{"__size__":12,"type":0,"value":8,"which":4,"padding2":7,"padding1":6,"axis":5},"netent":{"n_name":0,"n_net":12,"n_addrtype":8,"n_aliases":4,"__size__":16},"SDL_PixelFormat":{"palette":4,"Gloss":29,"Bmask":20,"Bloss":30,"Rloss":28,"format":0,"Gshift":33,"Aloss":31,"BitsPerPixel":8,"refcount":36,"next":40,"padding":10,"Rmask":12,"Bshift":34,"Gmask":16,"BytesPerPixel":9,"Amask":24,"Rshift":32,"Ashift":35,"__size__":44},"SDL_JoyButtonEvent":{"type":0,"button":5,"state":6,"which":4,"padding1":7,"__size__":8},"EmscriptenPointerlockChangeEvent":{"id":132,"nodeName":4,"isActive":0,"__size__":260},"in_addr":{"s_addr":0,"__size__":4},"EmscriptenDeviceOrientationEvent":{"timestamp":0,"beta":16,"alpha":8,"__size__":40,"gamma":24,"absolute":32},"SDL_WindowEvent":{"data2":16,"type":0,"data1":12,"windowID":4,"__size__":20,"padding1":9,"event":8,"padding3":11,"padding2":10},"SDL_Keysym":{"scancode":0,"mod":8,"unicode":12,"sym":4,"__size__":16},"cmsghdr":{"cmsg_type":8,"cmsg_level":4,"cmsg_len":0,"__size__":12},"EmscriptenUiEvent":{"windowInnerWidth":12,"detail":0,"scrollLeft":32,"documentBodyClientHeight":8,"windowInnerHeight":16,"scrollTop":28,"windowOuterHeight":24,"windowOuterWidth":20,"documentBodyClientWidth":4,"__size__":36},"thread_profiler_block":{"threadStatus":0,"timeSpentInStatus":16,"currentStatusStartTime":8,"name":72,"__size__":104},"stat":{"st_rdev":28,"st_mtim":{"tv_sec":56,"tv_nsec":60,"__size__":8},"st_blocks":44,"st_atim":{"tv_sec":48,"tv_nsec":52,"__size__":8},"st_nlink":16,"__st_ino_truncated":8,"st_ctim":{"tv_sec":64,"tv_nsec":68,"__size__":8},"st_mode":12,"st_blksize":40,"__st_dev_padding":4,"st_dev":0,"st_size":36,"st_gid":24,"__st_rdev_padding":32,"st_uid":20,"st_ino":72,"__size__":76},"pollfd":{"fd":0,"events":4,"revents":6,"__size__":8},"WebVRPositionState":{"linearVelocity":{"y":56,"x":48,"z":64,"w":72,"__size__":32},"orientation":{"y":128,"x":120,"z":136,"w":144,"__size__":32},"timeStamp":0,"angularVelocity":{"y":160,"x":152,"z":168,"w":176,"__size__":32},"hasPosition":8,"angularAcceleration":{"y":192,"x":184,"z":200,"w":208,"__size__":32},"linearAcceleration":{"y":88,"x":80,"z":96,"w":104,"__size__":32},"hasOrientation":112,"position":{"y":24,"x":16,"z":32,"w":40,"__size__":32},"__size__":216},"SDL_TextInputEvent":{"text":8,"windowID":4,"type":0,"__size__":40},"EmscriptenTouchPoint":{"clientX":12,"clientY":16,"identifier":0,"targetX":36,"targetY":40,"isChanged":28,"canvasY":48,"canvasX":44,"pageX":20,"pageY":24,"screenY":8,"screenX":4,"onTarget":32,"__size__":52},"EmscriptenDeviceMotionEvent":{"timestamp":0,"accelerationIncludingGravityZ":48,"accelerationIncludingGravityX":32,"accelerationIncludingGravityY":40,"accelerationY":16,"accelerationX":8,"rotationRateBeta":64,"accelerationZ":24,"rotationRateGamma":72,"rotationRateAlpha":56,"__size__":80},"SDL_AudioSpec":{"padding":10,"userdata":20,"format":4,"channels":6,"callback":16,"samples":8,"freq":0,"size":12,"silence":7,"__size__":24},"hostent":{"h_addrtype":8,"h_addr_list":16,"h_name":0,"__size__":20,"h_aliases":4,"h_length":12},"SDL_MouseWheelEvent":{"timestamp":4,"windowID":8,"which":12,"y":20,"x":16,"type":0,"__size__":24},"EmscriptenFocusEvent":{"id":128,"nodeName":0,"__size__":256},"SDL_version":{"major":0,"patch":2,"minor":1,"__size__":3},"statvfs":{"f_bsize":0,"f_bavail":16,"f_fsid":32,"f_favail":28,"f_files":20,"f_frsize":4,"f_blocks":8,"f_ffree":24,"f_bfree":12,"f_flag":40,"f_namemax":44,"__size__":72},"linger":{"l_onoff":0,"l_linger":4,"__size__":8},"EmscriptenFullscreenChangeEvent":{"elementWidth":264,"screenWidth":272,"nodeName":8,"elementHeight":268,"fullscreenEnabled":4,"screenHeight":276,"isFullscreen":0,"id":136,"__size__":280},"EmscriptenWheelEvent":{"deltaX":72,"deltaY":80,"deltaZ":88,"deltaMode":96,"mouse":0,"__size__":104},"WebVRIntRect":{"y":4,"x":0,"height":12,"width":8,"__size__":16},"SDL_TouchFingerEvent":{"timestamp":4,"dy":36,"touchId":8,"pressure":40,"dx":32,"type":0,"y":28,"x":24,"fingerId":16,"__size__":48},"SDL_AudioCVT":{"len_ratio":32,"len_cvt":24,"rate_incr":8,"filters":40,"len":20,"needed":0,"filter_index":80,"src_format":4,"len_mult":28,"__size__":88,"buf":16,"dst_format":6},"WebVRPoint":{"y":8,"x":0,"z":16,"w":24,"__size__":32},"statfs":{"f_bsize":4,"f_bavail":16,"f_fsid":28,"f_files":20,"f_frsize":40,"f_namelen":36,"f_blocks":8,"f_ffree":24,"f_bfree":12,"f_flags":44,"__size__":64},"msghdr":{"msg_iov":8,"msg_iovlen":12,"msg_namelen":4,"msg_controllen":20,"msg_flags":24,"msg_name":0,"msg_control":16,"__size__":28},"EmscriptenGamepadEvent":{"index":1300,"analogButton":528,"timestamp":0,"numButtons":12,"mapping":1368,"digitalButton":1040,"connected":1296,"numAxes":8,"__size__":1432,"id":1304,"axis":16},"SDL_Palette":{"ncolors":0,"colors":4,"version":8,"refcount":12,"__size__":16},"EmscriptenFullscreenStrategy":{"canvasResizedCallbackUserData":16,"canvasResolutionScaleMode":4,"scaleMode":0,"canvasResizedCallback":12,"filteringMode":8,"__size__":20},"timeb":{"dstflag":8,"timezone":6,"time":0,"millitm":4,"__size__":12},"WebVREyeParameters":{"currentFieldOfView":{"leftDegrees":152,"upDegrees":128,"downDegrees":144,"rightDegrees":136,"__size__":32},"recommendedFieldOfView":{"leftDegrees":88,"upDegrees":64,"downDegrees":80,"rightDegrees":72,"__size__":32},"eyeTranslation":{"y":104,"x":96,"z":112,"w":120,"__size__":32},"renderRect":{"y":164,"x":160,"height":172,"width":168,"__size__":16},"minimumFieldOfView":{"leftDegrees":24,"upDegrees":0,"downDegrees":16,"rightDegrees":8,"__size__":32},"maximumFieldOfView":{"leftDegrees":56,"upDegrees":32,"downDegrees":48,"rightDegrees":40,"__size__":32},"__size__":176}},"defines":{"ETXTBSY":26,"EOF":-1,"EMSCRIPTEN_EVENT_MOUSEOVER":35,"ETOOMANYREFS":109,"ENAMETOOLONG":36,"ENOPKG":65,"UUID_TYPE_DCE_TIME":1,"_SC_XOPEN_LEGACY":129,"_SC_XOPEN_VERSION":89,"F_UNLCK":2,"_SC_BC_DIM_MAX":37,"EL3HLT":46,"S_IFDIR":16384,"EMSCRIPTEN_EVENT_KEYPRESS":1,"EINPROGRESS":115,"_SC_BARRIERS":133,"EMSCRIPTEN_EVENT_TOUCHMOVE":24,"SDL_AUDIO_ALLOW_FREQUENCY_CHANGE":1,"AUDIO_U8":8,"EAI_AGAIN":-3,"_PC_MAX_CANON":1,"ENOTSUP":95,"EFBIG":27,"O_CREAT":64,"EMSCRIPTEN_EVENT_POINTERLOCKERROR":38,"_SC_2_PBS_LOCATE":170,"EM_PROXIED_SETENV":113,"_CS_POSIX_V6_LP64_OFF64_LIBS":1126,"ENOLINK":67,"ABDAY_7":131078,"ABDAY_6":131077,"ABDAY_5":131076,"ABDAY_4":131075,"ABDAY_3":131074,"ABDAY_2":131073,"ABDAY_1":131072,"EL3RST":47,"YESEXPR":327680,"_SC_V6_ILP32_OFFBIG":177,"SDL_MINOR_VERSION":3,"EM_PROXIED_CLEARENV":112,"_SC_MEMLOCK":17,"ENOTUNIQ":76,"EMSCRIPTEN_RESULT_FAILED":-6,"ABMON_1":131086,"ELNRNG":48,"UUID_VARIANT_MICROSOFT":2,"EMSCRIPTEN_EVENT_TOUCHSTART":22,"ENOANO":55,"EMSCRIPTEN_EVENT_FOCUSIN":14,"EMSCRIPTEN_EVENT_MOUSEUP":6,"ENOPROTOOPT":92,"POLLIN":1,"S_IALLUGO":4095,"_SC_THREAD_KEYS_MAX":74,"EM_THREAD_STATUS_WAITPROXY":5,"O_RDWR":2,"EREMCHG":78,"EMSCRIPTEN_EVENT_GAMEPADDISCONNECTED":27,"_SC_2_PBS":168,"_SC_TRACE_INHERIT":183,"_SC_REGEXP":155,"_CS_POSIX_V6_LP64_OFF64_CFLAGS":1124,"_SC_DELAYTIMER_MAX":26,"S_IWUGO":146,"S_IFREG":32768,"F_GETLK64":12,"O_DIRECTORY":65536,"EM_PROXIED_UTIMES":13,"POLLHUP":16,"S_IFMT":61440,"F_SETLK64":13,"_SC_XOPEN_CRYPT":92,"_SC_CLOCK_SELECTION":137,"_PC_CHOWN_RESTRICTED":6,"E2BIG":7,"ABMON_3":131088,"AM_STR":131110,"SDL_AUDIO_MASK_ENDIAN":4096,"ALT_DIGITS":131119,"EHOSTDOWN":112,"EBFONT":59,"ENOTEMPTY":39,"AUDIO_S16":32784,"TIOCGPGRP":21519,"EBUSY":16,"_SC_MQ_PRIO_MAX":28,"_SC_PAGE_SIZE":30,"EADDRINUSE":98,"ENOTSOCK":88,"PM_STR":131111,"O_WRONLY":1,"_SC_STREAM_MAX":5,"ABMON_9":131094,"ELIBACC":79,"S_IFIFO":4096,"EDQUOT":122,"EAI_SYSTEM":-11,"ENOENT":2,"_SC_TIMERS":11,"O_SYNC":1052672,"SEEK_END":2,"EM_THREAD_STATUS_FINISHED":6,"_PC_REC_MIN_XFER_SIZE":16,"_PC_PATH_MAX":4,"_SC_SPORADIC_SERVER":160,"ECOMM":70,"_SC_NPROCESSORS_ONLN":84,"_CS_POSIX_V6_LPBIG_OFFBIG_LIBS":1130,"_PC_MAX_INPUT":2,"_SC_VERSION":29,"_SC_XBS5_LPBIG_OFFBIG":128,"_SC_CLK_TCK":2,"ABMON_2":131087,"EXFULL":54,"ABMON_7":131092,"ABMON_6":131091,"ABMON_5":131090,"ABMON_4":131089,"ENOTDIR":20,"ABMON_8":131093,"_SC_AIO_MAX":24,"ERA":131116,"EM_PROXIED_UNSETENV":114,"_SC_THREAD_PRIO_INHERIT":80,"_PC_2_SYMLINKS":20,"_SC_XBS5_LP64_OFF64":127,"EMSCRIPTEN_EVENT_BATTERYLEVELCHANGE":30,"ENETRESET":102,"EAFNOSUPPORT":97,"MON_2":131099,"MON_3":131100,"MON_1":131098,"EMSCRIPTEN_EVENT_DEVICEORIENTATION":16,"MON_7":131104,"MON_4":131101,"MON_5":131102,"_SC_SPAWN":159,"MON_8":131105,"MON_9":131106,"_CS_POSIX_V6_ILP32_OFF32_LDFLAGS":1117,"S_IFSOCK":49152,"S_IRUGO":292,"SOCK_DGRAM":2,"POLLERR":8,"EINVAL":22,"_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS":1128,"POLLRDNORM":64,"AUDIO_F32SYS":33056,"_SC_TRACE_SYS_MAX":244,"AI_V4MAPPED":8,"AI_NUMERICHOST":4,"_CS_POSIX_V6_WIDTH_RESTRICTED_ENVS":1,"EHOSTUNREACH":113,"ENOCSI":50,"EPROTONOSUPPORT":93,"_SC_AIO_PRIO_DELTA_MAX":25,"_SC_MONOTONIC_CLOCK":149,"ETIME":62,"ENOTTY":25,"_SC_XOPEN_ENH_I18N":93,"EAI_SERVICE":-8,"EAGAIN":11,"F_SETLKW64":14,"EMSGSIZE":90,"ELIBEXEC":83,"_SC_MEMORY_PROTECTION":19,"EMSCRIPTEN_FULLSCREEN_SCALE_CENTER":3,"SDL_AUDIO_ALLOW_FORMAT_CHANGE":2,"ECANCELED":125,"_SC_SPIN_LOCKS":154,"_SC_XOPEN_SHM":94,"_PC_LINK_MAX":0,"TIOCSPGRP":21520,"EOPNOTSUPP":95,"EMSCRIPTEN_EVENT_MOUSEENTER":33,"EAI_FAIL":-4,"NOEXPR":327681,"_SC_FSYNC":15,"_SC_GETGR_R_SIZE_MAX":69,"EDESTADDRREQ":89,"EADDRNOTAVAIL":99,"AUDIO_S32SYS":32800,"_SC_TRACE_NAME_MAX":243,"_SC_BC_BASE_MAX":36,"EMSCRIPTEN_EVENT_CANVASRESIZED":37,"EPERM":1,"EAI_FAMILY":-6,"O_NOFOLLOW":131072,"SOCK_STREAM":1,"O_APPEND":1024,"_SC_XOPEN_STREAMS":246,"_SC_GETPW_R_SIZE_MAX":70,"MON_6":131103,"EPROTOTYPE":91,"_SC_CPUTIME":138,"EISCONN":106,"_SC_XBS5_ILP32_OFFBIG":126,"S_IFBLK":24576,"T_FMT_AMPM":131115,"SDL_PIXELFORMAT_RGBA8888":-2042224636,"F_SETLKW":14,"SDL_TOUCH_MOUSEID":-1,"EMSCRIPTEN_EVENT_SCROLL":11,"ELOOP":40,"_SC_OPEN_MAX":4,"_SC_2_FORT_RUN":50,"EMSCRIPTEN_EVENT_VISIBILITYCHANGE":21,"EREMOTE":66,"_SC_RE_DUP_MAX":44,"_SC_THREAD_PRIO_PROTECT":81,"_SC_2_PBS_CHECKPOINT":175,"_SC_2_PBS_TRACK":172,"F_GETLK":12,"MON_10":131107,"MON_11":131108,"MON_12":131109,"TCGETS":21505,"_SC_THREAD_PROCESS_SHARED":82,"AF_INET":2,"_SC_SHARED_MEMORY_OBJECTS":22,"F_GETFD":1,"EMSCRIPTEN_EVENT_DEVICEMOTION":17,"SDL_MIX_MAXVOLUME":128,"_PC_ALLOC_SIZE_MIN":18,"TCSETS":21506,"ELIBMAX":82,"_SC_READER_WRITER_LOCKS":153,"EMULTIHOP":72,"_SC_PHYS_PAGES":85,"_SC_MEMLOCK_RANGE":18,"_SC_PRIORITY_SCHEDULING":10,"T_FMT":131114,"AI_ALL":16,"_PC_VDISABLE":8,"THOUSEP":65537,"_SC_TRACE_EVENT_FILTER":182,"ERA_T_FMT":131121,"_SC_THREAD_ATTR_STACKADDR":77,"_SC_THREAD_THREADS_MAX":76,"_SC_LOGIN_NAME_MAX":71,"_SC_2_C_BIND":47,"_PC_NO_TRUNC":7,"ECONNABORTED":103,"EMSCRIPTEN_RESULT_SUCCESS":0,"_SC_SHELL":157,"EFAULT":14,"_SC_V6_LP64_OFF64":178,"_CS_GNU_LIBC_VERSION":2,"ENODATA":61,"_SC_SEM_VALUE_MAX":33,"_SC_MQ_OPEN_MAX":27,"AI_ADDRCONFIG":32,"_SC_HOST_NAME_MAX":180,"_SC_THREAD_STACK_MIN":75,"_SC_TIMEOUTS":164,"POLLOUT":4,"_SC_IPV6":235,"_SC_CHILD_MAX":1,"EDOM":33,"_SC_2_PBS_MESSAGE":171,"EILSEQ":84,"UUID_VARIANT_DCE":1,"_SC_2_C_DEV":48,"_SC_TIMER_MAX":35,"FP_ZERO":2,"EPFNOSUPPORT":96,"ENONET":64,"ECHRNG":44,"_SC_THREADS":67,"_SC_REALTIME_SIGNALS":9,"CLOCKS_PER_SEC":1000000,"ERA_D_T_FMT":131120,"ESRCH":3,"D_FMT":131113,"POLLPRI":2,"_PC_ASYNC_IO":10,"DAY_2":131080,"DAY_3":131081,"DAY_1":131079,"DAY_6":131084,"DAY_7":131085,"DAY_4":131082,"DAY_5":131083,"_SC_SYNCHRONIZED_IO":14,"EL2HLT":51,"EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF":1,"IPPROTO_UDP":17,"_SC_MAPPED_FILES":16,"EL2NSYNC":45,"_SC_NGROUPS_MAX":3,"ENOMSG":42,"EISDIR":21,"_SC_SEMAPHORES":21,"AI_NUMERICSERV":1024,"EDEADLOCK":35,"EMSCRIPTEN_EVENT_WEBGLCONTEXTLOST":31,"EMSCRIPTEN_EVENT_BATTERYCHARGINGCHANGE":29,"AUDIO_F32LSB":33056,"_SC_COLL_WEIGHTS_MAX":40,"SO_ERROR":4,"ECONNRESET":104,"AT_SYMLINK_NOFOLLOW":256,"_SC_TRACE_LOG":184,"AUDIO_U16LSB":16,"ESTRPIPE":86,"ESHUTDOWN":108,"_PC_SOCK_MAXBUF":12,"_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS":1129,"EDEADLK":35,"_CS_POSIX_V6_ILP32_OFF32_CFLAGS":1116,"EBADRQC":56,"_SC_THREAD_DESTRUCTOR_ITERATIONS":73,"_SC_TYPED_MEMORY_OBJECTS":165,"_SC_TRACE_EVENT_NAME_MAX":242,"_SC_BC_STRING_MAX":39,"_SC_2_SW_DEV":51,"FP_NAN":0,"F_SETOWN":8,"EMSCRIPTEN_EVENT_RESIZE":10,"_SC_ARG_MAX":0,"_SC_THREAD_PRIORITY_SCHEDULING":79,"EM_PROXIED_FPATHCONF":46,"EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF":2,"FIONREAD":21531,"_SC_THREAD_CPUTIME":139,"EMSCRIPTEN_EVENT_POINTERLOCKCHANGE":20,"EM_THREAD_STATUS_NOTSTARTED":0,"_CS_POSIX_V6_ILP32_OFF32_LIBS":1118,"EUNATCH":49,"AUDIO_S8":32776,"AUDIO_S32LSB":32800,"SDL_AUDIO_MASK_BITSIZE":255,"ERA_D_FMT":131118,"AUDIO_F32MSB":37152,"_CS_POSIX_V6_LP64_OFF64_LDFLAGS":1125,"FP_INFINITE":1,"ECHILD":10,"EAI_MEMORY":-10,"O_TRUNC":512,"ETIMEDOUT":110,"EALREADY":114,"ENXIO":6,"NI_NUMERICHOST":1,"EMFILE":24,"F_GETOWN":9,"EMLINK":31,"F_SETFD":2,"ENFILE":23,"EM_PROXIED_SYSCONF":72,"EM_PROXIED_GETENV":111,"SDL_MAJOR_VERSION":1,"ENOMEM":12,"ENOSR":63,"SDL_AUDIO_ALLOW_ANY_CHANGE":7,"EOWNERDEAD":130,"_PC_PRIO_IO":11,"ELIBSCN":81,"_SC_V6_LPBIG_OFFBIG":179,"EM_PROXIED_CHROOT":37,"EMSCRIPTEN_EVENT_CLICK":4,"EPIPE":32,"_SC_EXPR_NEST_MAX":42,"_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS":1120,"EBADSLT":57,"AUDIO_S16MSB":36880,"S_ISVTX":512,"EMSCRIPTEN_RESULT_DEFERRED":1,"EMSCRIPTEN_RESULT_UNKNOWN_TARGET":-4,"S_IRWXUGO":511,"EM_PROXIED_TZSET":119,"_CS_GNU_LIBPTHREAD_VERSION":3,"_PC_REC_MAX_XFER_SIZE":15,"UUID_VARIANT_OTHER":3,"EMSCRIPTEN_EVENT_WEBGLCONTEXTRESTORED":32,"EM_PROXIED_PTHREAD_CREATE":137,"EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT":0,"RADIXCHAR":65536,"AF_UNSPEC":0,"ENOSTR":60,"W_OK":2,"AUDIO_S32":32800,"EACCES":13,"R_OK":4,"S_IRWXO":7,"_SC_V6_ILP32_OFF32":176,"EMSCRIPTEN_EVENT_FULLSCREENCHANGE":19,"EIO":5,"EMSCRIPTEN_RESULT_NOT_SUPPORTED":-1,"EM_PROXIED_CONFSTR":68,"_SC_SIGQUEUE_MAX":34,"EWOULDBLOCK":11,"AUDIO_U16SYS":16,"EMSCRIPTEN_EVENT_FOCUSOUT":15,"EAI_OVERFLOW":-12,"SDL_AUDIO_MASK_DATATYPE":256,"MAP_PRIVATE":2,"_SC_TZNAME_MAX":6,"_CS_PATH":0,"SEEK_SET":0,"EBADE":52,"EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED":-2,"INT_MAX":2147483647,"EMSCRIPTEN_EVENT_KEYDOWN":2,"EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH":1,"_SC_MESSAGE_PASSING":20,"_SC_THREAD_SAFE_FUNCTIONS":68,"_SC_SYMLOOP_MAX":173,"_PC_NAME_MAX":3,"O_EXCL":128,"_SC_TRACE_USER_EVENT_MAX":245,"_PC_REC_XFER_ALIGN":17,"EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT":0,"_SC_RAW_SOCKETS":236,"_SC_2_UPE":97,"EMSCRIPTEN_RESULT_NO_DATA":-7,"EMSCRIPTEN_EVENT_BLUR":12,"_SC_RTSIG_MAX":31,"ESOCKTNOSUPPORT":94,"_SC_PRIORITIZED_IO":13,"_SC_XOPEN_UNIX":91,"CODESET":14,"IPPROTO_TCP":6,"_PC_REC_INCR_XFER_SIZE":14,"F_SETLK":13,"_PC_FILESIZEBITS":13,"_SC_XBS5_ILP32_OFF32":125,"RAND_MAX":2147483647,"EM_PROXIED_SYSCALL":138,"ENOLCK":37,"EM_PROXIED_PUTENV":115,"AUDIO_U16":16,"EMSCRIPTEN_EVENT_MOUSELEAVE":34,"EMSCRIPTEN_EVENT_MOUSEOUT":36,"_SC_2_VERSION":46,"_PC_SYNC_IO":9,"EEXIST":17,"FP_NORMAL":4,"O_RDONLY":0,"_SC_SEM_NSEMS_MAX":32,"_SC_IOV_MAX":60,"EPROTO":71,"_SC_TRACE":181,"ESRMNT":69,"_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS":1121,"INADDR_LOOPBACK":2130706433,"EXDEV":18,"EM_THREAD_STATUS_RUNNING":1,"EMSCRIPTEN_EVENT_BEFOREUNLOAD":28,"EM_THREAD_STATUS_WAITFUTEX":3,"EMSCRIPTEN_RESULT_INVALID_TARGET":-3,"_SC_THREAD_SPORADIC_SERVER":161,"F_SETFL":4,"AI_PASSIVE":1,"ELIBBAD":80,"_SC_LINE_MAX":43,"D_T_FMT":131112,"ERANGE":34,"ESTALE":116,"F_DUPFD":0,"AUDIO_F32":33056,"CLOCK_MONOTONIC":1,"EMSCRIPTEN_EVENT_GAMEPADCONNECTED":26,"F_GETOWN_EX":16,"_SC_ASYNCHRONOUS_IO":12,"ENOTRECOVERABLE":131,"ENOBUFS":105,"EIDRM":43,"EMSCRIPTEN_EVENT_ORIENTATIONCHANGE":18,"CRNCYSTR":262159,"EINTR":4,"EADV":68,"ENOSYS":38,"_CS_POSIX_V6_ILP32_OFFBIG_LIBS":1122,"EM_PROXIED_UTIME":12,"F_GETFL":3,"S_IXUGO":73,"_SC_2_FORT_DEV":49,"SDL_COMPILEDVERSION":1300,"EBADMSG":74,"EUSERS":87,"CLOCK_REALTIME":0,"ENODEV":19,"AF_INET6":10,"_SC_ATEXIT_MAX":87,"_SC_SAVED_IDS":8,"SOL_SOCKET":1,"S_IFLNK":40960,"AUDIO_S16LSB":32784,"POLLNVAL":32,"EMSCRIPTEN_EVENT_TOUCHCANCEL":25,"EMSCRIPTEN_RESULT_INVALID_PARAM":-5,"EMSCRIPTEN_EVENT_MOUSEDOWN":5,"EM_THREAD_STATUS_SLEEPING":2,"_SC_JOB_CONTROL":7,"NI_NAMEREQD":8,"EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT":2,"EMSCRIPTEN_EVENT_MOUSEMOVE":8,"UUID_TYPE_DCE_RANDOM":4,"ENOTCONN":107,"_SC_ADVISORY_INFO":132,"ENETUNREACH":101,"_SC_XOPEN_REALTIME_THREADS":131,"_SC_2_LOCALEDEF":52,"_PC_SYMLINK_MAX":19,"X_OK":1,"EMSCRIPTEN_EVENT_KEYUP":3,"AI_CANONNAME":2,"UUID_VARIANT_NCS":0,"ESPIPE":29,"AUDIO_S32MSB":36896,"EMSCRIPTEN_EVENT_WHEEL":9,"SDL_AUDIO_ALLOW_CHANNELS_CHANGE":4,"_SC_XOPEN_REALTIME":130,"EAI_NONAME":-2,"_PC_PIPE_BUF":5,"EROFS":30,"EM_PROXIED_ATEXIT":110,"ECONNREFUSED":111,"_SC_2_PBS_ACCOUNTING":169,"EMSCRIPTEN_EVENT_FOCUS":13,"AUDIO_S16SYS":32784,"ENETDOWN":100,"ENOEXEC":8,"ENOSPC":28,"EBADF":9,"EAI_SOCKTYPE":-7,"EDOTDOT":73,"_SC_THREAD_ATTR_STACKSIZE":78,"EBADFD":77,"O_ACCMODE":2097155,"EBADR":53,"EM_PROXIED_SBRK":73,"S_IFCHR":8192,"SDL_PATCHLEVEL":0,"ABMON_12":131097,"PTHREAD_KEYS_MAX":128,"ENOMEDIUM":123,"EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE":0,"AUDIO_U16MSB":4112,"EMSCRIPTEN_FULLSCREEN_FILTERING_BILINEAR":2,"_SC_2_CHAR_TERM":95,"EMSCRIPTEN_EVENT_TOUCHEND":23,"_SC_AIO_LISTIO_MAX":23,"_SC_BC_SCALE_MAX":38,"ENOTBLK":15,"EAI_BADFLAGS":-1,"EOVERFLOW":75,"EMSCRIPTEN_EVENT_DBLCLICK":7,"SDL_AUDIO_MASK_SIGNED":32768,"EMSCRIPTEN_FULLSCREEN_FILTERING_NEAREST":1,"ABMON_11":131096,"ABMON_10":131095,"AT_FDCWD":-100,"_SC_TTY_NAME_MAX":72}}
\ No newline at end of file
diff --git a/src/struct_info.json b/src/struct_info.json
index 80814ea2197bc..34da283b1e500 100644
--- a/src/struct_info.json
+++ b/src/struct_info.json
@@ -1198,6 +1198,7 @@
"EMSCRIPTEN_EVENT_MOUSEOVER",
"EMSCRIPTEN_EVENT_MOUSEOUT",
"EMSCRIPTEN_EVENT_CANVASRESIZED",
+ "EMSCRIPTEN_EVENT_POINTERLOCKERROR",
"EMSCRIPTEN_RESULT_SUCCESS",
"EMSCRIPTEN_RESULT_DEFERRED",
diff --git a/system/include/emscripten/html5.h b/system/include/emscripten/html5.h
index 7d979e252606b..75fff6247fb30 100644
--- a/system/include/emscripten/html5.h
+++ b/system/include/emscripten/html5.h
@@ -53,6 +53,7 @@ extern "C" {
#define EMSCRIPTEN_EVENT_MOUSEOVER 35
#define EMSCRIPTEN_EVENT_MOUSEOUT 36
#define EMSCRIPTEN_EVENT_CANVASRESIZED 37
+#define EMSCRIPTEN_EVENT_POINTERLOCKERROR 38
#define EMSCRIPTEN_RESULT int
@@ -292,6 +293,9 @@ typedef struct EmscriptenPointerlockChangeEvent {
typedef EM_BOOL (*em_pointerlockchange_callback_func)(int eventType, const EmscriptenPointerlockChangeEvent *pointerlockChangeEvent, void *userData);
extern EMSCRIPTEN_RESULT emscripten_set_pointerlockchange_callback(const char *target, void *userData, EM_BOOL useCapture, em_pointerlockchange_callback_func callback);
+typedef EM_BOOL (*em_pointerlockerror_callback_func)(int eventType, const void *reserved, void *userData);
+extern EMSCRIPTEN_RESULT emscripten_set_pointerlockerror_callback(const char *target, void *userData, EM_BOOL useCapture, em_pointerlockerror_callback_func callback);
+
extern EMSCRIPTEN_RESULT emscripten_get_pointerlock_status(EmscriptenPointerlockChangeEvent *pointerlockStatus);
extern EMSCRIPTEN_RESULT emscripten_request_pointerlock(const char *target, EM_BOOL deferUntilInEventHandler);
diff --git a/tests/test_html5_pointerlockerror.c b/tests/test_html5_pointerlockerror.c
new file mode 100644
index 0000000000000..8580f29d845fc
--- /dev/null
+++ b/tests/test_html5_pointerlockerror.c
@@ -0,0 +1,94 @@
+#include
+#include
+#include
+#include
+
+void report_result(int result)
+{
+ if (result == 0) {
+ printf("Test successful!\n");
+ } else {
+ printf("Test failed!\n");
+ }
+#ifdef REPORT_RESULT
+ REPORT_RESULT();
+#endif
+}
+
+const char *emscripten_result_to_string(EMSCRIPTEN_RESULT result) {
+ if (result == EMSCRIPTEN_RESULT_SUCCESS) return "EMSCRIPTEN_RESULT_SUCCESS";
+ if (result == EMSCRIPTEN_RESULT_DEFERRED) return "EMSCRIPTEN_RESULT_DEFERRED";
+ if (result == EMSCRIPTEN_RESULT_NOT_SUPPORTED) return "EMSCRIPTEN_RESULT_NOT_SUPPORTED";
+ if (result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED) return "EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED";
+ if (result == EMSCRIPTEN_RESULT_INVALID_TARGET) return "EMSCRIPTEN_RESULT_INVALID_TARGET";
+ if (result == EMSCRIPTEN_RESULT_UNKNOWN_TARGET) return "EMSCRIPTEN_RESULT_UNKNOWN_TARGET";
+ if (result == EMSCRIPTEN_RESULT_INVALID_PARAM) return "EMSCRIPTEN_RESULT_INVALID_PARAM";
+ if (result == EMSCRIPTEN_RESULT_FAILED) return "EMSCRIPTEN_RESULT_FAILED";
+ if (result == EMSCRIPTEN_RESULT_NO_DATA) return "EMSCRIPTEN_RESULT_NO_DATA";
+ return "Unknown EMSCRIPTEN_RESULT!";
+}
+
+#define TEST_RESULT(x) if (ret != EMSCRIPTEN_RESULT_SUCCESS) printf("%s returned %s.\n", #x, emscripten_result_to_string(ret));
+
+int gotClick = 0;
+
+EM_BOOL click_callback(int eventType, const EmscriptenMouseEvent *e, void *userData)
+{
+ if (e->screenX != 0 && e->screenY != 0 && e->clientX != 0 && e->clientY != 0 && e->canvasX != 0 && e->canvasY != 0 && e->targetX != 0 && e->targetY != 0)
+ {
+ if (eventType == EMSCRIPTEN_EVENT_CLICK && !gotClick) {
+ gotClick = 1;
+ printf("Request pointer lock...\n");
+ EMSCRIPTEN_RESULT ret = emscripten_request_pointerlock(0, 0);
+ TEST_RESULT(ret);
+ if (ret != EMSCRIPTEN_RESULT_SUCCESS) {
+ printf("ERROR! emscripten_request_pointerlock() failure\n");
+ report_result(1);
+ }
+ }
+ }
+
+ return 0;
+}
+
+EM_BOOL pointerlockchange_callback(int eventType, const EmscriptenPointerlockChangeEvent *e, void *userData) {
+ printf("ERROR! received 'pointerlockchange' event\n");
+ report_result(1);
+
+ return 0;
+}
+
+EM_BOOL pointerlockerror_callback(int eventType, const void *reserved, void *userData) {
+ if (eventType != EMSCRIPTEN_EVENT_POINTERLOCKERROR) {
+ printf("ERROR! invalid event type for 'pointerlockerror' callback\n");
+ report_result(1);
+ return 0;
+ }
+
+ printf("SUCCESS! received 'pointerlockerror' event\n");
+ report_result(0);
+
+ return 0;
+}
+
+int main()
+{
+ printf("'pointerlockerror' event test:\n");
+ printf("Reject the pointer lock request after clicking on canvas.\n");
+
+ // Make the canvas area stand out from the background.
+ emscripten_set_canvas_size(400, 300);
+ EM_ASM(Module['canvas'].style.backgroundColor = 'black';);
+
+ EMSCRIPTEN_RESULT ret = emscripten_set_click_callback(0, 0, 1, click_callback);
+ TEST_RESULT(emscripten_set_click_callback);
+ ret = emscripten_set_pointerlockchange_callback("#window", 0, 1, pointerlockchange_callback);
+ TEST_RESULT(emscripten_set_pointerlockchange_callback);
+ ret = emscripten_set_pointerlockerror_callback("#window", 0, 1, pointerlockerror_callback);
+ TEST_RESULT(emscripten_set_pointerlockerror_callback);
+
+ /* For the events to function, one must either call emscripten_set_main_loop or enable Module.noExitRuntime by some other means.
+ Otherwise the application will exit after leaving main(), and the atexit handlers will clean up all event hooks (by design). */
+ EM_ASM(Module['noExitRuntime'] = true);
+ return 0;
+}
diff --git a/tests/test_interactive.py b/tests/test_interactive.py
index f9e6c3bbb5535..c18f8a34b6b95 100644
--- a/tests/test_interactive.py
+++ b/tests/test_interactive.py
@@ -28,6 +28,9 @@ def test_html5_fullscreen(self):
def test_html5_mouse(self):
self.btest(path_from_root('tests', 'test_html5_mouse.c'), expected='0')
+ def test_html5_pointerlockerror(self):
+ self.btest(path_from_root('tests', 'test_html5_pointerlockerror.c'), expected='0')
+
def test_sdl_mousewheel(self):
self.btest(path_from_root('tests', 'test_sdl_mousewheel.c'), expected='0')
From d5940078c3e16013afc7b66ac8fdfef22ca88686 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9gis=20F=C3=A9n=C3=A9on?=
Date: Fri, 27 May 2016 11:25:18 +0200
Subject: [PATCH 037/102] Report WebGL GLSL version number in
GL_SHADING_LANGUAGE_VERSION string
This fixes the returned string in case the version is neither "1.0" nor "3.00".
The WebGL GLSL version information is returned in the vendor-specific information field.
---
AUTHORS | 1 +
src/library_gl.js | 12 +++++++-----
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index 8a8f7c663731b..32636ac9f8e95 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -253,3 +253,4 @@ a license to everyone to use it as detailed in LICENSE.)
* Aiden Koss
* Dustin VanLerberghe
* Philip Bielby (copyright owned by Jagex Ltd.)
+* Régis Fénéon
diff --git a/src/library_gl.js b/src/library_gl.js
index 7e0b705efa482..95a36049dd70b 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -742,11 +742,13 @@ var LibraryGL = {
break;
case 0x8B8C /* GL_SHADING_LANGUAGE_VERSION */:
var glslVersion = GLctx.getParameter(GLctx.SHADING_LANGUAGE_VERSION);
- // Map WebGL GL_SHADING_LANGUAGE_VERSION string format to GLES format.
- if (glslVersion.indexOf('WebGL GLSL ES 1.0') != -1) glslVersion = 'OpenGL ES GLSL ES 1.00 (WebGL)';
-#if USE_WEBGL2
- else if (glslVersion.indexOf('WebGL GLSL ES 3.00') != -1) glslVersion = 'OpenGL ES GLSL ES 3.00 (WebGL 2)';
-#endif
+ // extract the version number 'N.M' from the string 'WebGL GLSL ES N.M ...'
+ var ver_re = /^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;
+ var ver_num = glslVersion.match(ver_re);
+ if (ver_num !== null) {
+ if (ver_num[1].length == 3) ver_num[1] = ver_num[1] + '0'; // ensure minor version has 2 digits
+ glslVersion = 'OpenGL ES GLSL ES ' + ver_num[1] + ' (' + glslVersion + ')';
+ }
ret = allocate(intArrayFromString(glslVersion), 'i8', ALLOC_NORMAL);
break;
default:
From 06d98e783f5c6121b51fc1aaba8f884696b8be54 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?=
Date: Mon, 20 Jun 2016 18:23:41 +0300
Subject: [PATCH 038/102] Separate startup time endianness check and heap
address 0 integrity check to two different operations. Also check heap
integrity in checkStackCookie() function, which is a good spot for the
operation in debug builds.
---
src/preamble.js | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/preamble.js b/src/preamble.js
index 038eeedb559ea..dccf7e80309c9 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -912,6 +912,8 @@ function checkStackCookie() {
if (HEAPU32[(STACK_MAX >> 2)-1] != 0x02135467 || HEAPU32[(STACK_MAX >> 2)-2] != 0x89BACDFE) {
abort('Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x02135467, but received 0x' + HEAPU32[(STACK_MAX >> 2)-2].toString(16) + ' ' + HEAPU32[(STACK_MAX >> 2)-1].toString(16));
}
+ // Also test the global address 0 for integrity.
+ if (HEAP32[0] !== 0x63736d65 /* 'emsc' */) throw 'Runtime error: The application has corrupted its heap memory area (address zero)!';
}
function abortStackOverflow(allocSize) {
@@ -1425,11 +1427,14 @@ function setF64(ptr, value) {
#if USE_PTHREADS
if (!ENVIRONMENT_IS_PTHREAD) {
#endif
- HEAP32[0] = 255;
+ HEAP32[0] = 0x63736d65; /* 'emsc' */
#if USE_PTHREADS
+} else {
+ if (HEAP32[0] !== 0x63736d65) throw 'Runtime error: The application has corrupted its heap memory area (address zero)!';
}
#endif
-if (HEAPU8[0] !== 255 || HEAPU8[3] !== 0) throw 'Runtime error: either the current system is not little-endian, or it has corrupted its heap memory area (address zero)!';
+HEAP16[1] = 0x6373;
+if (HEAPU8[2] !== 0x73 || HEAPU8[3] !== 0x63) throw 'Runtime error: expected the system to be little-endian!';
#endif
Module['HEAP'] = HEAP;
From 2e26d286d0ca83df310cfc0b266c27f14f9ebf1a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?=
Date: Wed, 22 Jun 2016 12:04:08 +0300
Subject: [PATCH 039/102] Remove doc files in site/build/ directory, since
those are build artifacts that are built during the docs build process. Leave
emcc.txt intact because that is referenced externally by emcc.py tool itself.
---
.../text/docs/api_reference/emscripten.h.txt | 1911 -----------
.../build/text/docs/api_reference/html5.h.txt | 2840 -----------------
.../text/docs/api_reference/preamble.js.txt | 517 ---
3 files changed, 5268 deletions(-)
delete mode 100644 site/build/text/docs/api_reference/emscripten.h.txt
delete mode 100644 site/build/text/docs/api_reference/html5.h.txt
delete mode 100644 site/build/text/docs/api_reference/preamble.js.txt
diff --git a/site/build/text/docs/api_reference/emscripten.h.txt b/site/build/text/docs/api_reference/emscripten.h.txt
deleted file mode 100644
index 1df8e81c3acda..0000000000000
--- a/site/build/text/docs/api_reference/emscripten.h.txt
+++ /dev/null
@@ -1,1911 +0,0 @@
-
-emscripten.h
-************
-
-This page documents the public C++ APIs provided by emscripten.h.
-
-Emscripten uses existing/familiar APIs where possible (for example:
-*SDL*). This API provides C++ support for capabilities that are
-specific to JavaScript or the browser environment, or for which there
-is no existing API.
-
-
-Table of Contents
-^^^^^^^^^^^^^^^^^
-
-* Inline assembly/JavaScript
-
-* Calling JavaScript From C/C++
-
-* Browser Execution Environment
-
-* Emscripten Asynchronous File System API
-
-* Emscripten Asynchronous IndexedDB API
-
-* Compiling
-
-* Worker API
-
-* Logging utilities
-
-* Socket event registration
-
-* Unaligned types
-
-* Emterpreter-Async functions
-
-* Asyncify functions
-
-
-Inline assembly/JavaScript
-==========================
-
-Guide material for the following APIs can be found in Calling
-JavaScript from C/C++.
-
-
-Defines
--------
-
-EM_ASM(...)
-
- Convenient syntax for inline assembly/JavaScript.
-
- This allows you to declare JavaScript in your C code "inline",
- which is then executed when your compiled code is run in the
- browser. For example, the following C code would display two alerts
- if it was compiled with Emscripten and run in the browser:
-
- EM_ASM( alert(‘hai’));
- alert(‘bai’)); )
-
- Note: * Double-quotes (") cannot be used in the inline
-
- assembly/JavaScript. Single-quotes (‘) can be used, as shown
- above.
-
- * Newlines (\n, \r etc.) are supported in the inline
- JavaScript. Note that any platform-specific issues with line
- endings in normal JavaScript also apply to inline JavaScript
- declared using "EM_ASM".
-
- * You can’t access C variables with "EM_ASM", nor receive a
- value back. Instead use "EM_ASM_ARGS", "EM_ASM_INT", or
- "EM_ASM_DOUBLE".
-
- * As of "1.30.4", "EM_ASM" contents appear as normal JS,
- outside of the compiled code. Previously we had them as a
- string that was "eval``ed. The newer approach avoids the
- overhead of ``eval", and also allows for better optimization of
- "EM_ASM" contents by things like closure compiler, as their
- contents are now visible. Note that this means that closure
- compiler will optimize them as if they were written together
- with the rest of the codebase, which is a change from before -
- you may need to use safety quotes in some places ("a['b']"
- instead of "a.b").
-
-EM_ASM_(code, ...)
-EM_ASM_ARGS(code, ...)
-EM_ASM_INT(code, ...)
-EM_ASM_DOUBLE(code, ...)
-EM_ASM_INT_V(code)
-EM_ASM_DOUBLE_V(code)
-
- Input-output versions of EM_ASM.
-
- "EM_ASM_" (an extra "_" is added) or "EM_ASM_ARGS" allow values
- ("int" or "double") to be sent into the code.
-
- If you also want a return value, "EM_ASM_INT" receives arguments
- (of "int" or "double" type) and returns an "int"; "EM_ASM_DOUBLE"
- does the same and returns a "double".
-
- Arguments arrive as "$0", "$1" etc. The output value should be
- returned:
-
- int x = EM_ASM_INT({
- console.log('I received: ' + [$0, $1]);
- return $0 + $1;
- }, calc(), otherCalc());
-
- Note the "{" and "}".
-
- If you just want to receive an output value ("int" or "double") but
- not pass any values, you can use "EM_ASM_INT_V" or
- "EM_ASM_DOUBLE_V", respectively.
-
-
-Calling JavaScript From C/C++
-=============================
-
-Guide material for the following APIs can be found in Calling
-JavaScript from C/C++.
-
-
-Function pointer types for callbacks
-------------------------------------
-
-The following types are used to define function callback signatures
-used in a number of functions in this file.
-
-em_callback_func
-
- General function pointer type for use in callbacks with no
- parameters.
-
- Defined as:
-
- typedef void (*em_callback_func)(void)
-
-em_arg_callback_func
-
- Generic function pointer type for use in callbacks with a single
- "void*" parameter.
-
- This type is used to define function callbacks that need to pass
- arbitrary data. For example, "emscripten_set_main_loop_arg()" sets
- user-defined data, and passes it to a callback of this type on
- completion.
-
- Defined as:
-
- typedef void (*em_arg_callback_func)(void*)
-
-em_str_callback_func
-
- General function pointer type for use in callbacks with a C string
- ("const char *") parameter.
-
- This type is used for function callbacks that need to be passed a C
- string. For example, it is used in "emscripten_async_wget()" to
- pass the name of a file that has been asynchronously loaded.
-
- Defined as:
-
- typedef void (*em_str_callback_func)(const char *)
-
-
-Functions
----------
-
-void emscripten_run_script(const char *script)
-
- Interface to the underlying JavaScript engine. This function will
- "eval()" the given script.
-
- Parameters:
- * **script** (*const char**) -- The script to evaluate.
-
- Return type:
- void
-
-int emscripten_run_script_int(const char *script)
-
- Interface to the underlying JavaScript engine. This function will
- "eval()" the given script.
-
- Parameters:
- * **script** (*const char**) -- The script to evaluate.
-
- Returns:
- The result of the evaluation, as an integer.
-
- Return type:
- int
-
-char *emscripten_run_script_string(const char *script)
-
- Interface to the underlying JavaScript engine. This function will
- "eval()" the given script. Note that this overload uses a single
- buffer shared between calls.
-
- Parameters:
- * **script** (*const char**) -- The script to evaluate.
-
- Returns:
- The result of the evaluation, as a string.
-
- Return type:
- char*
-
-void emscripten_async_run_script(const char *script, int millis)
-
- Asynchronously run a script, after a specified amount of time.
-
- Parameters:
- * **script** (*const char**) -- The script to evaluate.
-
- * **millis** (*int*) -- The amount of time before the script
- is run, in milliseconds.
-
- Return type:
- void
-
-void emscripten_async_load_script(const char *script, em_callback_func onload, em_callback_func onerror)
-
- Asynchronously loads a script from a URL.
-
- This integrates with the run dependencies system, so your script
- can call "addRunDependency" multiple times, prepare various
- asynchronous tasks, and call "removeRunDependency" on them; when
- all are complete (or if there were no run dependencies to begin
- with), "onload" is called. An example use for this is to load an
- asset module, that is, the output of the file packager.
-
- Parameters:
- * **script** (*const char**) -- The script to evaluate.
-
- * **onload** (*em_callback_func*) -- A callback function, with
- no parameters, that is executed when the script has fully
- loaded.
-
- * **onerror** (*em_callback_func*) -- A callback function,
- with no parameters, that is executed if there is an error in
- loading.
-
- Return type:
- void
-
-
-Browser Execution Environment
-=============================
-
-Guide material for the following APIs can be found in Emscripten
-Runtime Environment.
-
-
-Functions
----------
-
-void emscripten_set_main_loop(em_callback_func func, int fps, int simulate_infinite_loop)
-
- Set a C function as the main event loop.
-
- If the main loop function needs to receive user-defined data, use
- "emscripten_set_main_loop_arg()" instead.
-
- The JavaScript environment will call that function at a specified
- number of frames per second. Setting 0 or a negative value as the
- "fps" will instead use the browser’s "requestAnimationFrame"
- mechanism to call the main loop function. This is **HIGHLY**
- recommended if you are doing rendering, as the browser’s
- "requestAnimationFrame" will make sure you render at a proper
- smooth rate that lines up properly with the browser and monitor. If
- you do not render at all in your application, then you should pick
- a specific frame rate that makes sense for your code.
-
- If "simulate_infinite_loop" is true, the function will throw an
- exception in order to stop execution of the caller. This will lead
- to the main loop being entered instead of code after the call to
- "emscripten_set_main_loop()" being run, which is the closest we can
- get to simulating an infinite loop (we do something similar in
- glutMainLoop in GLUT). If this parameter is "false", then the
- behavior is the same as it was before this parameter was added to
- the API, which is that execution continues normally. Note that in
- both cases we do not run global destructors, "atexit", etc., since
- we know the main loop will still be running, but if we do not
- simulate an infinite loop then the stack will be unwound. That
- means that if "simulate_infinite_loop" is "false", and you created
- an object on the stack, it will be cleaned up before the main loop
- is called for the first time.
-
- Tip: There can be only *one* main loop function at a time. To
- change the main loop function, first "cancel" the current loop,
- and then call this function to set another.
-
- Note: See "emscripten_set_main_loop_expected_blockers()",
- "emscripten_pause_main_loop()", "emscripten_resume_main_loop()"
- and "emscripten_cancel_main_loop()" for information about
- blocking, pausing, and resuming the main loop.
-
- Note: Calling this function overrides the effect of any previous
- calls to "emscripten_set_main_loop_timing()" by applying the
- timing mode specified by the parameter "fps". To specify a
- different timing mode, call the function
- "emscripten_set_main_loop_timing()" after setting up the main
- loop.
-
- Parameters:
- * **func** (*em_callback_func*) -- C function to set as main
- event loop.
-
- * **fps** (*int*) -- Number of frames per second that the
- JavaScript will call the function. Setting "int <=0"
- (recommended) uses the browser’s "requestAnimationFrame"
- mechanism to call the function.
-
- * **simulate_infinite_loop** (*int*) -- If true, this function
- will throw an exception in order to stop execution of the
- caller.
-
-void emscripten_set_main_loop_arg(em_arg_callback_func func, void *arg, int fps, int simulate_infinite_loop)
-
- Set a C function as the main event loop, passing it user-defined
- data.
-
- See also: The information in "emscripten_set_main_loop()" also
- applies to this function.
-
- Parameters:
- * **func** (*em_arg_callback_func*) -- C function to set as
- main event loop. The function signature must have a "void*"
- parameter for passing the "arg" value.
-
- * **arg** (*void**) -- User-defined data passed to the main
- loop function, untouched by the API itself.
-
- * **fps** (*int*) -- Number of frames per second at which the
- JavaScript will call the function. Setting "int <=0"
- (recommended) uses the browser’s "requestAnimationFrame"
- mechanism to call the function.
-
- * **simulate_infinite_loop** (*int*) -- If true, this function
- will throw an exception in order to stop execution of the
- caller.
-
-void emscripten_push_main_loop_blocker(em_arg_callback_func func, void *arg)
-void emscripten_push_uncounted_main_loop_blocker(em_arg_callback_func func, void *arg)
-
- Add a function that **blocks** the main loop.
-
- The function is added to the back of a queue of events to be
- blocked; the main loop will not run until all blockers in the queue
- complete.
-
- In the "counted" version, blockers are counted (internally) and
- "Module.setStatus" is called with some text to report progress
- ("setStatus" is a general hook that a program can define in order
- to show processing updates).
-
- Note: * Main loop blockers block the main loop from running, and
- can
-
- be counted to show progress. In contrast,
- "emscripten_async_calls" are not counted, do not block the main
- loop, and can fire at specific time in the future.
-
- Parameters:
- * **func** (*em_arg_callback_func*) -- The main loop blocker
- function. The function signature must have a "void*" parameter
- for passing the "arg" value.
-
- * **arg** (*void**) -- User-defined arguments to pass to the
- blocker function.
-
- Return type:
- void
-
-void emscripten_pause_main_loop(void)
-void emscripten_resume_main_loop(void)
-
- Pause and resume the main loop.
-
- Pausing and resuming the main loop is useful if your app needs to
- perform some synchronous operation, for example to load a file from
- the network. It might be wrong to run the main loop before that
- finishes (the original code assumes that), so you can break the
- code up into asynchronous callbacks, but you must pause the main
- loop until they complete.
-
- Note: These are fairly low-level functions.
- "emscripten_push_main_loop_blocker()" (and friends) provide more
- convenient alternatives.
-
-void emscripten_cancel_main_loop(void)
-
- Cancels the main event loop.
-
- See also "emscripten_set_main_loop()" and
- "emscripten_set_main_loop_arg()" for information about setting and
- using the main loop.
-
-int emscripten_set_main_loop_timing(int mode, int value)
-
- Specifies the scheduling mode that the current main loop tick
- function will be called with.
-
- This function can be used to interactively control the rate at
- which Emscripten runtime drives the main loop specified by
- calling the function "emscripten_set_main_loop()". In native
- development, this corresponds with the "swap interval" or the
- "presentation interval" for 3D rendering. The new tick interval
- specified by this function takes effect immediately on the
- existing main loop, and this function must be called only after
- setting up a main loop via "emscripten_set_main_loop()".
-
- Parameters:
- * **mode** (*int*) --
-
- The timing mode to use. Allowed values are
- EM_TIMING_SETTIMEOUT, EM_TIMING_RAF and
- EM_TIMING_SETIMMEDIATE.
-
- param int value:
- The timing value to activate for the main loop. This value
- interpreted differently according to the "mode" parameter:
-
- * If "mode" is EM_TIMING_SETTIMEOUT, then "value"
- specifies the number of milliseconds to wait between
- subsequent ticks to the main loop and updates occur
- independent of the vsync rate of the display (vsync off).
- This method uses the JavaScript "setTimeout" function to
- drive the animation.
-
- * If "mode" is EM_TIMING_RAF, then updates are performed
- using the "requestAnimationFrame" function (with vsync
- enabled), and this value is interpreted as a "swap
- interval" rate for the main loop. The value of "1"
- specifies the runtime that it should render at every
- vsync (typically 60fps), whereas the value "2" means that
- the main loop callback should be called only every second
- vsync (30fps). As a general formula, the value "n" means
- that the main loop is updated at every n'th vsync, or at
- a rate of "60/n" for 60Hz displays, and "120/n" for 120Hz
- displays.
-
- * If "mode" is EM_TIMING_SETIMMEDIATE, then updates are
- performed using the "setImmediate" function, or if not
- available, emulated via "postMessage". See *setImmediate
- on MDN * for more
- information. Note that this mode is **strongly not
- recommended** to be used when deploying Emscripten output
- to the web, since it depends on an unstable web extension
- that is in draft status, browsers other than IE do not
- currently support it, and its implementation has been
- considered controversial in review.
-
- rtype:
- int
-
- return:
- The value 0 is returned on success, and a nonzero value is
- returned on failure. A failure occurs if there is no main
- loop active before calling this function.
-
- Note: Browsers heavily optimize towards using
- "requestAnimationFrame" for animation instead of the other
- provided modes. Because of that, for best experience across
- browsers, calling this function with "mode=EM_TIMING_RAF"
- and "value=1" will yield best results. Using the JavaScript
- "setTimeout" function is known to cause stutter and
- generally worse experience than using the
- "requestAnimationFrame" function.
-
- Note: There is a functional difference between "setTimeout"
- and "requestAnimationFrame": If the user minimizes the
- browser window or hides your application tab, browsers will
- typically stop calling "requestAnimationFrame" callbacks,
- but "setTimeout"-based main loop will continue to be run,
- although with heavily throttled intervals. See *setTimeout
- on MDN * for
- more information.
-
-void emscripten_get_main_loop_timing(int *mode, int *value)
-
- Returns the current main loop timing mode that is in effect. For
- interpretation of the values, see the documentation of the
- function "emscripten_set_main_loop_timing()". The timing mode is
- controlled by calling the functions
- "emscripten_set_main_loop_timing()" and
- "emscripten_set_main_loop()".
-
- Parameters:
- * **mode** (*int**) -- If not null, the used timing mode is
- returned here.
-
- * **value** (*int**) -- If not null, the used timing value is
- returned here.
-
-void emscripten_set_main_loop_expected_blockers(int num)
-
- Sets the number of blockers that are about to be pushed.
-
- The number is used for reporting the *relative progress* through a
- set of blockers, after which the main loop will continue.
-
- For example, a game might have to run 10 blockers before starting a
- new level. The operation would first set this value as '10' and
- then push the 10 blockers. When the 3^rd blocker (say) completes,
- progress is displayed as 3/10.
-
- Parameters:
- * **num** (*int*) -- The number of blockers that are about to
- be pushed.
-
-void emscripten_async_call(em_arg_callback_func func, void *arg, int millis)
-
- Call a C function asynchronously, that is, after returning control
- to the JavaScript event loop.
-
- This is done by a "setTimeout".
-
- When building natively this becomes a simple direct call, after
- "SDL_Delay" (you must include **SDL.h** for that).
-
- If "millis" is negative, the browser's "requestAnimationFrame"
- mechanism is used.
-
- Parameters:
- * **func** (*em_arg_callback_func*) -- The C function to call
- asynchronously. The function signature must have a "void*"
- parameter for passing the "arg" value.
-
- * **arg** (*void**) -- User-defined argument to pass to the C
- function.
-
- * **millis** (*int*) -- Timeout before function is called.
-
-void emscripten_exit_with_live_runtime(void)
-
- Exits the program immediately, but leaves the runtime alive so that
- you can continue to run code later (so global destructors etc., are
- not run). Note that the runtime is kept alive automatically when
- you do an asynchronous operation like "emscripten_async_call()", so
- you don't need to call this function for those cases.
-
-void emscripten_force_exit(int status)
-
- Shuts down the runtime and exits (terminates) the program, as if
- you called "exit()".
-
- The difference is that "emscripten_force_exit" will shut down the
- runtime even if you previously called
- "emscripten_exit_with_live_runtime()" or otherwise kept the runtime
- alive. In other words, this method gives you the option to
- completely shut down the runtime after it was kept alive beyond the
- completion of "main()".
-
- Parameters:
- * **status** (*int*) -- The same as for the *libc* function
- exit().
-
-double emscripten_get_device_pixel_ratio(void)
-
- Returns the value of "window.devicePixelRatio".
-
- Return type:
- double
-
- Returns:
- The pixel ratio or 1.0 if not supported.
-
-void emscripten_set_canvas_size(int width, int height)
-
- Resizes the pixel width and height of the "