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 @@ 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 "" element on the - Emscripten web page. - - Parameters: - * **width** (*int*) -- New pixel width of canvas element. - - * **height** (*int*) -- New pixel height of canvas element. - -void emscripten_get_canvas_size(int * width, int * height, int * isFullscreen) - - Gets the current pixel width and height of the "" element - as well as whether the canvas is fullscreen or not. - - Parameters: - * **width** (*int**) -- Pixel width of canvas element. - - * **height** (*int**) -- New pixel height of canvas element. - - * **isFullscreen** (*int**) -- If True ("*int > 0"), - "" is full screen. - -double emscripten_get_now(void) - - Returns the highest-precision representation of the current time - that the browser provides. - - This uses either "Date.now" or "performance.now". The result is not - an absolute time, and is only meaningful in comparison to other - calls to this function. - - Return type: - double - - Returns: - The current time, in milliseconds (ms). - -float emscripten_random(void) - - Generates a random number in the range 0-1. This maps to - "Math.random()". - - Return type: - float - - Returns: - A random number. - - -Emscripten Asynchronous File System API -======================================= - - -Typedefs --------- - -em_async_wget_onload_func - - Function pointer type for the "onload" callback of - "emscripten_async_wget_data()" (specific values of the parameters - documented in that method). - - Defined as: - - typedef void (*em_async_wget_onload_func)(void*, void*, int) - -em_async_wget2_onload_func - - Function pointer type for the "onload" callback of - "emscripten_async_wget2()" (specific values of the parameters - documented in that method). - - Defined as: - - typedef void (*em_async_wget2_onload_func)(void*, const char*) - -em_async_wget2_onstatus_func - - Function pointer type for the "onerror" and "onprogress" callbacks - of "emscripten_async_wget2()" (specific values of the parameters - documented in that method). - - Defined as: - - typedef void (*em_async_wget2_onstatus_func)(void*, int) - -em_async_wget2_data_onload_func - - Function pointer type for the "onload" callback of - "emscripten_async_wget2_data()" (specific values of the parameters - documented in that method). - - Defined as: - - typedef void (*em_async_wget2_data_onload_func)(void*, void *, unsigned*) - -em_async_wget2_data_onerror_func - - Function pointer type for the "onerror" callback of - "emscripten_async_wget2_data()" (specific values of the parameters - documented in that method). - - Defined as: - - typedef void (*em_async_wget2_data_onerror_func)(void*, int, const char*) - -em_async_wget2_data_onprogress_func - - Function pointer type for the "onprogress" callback of - "emscripten_async_wget2_data()" (specific values of the parameters - documented in that method). - - Defined as: - - typedef void (*em_async_wget2_data_onprogress_func)(void*, int, int) - -em_async_prepare_data_onload_func - - Function pointer type for the "onload" callback of - "emscripten_async_prepare_data()" (specific values of the - parameters documented in that method). - - Defined as: - - typedef void (*em_async_prepare_data_onload_func)(void*, const char*) - - -Functions ---------- - -void emscripten_wget(const char* url, const char* file) - - Load file from url in *synchronously*. For the asynchronous - version, see the "emscripten_async_wget()". - - In addition to fetching the URL from the network, the contents are - prepared so that the data is usable in "IMG_Load" and so forth (we - synchronously do the work to make the browser decode the image or - audio etc.). - - This function is blocking; it won't return until all operations are - finished. You can then open and read the file if it succeeded. - - To use this function, you will need to compile your application - with the linker flag "-s ASYNCIFY=1" - - Parameters: - * **char* url** (*const*) -- The URL to load. - - * **char* file** (*const*) -- The name of the file created and - loaded from the URL. If the file already exists it will be - overwritten. - -void emscripten_async_wget(const char* url, const char* file, em_str_callback_func onload, em_str_callback_func onerror) - - Loads a file from a URL asynchronously. - - In addition to fetching the URL from the network, the contents are - prepared so that the data is usable in "IMG_Load" and so forth (we - asynchronously do the work to make the browser decode the image or - audio etc.). - - When the file is ready the "onload" callback will be called. If any - error occurs "onerror" will be called. The callbacks are called - with the file as their argument. - - Parameters: - * **char* url** (*const*) -- The URL to load. - - * **char* file** (*const*) -- The name of the file created and - loaded from the URL. If the file already exists it will be - overwritten. - - * **onload** (*em_str_callback_func*) -- - - Callback on successful load of the file. The callback function - parameter value is: - - * *(const char*)* : The name of the "file" that was loaded - from the URL. - - * **onerror** (*em_str_callback_func*) -- - - Callback in the event of failure. The callback function - parameter value is: - - * *(const char*)* : The name of the "file" that failed to - load from the URL. - -void emscripten_async_wget_data(const char* url, void *arg, em_async_wget_onload_func onload, em_arg_callback_func onerror) - - Loads a buffer from a URL asynchronously. - - This is the "data" version of "emscripten_async_wget()". - - Instead of writing to a file, this function writes to a buffer - directly in memory. This avoids the overhead of using the emulated - file system; note however that since files are not used, it cannot - do the 'prepare' stage to set things up for "IMG_Load" and so forth - ("IMG_Load" etc. work on files). - - When the file is ready then the "onload" callback will be called. - If any error occurred "onerror" will be called. - - Parameters: - * **url** (*const char**) -- The URL of the file to load. - - * **arg** (*void**) -- User-defined data that is passed to the - callbacks, untouched by the API itself. This may be used by a - callback to identify the associated call. - - * **onload** (*em_async_wget_onload_func*) -- - - Callback on successful load of the URL into the buffer. The - callback function parameter values are: - - * *(void*)* : Equal to "arg" (user defined data). - - * *(void*)* : A pointer to a buffer with the data. Note - that, as with the worker API, the data buffer only lives - during the callback; it must be used or copied during that - time. - - * *(int)* : The size of the buffer, in bytes. - - * **onerror** (*em_arg_callback_func*) -- - - Callback in the event of failure. The callback function - parameter values are: - - * *(void*)* : Equal to "arg" (user defined data). - -int emscripten_async_wget2(const char* url, const char* file, const char* requesttype, const char* param, void *arg, em_async_wget2_onload_func onload, em_async_wget2_onstatus_func onerror, em_async_wget2_onstatus_func onprogress) - - Loads a file from a URL asynchronously. - - This is an **experimental** "more feature-complete" version of - "emscripten_async_wget()". - - In addition to fetching the URL from the network, the contents are - prepared so that the data is usable in "IMG_Load" and so forth (we - asynchronously do the work to make the browser decode the image, - audio, etc.). - - When the file is ready the "onload" callback will be called with - the object pointers given in "arg" and "file". During the download - the "onprogress" callback is called. - - Parameters: - * **url** (*const char**) -- The URL of the file to load. - - * **file** (*const char**) -- The name of the file created and - loaded from the URL. If the file already exists it will be - overwritten. - - * **requesttype** (*const char**) -- 'GET' or 'POST'. - - * **param** (*const char**) -- Request parameters for POST - requests (see "requesttype"). The parameters are specified in - the same way as they would be in the URL for an equivalent GET - request: e.g. "key=value&key2=value2". - - * **arg** (*void**) -- User-defined data that is passed to the - callbacks, untouched by the API itself. This may be used by a - callback to identify the associated call. - - * **onload** (*em_async_wget2_onload_func*) -- - - Callback on successful load of the file. The callback function - parameter values are: - - * *(void*)* : Equal to "arg" (user defined data). - - * *(const char*)* : The "file" passed to the original call. - - * **onerror** (*em_async_wget2_onstatus_func*) -- - - Callback in the event of failure. The callback function - parameter values are: - - * *(void*)* : Equal to "arg" (user defined data). - - * *(int)* : The HTTP status code. - - * **onprogress** (*em_async_wget2_onstatus_func*) -- - - Callback during load of the file. The callback function - parameter values are: - - * *(void*)* : Equal to "arg" (user defined data). - - * *(int)* : The progress (percentage completed). - - Returns: - A handle to request ("int") that can be used to "abort" the - request. - -int emscripten_async_wget2_data(const char* url, const char* requesttype, const char* param, void *arg, int free, em_async_wget2_data_onload_func onload, em_async_wget2_data_onerror_func onerror, em_async_wget2_data_onprogress_func onprogress) - - Loads a buffer from a URL asynchronously. - - This is the "data" version of "emscripten_async_wget2()". It is an - **experimental** "more feature complete" version of - "emscripten_async_wget_data()". - - Instead of writing to a file, this function writes to a buffer - directly in memory. This avoids the overhead of using the emulated - file system; note however that since files are not used, it cannot - do the 'prepare' stage to set things up for "IMG_Load" and so forth - ("IMG_Load" etc. work on files). - - In addition to fetching the URL from the network, the contents are - prepared so that the data is usable in "IMG_Load" and so forth (we - asynchronously do the work to make the browser decode the image or - audio etc.). - - When the file is ready the "onload" callback will be called with - the object pointers given in "arg", a pointer to the buffer in - memory, and an unsigned integer containing the size of the buffer. - During the download the "onprogress" callback is called with - progress information. If an error occurs, "onerror" will be called - with the HTTP status code and a string containing the status - description. - - Parameters: - * **url** (*const char**) -- The URL of the file to load. - - * **requesttype** (*const char**) -- 'GET' or 'POST'. - - * **param** (*const char**) -- Request parameters for POST - requests (see "requesttype"). The parameters are specified in - the same way as they would be in the URL for an equivalent GET - request: e.g. "key=value&key2=value2". - - * **arg** (*void**) -- User-defined data that is passed to the - callbacks, untouched by the API itself. This may be used by a - callback to identify the associated call. - - * **free** (*int*) -- Tells the runtime whether to free - the returned buffer after "onload" is complete. If "false" - freeing the buffer is the receiver's responsibility. - - * **onload** (*em_async_wget2_data_onload_func*) -- - - Callback on successful load of the file. The callback function - parameter values are: - - * *(void*)* : Equal to "arg" (user defined data). - - * *(void*)* : A pointer to the buffer in memory. - - * *(unsigned)* : The size of the buffer (in bytes). - - * **onerror** (*em_async_wget2_data_onerror_func*) -- - - Callback in the event of failure. The callback function - parameter values are: - - * *(void*)* : Equal to "arg" (user defined data). - - * *(int)* : The HTTP error code. - - * *(const char*)* : A string with the status description. - - * **onprogress** (*em_async_wget2_data_onprogress_func*) -- - - Callback called (regularly) during load of the file to update - progress. The callback function parameter values are: - - * *(void*)* : Equal to "arg" (user defined data). - - * *(int)* : The number of bytes loaded. - - * *(int)* : The total size of the data in bytes, or zero if - the size is unavailable. - - Returns: - A handle to request ("int") that can be used to "abort" the - request. - -emscripten_async_wget2_abort(int handle) - - Abort an asynchronous request raised using - "emscripten_async_wget2()" or "emscripten_async_wget2_data()". - - Parameters: - * **handle** (*int*) -- A handle to request to be aborted. - -void emscripten_async_prepare_data(char* data, int size, const char *suffix, void *arg, em_async_prepare_data_onload_func onload, em_arg_callback_func onerror) - - Prepares a buffer of data asynchronously. This is a "data" version - of "emscripten_async_prepare()", which receives raw data as input - instead of a filename (this can prevent the need to write data to a - file first). - - When file is loaded then the "onload" callback will be called. If - any error occurs "onerror" will be called. - - "onload" also receives a second parameter, which is a 'fake' - filename which you can pass into "IMG_Load" (it is not an actual - file, but it identifies this image for "IMG_Load" to be able to - process it). Note that the user of this API is responsible for - "free()" ing the memory allocated for the fake filename. - - Parameters: - * **data** (*char**) -- The buffer of data to prepare. - - * **suffix** (*const char**) -- The file suffix, e.g. 'png' or - 'jpg'. - - * **arg** (*void**) -- User-defined data that is passed to the - callbacks, untouched by the API itself. This may be used by a - callback to identify the associated call. - - * **onload** (*em_async_prepare_data_onload_func*) -- - - Callback on successful preparation of the file. The callback - function parameter values are: - - * *(void*)* : Equal to "arg" (user defined data). - - * *(const char*)* : A 'fake' filename which you can pass - into "IMG_Load". See above for more information. - - * **onerror** (*em_arg_callback_func*) -- - - Callback in the event of failure. The callback function - parameter value is: - - * *(void*)* : Equal to "arg" (user defined data). - - -Emscripten Asynchronous IndexedDB API -===================================== - - IndexedDB is a browser API that lets you store data persistently, - that is, you can save data there and load it later when the user - re-visits the web page. IDBFS provides one way to use IndexedDB, - through the Emscripten filesystem layer. The "emscripten_idb_*" - methods listed here provide an alternative API, directly to - IndexedDB, thereby avoiding the overhead of the filesystem layer. - -void emscripten_idb_async_load(const char *db_name, const char *file_id, void* arg, em_async_wget_onload_func onload, em_arg_callback_func onerror) - - Loads data from local IndexedDB storage asynchronously. This allows - use of persistent data, without the overhead of the filesystem - layer. - - When the data is ready then the "onload" callback will be called. - If any error occurred "onerror" will be called. - - Parameters: - * **db_name** -- The IndexedDB database from which to load. - - * **file_id** -- The identifier of the data to load. - - * **arg** (*void**) -- User-defined data that is passed to the - callbacks, untouched by the API itself. This may be used by a - callback to identify the associated call. - - * **onload** (*em_async_wget_onload_func*) -- - - Callback on successful load of the URL into the buffer. The - callback function parameter values are: - - * *(void*)* : Equal to "arg" (user defined data). - - * *(void*)* : A pointer to a buffer with the data. Note - that, as with the worker API, the data buffer only lives - during the callback; it must be used or copied during that - time. - - * *(int)* : The size of the buffer, in bytes. - - * **onerror** (*em_arg_callback_func*) -- - - Callback in the event of failure. The callback function - parameter values are: - - * *(void*)* : Equal to "arg" (user defined data). - -void emscripten_idb_async_store(const char *db_name, const char *file_id, void* ptr, int num, void* arg, em_arg_callback_func onstore, em_arg_callback_func onerror); - - Stores data to local IndexedDB storage asynchronously. This allows - use of persistent data, without the overhead of the filesystem - layer. - - When the data has been stored then the "onstore" callback will be - called. If any error occurred "onerror" will be called. - - Parameters: - * **db_name** -- The IndexedDB database from which to load. - - * **file_id** -- The identifier of the data to load. - - * **ptr** -- A pointer to the data to store. - - * **num** -- How many bytes to store. - - * **arg** (*void**) -- User-defined data that is passed to the - callbacks, untouched by the API itself. This may be used by a - callback to identify the associated call. - - * **onload** (*em_arg_callback_func*) -- - - Callback on successful load of the URL into the buffer. The - callback function parameter values are: - - * *(void*)* : Equal to "arg" (user defined data). - - * **onerror** (*em_arg_callback_func*) -- - - Callback in the event of failure. The callback function - parameter values are: - - * *(void*)* : Equal to "arg" (user defined data). - -void emscripten_idb_async_delete(const char *db_name, const char *file_id, void* arg, em_arg_callback_func ondelete, em_arg_callback_func onerror) - - Deletes data from local IndexedDB storage asynchronously. - - When the data has been deleted then the "ondelete" callback will be - called. If any error occurred "onerror" will be called. - - Parameters: - * **db_name** -- The IndexedDB database. - - * **file_id** -- The identifier of the data. - - * **arg** (*void**) -- User-defined data that is passed to the - callbacks, untouched by the API itself. This may be used by a - callback to identify the associated call. - - * **ondelete** (*em_arg_callback_func*) -- - - Callback on successful delete - - * *(void*)* : Equal to "arg" (user defined data). - - * **onerror** (*em_arg_callback_func*) -- - - Callback in the event of failure. The callback function - parameter values are: - - * *(void*)* : Equal to "arg" (user defined data). - -void emscripten_idb_async_exists(const char *db_name, const char *file_id, void* arg, em_idb_exists_func oncheck, em_arg_callback_func onerror) - - Checks if data with a certain ID exists in the local IndexedDB - storage asynchronously. - - When the data has been checked then the "oncheck" callback will be - called. If any error occurred "onerror" will be called. - - Parameters: - * **db_name** -- The IndexedDB database. - - * **file_id** -- The identifier of the data. - - * **arg** (*void**) -- User-defined data that is passed to the - callbacks, untouched by the API itself. This may be used by a - callback to identify the associated call. - - * **oncheck** (*em_idb_exists_func*) -- - - Callback on successful check, with arguments - - * *(void*)* : Equal to "arg" (user defined data). - - * *int* : Whether the file exists or not. - - * **onerror** (*em_arg_callback_func*) -- - - Callback in the event of failure. The callback function - parameter values are: - - * *(void*)* : Equal to "arg" (user defined data). - -int emscripten_async_prepare(const char* file, em_str_callback_func onload, em_str_callback_func onerror) - - Prepares a file asynchronously. - - This does just the preparation part of "emscripten_async_wget()". - That is, it works on file data already present and performs any - required asynchronous operations (for example, decoding images for - use in "IMG_Load", decoding audio for use in "Mix_LoadWAV", etc.). - - Once the operations are complete (the file is prepared), the - "onload" callback will be called. If any error occurs "onerror" - will be called. The callbacks are called with the file as their - argument. - - Parameters: - * **file** (*const char**) -- The name of the file to prepare. - - * **onload** (*em_str_callback_func*) -- - - Callback on successful preparation of the file. The callback - function parameter value is: - - * *(const char*)* : The name of the "file" that was - prepared. - - * **onerror** (*em_str_callback_func*) -- - - Callback in the event of failure. The callback function - parameter value is: - - * *(const char*)* : The name of the "file" for which the - prepare failed. - - Returns: - 0 if successful, -1 if the file does not exist - - Return type: - int - - -Compiling -========= - -EMSCRIPTEN_KEEPALIVE - - Forces LLVM to not dead-code-eliminate a function. - - This also exports the function, as if you added it to - EXPORTED_FUNCTIONS. - - For example: - - void EMSCRIPTEN_KEEPALIVE my_function() { printf("I am being kept alive\n"); } - - -Worker API -========== - - -Typedefs --------- - -int worker_handle - - A wrapper around web workers that lets you create workers and - communicate with them. - - Note that the current API is mainly focused on a main thread that - sends jobs to workers and waits for responses, i.e., in an - asymmetrical manner, there is no current API to send a message - without being asked for it from a worker to the main thread. - -em_worker_callback_func - - Function pointer type for the callback from - "emscripten_call_worker()" (specific values of the parameters - documented in that method). - - Defined as: - - typedef void (*em_worker_callback_func)(char*, int, void*) - - -Functions ---------- - -worker_handle emscripten_create_worker(const char * url) - - Creates a worker. - - A worker must be compiled separately from the main program, and - with the "BUILD_AS_WORKER" flag set to 1. - - Parameters: - * **url** (*const char**) -- The URL of the worker script. - - Returns: - A handle to the newly created worker. - - Return type: - worker_handle - -void emscripten_destroy_worker(worker_handle worker) - - Destroys a worker. See "emscripten_create_worker()" - - Parameters: - * **worker** (*worker_handle*) -- A handle to the worker to be - destroyed. - -void emscripten_call_worker(worker_handle worker, const char *funcname, char *data, int size, em_worker_callback_func callback, void *arg) - - Asynchronously calls a worker. - - The worker function will be called with two parameters: a data - pointer, and a size. The data block defined by the pointer and size - exists only during the callback: **it cannot be relied upon - afterwards**. If you need to keep some of that information outside - the callback, then it needs to be copied to a safe location. - - The called worker function can return data, by calling - "emscripten_worker_respond()". When the worker is called, if a - callback was given it will be called with three arguments: a data - pointer, a size, and an argument that was provided when calling - "emscripten_call_worker()" (to more easily associate callbacks to - calls). The data block defined by the data pointer and size behave - like the data block in the worker function — it exists only during - the callback. - - Parameters: - * **worker** (*worker_handle*) -- A handle to the worker to be - called. - - * **funcname** (*const char**) -- The name of the function in - the worker. The function must be a C function (so no C++ name - mangling), and must be exported (EXPORTED_FUNCTIONS). - - * **data** (*char**) -- The address of a block of memory to - copy over. - - * **size** (*int*) -- The size of the block of memory. - - * **callback** (*em_worker_callback_func*) -- - - Worker callback with the response. This can be "null". The - callback function parameter values are: - - * *(char*)* : The "data" pointer provided in - "emscripten_call_worker()". - - * *(int)* : The "size" of the block of data. - - * *(void*)* : Equal to "arg" (user defined data). - - * **arg** (*void**) -- An argument (user data) to be passed to - the callback - -void emscripten_worker_respond(char *data, int size) -void emscripten_worker_respond_provisionally(char *data, int size) - - Sends a response when in a worker call (that is, when called by the - main thread using "emscripten_call_worker()"). - - Both functions post a message back to the thread which called the - worker. The "emscripten_worker_respond_provisionally()" variant can - be invoked multiple times, which will queue up messages to be - posted to the worker’s creator. Eventually, the _respond variant - must be invoked, which will disallow further messages and free - framework resources previously allocated for this worker call. - - Note: Calling the provisional version is optional, but you must - call the non-provisional version to avoid leaks. - - Parameters: - * **data** (*char**) -- The message to be posted. - - * **size** (*int*) -- The size of the message, in bytes. - -int emscripten_get_worker_queue_size(worker_handle worker) - - Checks how many responses are being waited for from a worker. - - This only counts calls to "emscripten_call_worker()" that had a - callback (calls with null callbacks are ignored), and where the - response has not yet been received. It is a simple way to check on - the status of the worker to see how busy it is, and do basic - decisions about throttling. - - Parameters: - * **worker** (*worker_handle*) -- The handle to the relevant - worker. - - Returns: - The number of responses waited on from a worker. - - Return type: - int - - -Logging utilities -================= - - -Defines -------- - -EM_LOG_CONSOLE - - If specified, logs directly to the browser console/inspector - window. If not specified, logs via the application Module. - -EM_LOG_WARN - - If specified, prints a warning message. - -EM_LOG_ERROR - - If specified, prints an error message. If neither "EM_LOG_WARN" or - "EM_LOG_ERROR" is specified, an info message is printed. - "EM_LOG_WARN" and "EM_LOG_ERROR" are mutually exclusive. - -EM_LOG_C_STACK - - If specified, prints a call stack that contains file names - referring to original C sources using source map information. - -EM_LOG_JS_STACK - - If specified, prints a call stack that contains file names - referring to lines in the built .js/.html file along with the - message. The flags "EM_LOG_C_STACK" and "EM_LOG_JS_STACK" can be - combined to output both untranslated and translated file and line - information. - -EM_LOG_DEMANGLE - - If specified, C/C++ function names are de-mangled before printing. - Otherwise, the mangled post-compilation JavaScript function names - are displayed. - -EM_LOG_NO_PATHS - - If specified, the pathnames of the file information in the call - stack will be omitted. - -EM_LOG_FUNC_PARAMS - - If specified, prints out the actual values of the parameters the - functions were invoked with. - - -Functions ---------- - -int emscripten_get_compiler_setting(const char *name) - - Returns the value of a compiler setting. - - For example, to return the integer representing the value of - "PRECISE_F32" during compilation: - - emscripten_get_compiler_setting("PRECISE_F32") - - For values containing anything other than an integer, a string is - returned (you will need to cast the "int" return value to a - "char*"). - - Some useful things this can do is provide the version of Emscripten - (“EMSCRIPTEN_VERSION”), the optimization level (“OPT_LEVEL”), debug - level (“DEBUG_LEVEL”), etc. - - For this command to work, you must build with the following - compiler option (as we do not want to increase the build size with - this metadata): - - -s RETAIN_COMPILER_SETTINGS=1 - - Parameters: - * **name** (*const char**) -- The compiler setting to return. - - Returns: - The value of the specified setting. Note that for values other - than an integer, a string is returned (cast the "int" return - value to a "char*"). - - Return type: - int - -void emscripten_debugger() - - Emits "debugger". - - This is inline in the code, which tells the JavaScript engine to - invoke the debugger if it gets there. - -void emscripten_log(int flags, ...) - - Prints out a message to the console, optionally with the callstack - information. - - Parameters: - * **flags** (*int*) -- A binary OR of items from the list of - "EM_LOG_xxx" flags that specify printing options. - - * **...** -- A "printf"-style "format, ..." parameter list - that is parsed according to the "printf" formatting rules. - -int emscripten_get_callstack(int flags, char *out, int maxbytes) - - Programmatically obtains the current callstack. - - To query the amount of bytes needed for a callstack without writing - it, pass 0 to "out" and "maxbytes", in which case the function will - return the number of bytes (including the terminating zero) that - will be needed to hold the full callstack. Note that this might be - fully accurate since subsequent calls will carry different line - numbers, so it is best to allocate a few bytes extra to be safe. - - Parameters: - * **flags** (*int*) -- A binary OR of items from the list of - "EM_LOG_xxx" flags that specify printing options. The flags - "EM_LOG_CONSOLE", "EM_LOG_WARN" and "EM_LOG_ERROR" do not - apply in this function and are ignored. - - * **out** (*char**) -- A pointer to a memory region where the - callstack string will be written to. The string outputted by - this function will always be null-terminated. - - * **maxbytes** (*int*) -- The maximum number of bytes that - this function can write to the memory pointed to by "out". If - there is not enough space, the output will be truncated (but - always null-terminated). - - Returns: - The number of bytes written (not number of characters, so this - will also include the terminating zero). - - Return type: - int - -char *emscripten_get_preloaded_image_data(const char *path, int *w, int *h) - - Gets preloaded image data and the size of the image. - - The function returns pointer to loaded image or NULL — the pointer - should be "free()"'d. The width/height of the image are written to - the "w" and "h" parameters if the data is valid. - - Parameters: - * **path** -- Full path/filename to the file containing the - preloaded image. - - * **w** (*int**) -- Width of the image (if data is valid). - - * **h** (*int**) -- Height of the image (if data is valid). - - Type: - const char* - - Returns: - A pointer to the preloaded image or NULL. - - Return type: - char* - -char *emscripten_get_preloaded_image_data_from_FILE(FILE *file, int *w, int *h) - - Gets preloaded image data from a C "FILE*". - - Parameters: - * **file** (*FILE**) -- The "FILE" containing the preloaded - image. - - * **w** (*int**) -- Width of the image (if data is valid). - - * **h** (*int**) -- Height of the image (if data is valid). - - Type: - const char* - - Returns: - A pointer to the preloaded image or NULL. - - Return type: - char* - -int emscripten_print_double(double x, char *to, signed max) - - Prints a double as a string, including a null terminator. This is - useful because JS engines have good support for printing out a - double in a way that takes the least possible size, but preserves - all the information in the double, i.e., it can then be parsed back - in a perfectly reversible manner (snprintf etc. do not do so, - sadly). - - Parameters: - * **x** (*double*) -- The double. - - * **to** (*char**) -- A pre-allocated buffer of sufficient - size, or NULL if no output is requested (useful to get the - necessary size). - - * **max** (*signed*) -- The maximum number of characters to - write - - Return type: - The number of necessary bytes, not including the null terminator - (actually written, if "to" is not NULL). - - -Socket event registration -========================= - -The functions in this section register callback functions for -receiving socket events. These events are analogous to WebSocket -events but are emitted *after* the internal Emscripten socket -processing has occurred. This means, for example, that the message -callback will be triggered after the data has been added to the -*recv_queue*, so that an application receiving this callback can -simply read the data using the file descriptor passed as a parameter -to the callback. All of the callbacks are passed a file descriptor -("fd") representing the socket that the notified activity took place -on. The error callback also takes an "int" representing the socket -error number ("errno") and a "char*" that represents the error message -("msg"). - -Only a single callback function may be registered to handle any given -event, so calling a given registration function more than once will -cause the first callback to be replaced. Similarly, passing a "NULL" -callback function to any "emscripten_set_socket_*_callback" call will -de-register the callback registered for that event. - -The "userData" pointer allows arbitrary data specified during event -registration to be passed to the callback, this is particularly useful -for passing "this" pointers around in Object Oriented code. - -In addition to being able to register network callbacks from C it is -also possible for native JavaScript code to directly use the -underlying mechanism used to implement the callback registration. For -example, the following code shows simple logging callbacks that are -registered by default when "SOCKET_DEBUG" is enabled: - - Module['websocket']['on']('error', function(error) {console.log('Socket error ' + error);}); - Module['websocket']['on']('open', function(fd) {console.log('Socket open fd = ' + fd);}); - Module['websocket']['on']('listen', function(fd) {console.log('Socket listen fd = ' + fd);}); - Module['websocket']['on']('connection', function(fd) {console.log('Socket connection fd = ' + fd);}); - Module['websocket']['on']('message', function(fd) {console.log('Socket message fd = ' + fd);}); - Module['websocket']['on']('close', function(fd) {console.log('Socket close fd = ' + fd);}); - -Most of the JavaScript callback functions above get passed the file -descriptor of the socket that triggered the callback, the on error -callback however gets passed an *array* that contains the file -descriptor, the error code and an error message. - -Note: The underlying JavaScript implementation doesn't pass - "userData". This is mostly of use to C/C++ code and the - "emscripten_set_socket_*_callback" calls simply create a closure - containing the "userData" and pass that as the callback to the - underlying JavaScript event registration mechanism. - - -Callback functions ------------------- - -em_socket_callback - - Function pointer for "emscripten_set_socket_open_callback()", and - the other socket functions (except - "emscripten_set_socket_error_callback()"). This is defined as: - - typedef void (*em_socket_callback)(int fd, void *userData); - - Parameters: - * **fd** (*int*) -- The file descriptor of the socket that - triggered the callback. - - * **userData** (*void**) -- The "userData" originally passed - to the event registration function. - -em_socket_error_callback - - Function pointer for the "emscripten_set_socket_error_callback()", - defined as: - - typedef void (*em_socket_error_callback)(int fd, int err, const char* msg, void *userData); - - Parameters: - * **fd** (*int*) -- The file descriptor of the socket that - triggered the callback. - - * **err** (*int*) -- The code for the error that occurred. - - * **msg** (*int*) -- The message for the error that occurred. - - * **userData** (*void**) -- The "userData" originally passed - to the event registration function. - - -Functions ---------- - -void emscripten_set_socket_error_callback(void *userData, em_socket_error_callback callback) - - Triggered by a "WebSocket" error. - - See Socket event registration for more information. - - Parameters: - * **userData** (*void**) -- Arbitrary user data to be passed - to the callback. - - * **callback** (*em_socket_error_callback*) -- Pointer to a - callback function. The callback returns a file descriptor, - error code and message, and the arbitrary "userData" passed to - this function. - -void emscripten_set_socket_open_callback(void *userData, em_socket_callback callback) - - Triggered when the "WebSocket" has opened. - - See Socket event registration for more information. - - Parameters: - * **userData** (*void**) -- Arbitrary user data to be passed - to the callback. - - * **callback** (*em_socket_callback*) -- Pointer to a callback - function. The callback returns a file descriptor and the - arbitrary "userData" passed to this function. - -void emscripten_set_socket_listen_callback(void *userData, em_socket_callback callback) - - Triggered when "listen" has been called (synthetic event). - - See Socket event registration for more information. - - Parameters: - * **userData** (*void**) -- Arbitrary user data to be passed - to the callback. - - * **callback** (*em_socket_callback*) -- Pointer to a callback - function. The callback returns a file descriptor and the - arbitrary "userData" passed to this function. - -void emscripten_set_socket_connection_callback(void *userData, em_socket_callback callback) - - Triggered when the connection has been established. - - See Socket event registration for more information. - - Parameters: - * **userData** (*void**) -- Arbitrary user data to be passed - to the callback. - - * **callback** (*em_socket_callback*) -- Pointer to a callback - function. The callback returns a file descriptor and the - arbitrary "userData" passed to this function. - -void emscripten_set_socket_message_callback(void *userData, em_socket_callback callback) - - Triggered when data is available to be read from the socket. - - See Socket event registration for more information. - - Parameters: - * **userData** (*void**) -- Arbitrary user data to be passed - to the callback. - - * **callback** (*em_socket_callback*) -- Pointer to a callback - function. The callback returns a file descriptor and the - arbitrary "userData" passed to this function. - -void emscripten_set_socket_close_callback(void *userData, em_socket_callback callback) - - Triggered when the "WebSocket" has closed. - - See Socket event registration for more information. - - Parameters: - * **userData** (*void**) -- Arbitrary user data to be passed - to the callback. - - * **callback** (*em_socket_callback*) -- Pointer to a callback - function. The callback returns a file descriptor and the - arbitrary "userData" passed to this function. - - -Unaligned types -=============== - - -Typedefs --------- - -emscripten_align1_short -emscripten_align2_int -emscripten_align1_int -emscripten_align2_float -emscripten_align1_float -emscripten_align4_double -emscripten_align2_double -emscripten_align1_double - - Unaligned types. These may be used to force LLVM to emit unaligned - loads/stores in places in your code where SAFE_HEAP found an - unaligned operation. - - For usage examples see tests/core/test_set_align.c. - - Note: It is better to avoid unaligned operations, but if you are - reading from a packed stream of bytes or such, these types may be - useful! - - -Emterpreter-Async functions -=========================== - -Emterpreter-async functions are asynchronous functions that appear -synchronously in C, the linker flags "-s EMTERPRETIFY -s -EMTERPRETIFY_ASYNC=1" are required to use these functions. See -Emterpreter for more details. - - -Sleeping --------- - -void emscripten_sleep(unsigned int ms) - - Sleep for *ms* milliseconds. This is a normal "synchronous" sleep, - which blocks all other operations while it runs. In other words, if - there are other async events waiting to happen, they will not - happen during this sleep, which makes sense as conceptually this - code is on the stack (that's how it looks in the C source code). If - you do want things to happen while sleeping, see - "emscripten_sleep_with_yield". - -void emscripten_sleep_with_yield(unsigned int ms) - - Sleep for *ms* milliseconds, while allowing other asynchronous - operations, e.g. caused by "emscripten_async_call", to run - normally, during this sleep. Note that this method **does** still - block the main loop, as otherwise it could recurse, if you are - calling this method from it. Even so, you should use this method - carefully: the order of execution is potentially very confusing - this way. - - -Network -------- - -void emscripten_wget_data(const char* url, void** pbuffer, int* pnum, int *perror); - - Synchronously fetches data off the network, and stores it to a - buffer in memory, which is allocated for you. **You must free the - buffer, or it will leak!** - - Parameters: - * **url** -- The URL to fetch from - - * **pbuffer** -- An out parameter that will be filled with a - pointer to a buffer containing the data that is downloaded. - This space has been malloced for you, **and you must free it, - or it will leak!** - - * **pnum** -- An out parameter that will be filled with the - size of the downloaded data. - - * **perror** -- An out parameter that will be filled with a - non- zero value if an error occurred. - - -IndexedDB ---------- - -void emscripten_idb_load(const char *db_name, const char *file_id, void** pbuffer, int* pnum, int *perror); - - Synchronously fetches data from IndexedDB, and stores it to a - buffer in memory, which is allocated for you. **You must free the - buffer, or it will leak!** - - Parameters: - * **db_name** -- The name of the database to load from - - * **file_id** -- The name of the file to load - - * **pbuffer** -- An out parameter that will be filled with a - pointer to a buffer containing the data that is downloaded. - This space has been malloced for you, **and you must free it, - or it will leak!** - - * **pnum** -- An out parameter that will be filled with the - size of the downloaded data. - - * **perror** -- An out parameter that will be filled with a - non- zero value if an error occurred. - -void emscripten_idb_store(const char *db_name, const char *file_id, void* buffer, int num, int *perror); - - Synchronously stores data to IndexedDB. - - Parameters: - * **db_name** -- The name of the database to store to - - * **file_id** -- The name of the file to store - - * **buffer** -- A pointer to the data to store - - * **num** -- How many bytes to store - - * **perror** -- An out parameter that will be filled with a - non- zero value if an error occurred. - -void emscripten_idb_delete(const char *db_name, const char *file_id, int *perror); - - Synchronously deletes data from IndexedDB. - - Parameters: - * **db_name** -- The name of the database to delete from - - * **file_id** -- The name of the file to delete - - * **perror** -- An out parameter that will be filled with a - non- zero value if an error occurred. - -void emscripten_idb_exists(const char *db_name, const char *file_id, int* pexists, int *perror); - - Synchronously checks if a file exists in IndexedDB. - - Parameters: - * **db_name** -- The name of the database to check in - - * **file_id** -- The name of the file to check - - * **pexists** -- An out parameter that will be filled with a - non-zero value if the file exists in that database. - - * **perror** -- An out parameter that will be filled with a - non- zero value if an error occurred. - - -Asyncify functions -================== - -Asyncify functions are asynchronous functions that appear -synchronously in C, the linker flag *-s ASYNCIFY=1* is required to use -these functions. See Asyncify for more details. - - -Typedefs --------- - -emscripten_coroutine - - A handle to the structure used by coroutine supporting functions. - - -Functions ---------- diff --git a/site/build/text/docs/api_reference/html5.h.txt b/site/build/text/docs/api_reference/html5.h.txt deleted file mode 100644 index 4707e163e051d..0000000000000 --- a/site/build/text/docs/api_reference/html5.h.txt +++ /dev/null @@ -1,2840 +0,0 @@ - -html5.h -******* - -The C++ APIs in html5.h define the Emscripten low-level glue bindings -to interact with HTML5 events from native code. - -Tip: The C++ APIs map closely to their equivalent HTML5 JavaScript - APIs. The HTML5 specifications listed below provide additional - detailed reference "over and above" the information provided in this - document.In addition, the Test/Example code can be reviewed to see - how the code is used. - -The HTML5 specifications for APIs that are mapped by **html5.h** -include: - - * DOM Level 3 Events: Keyboard, Mouse, Mouse Wheel, Resize, - Scroll, Focus. - - * Device Orientation Events for gyro and accelerometer. - - * Screen Orientation Events for portrait/landscape handling. - - * Fullscreen Events for browser canvas fullscreen modes - transitioning. - - * Pointer Lock Events for relative-mode mouse motion control. - - * Vibration API for mobile device haptic vibration feedback - control. - - * Page Visibility Events for power management control. - - * Touch Events. - - * Gamepad API. - - * Beforeunload event. - - * WebGL context events - - -Table of Contents -^^^^^^^^^^^^^^^^^ - -* How to use this API - -* General types - -* Function result values - -* Keys - -* Mouse - -* Wheel - -* UI - -* Focus - -* Device orientation - -* Device motion - -* Orientation - -* Fullscreen - -* Pointerlock - -* Visibility - -* Touch - -* Gamepad - -* Battery - -* Vibration - -* Page unload - -* WebGL context - -* CSS - - -How to use this API -=================== - -Most of these APIs use an event-based architecture; functionality is -accessed by registering a callback function that will be called when -the event occurs. - -Note: The Gamepad API is currently an exception, as only a polling - API is available. For some APIs, both an event-based and a polling- - based model are exposed. - - -Registration functions ----------------------- - -The typical format of registration functions is as follows (some -methods may omit various parameters): - - EMSCRIPTEN_RESULT emscripten_set_some_callback( - const char *target, // ID of the target HTML element. - void *userData, // User-defined data to be passed to the callback. - EM_BOOL useCapture, // Whether or not to use capture. - em_someevent_callback_func callback // Callback function. - ); - -The "target" parameter is the ID of the HTML element to which the -callback registration is to be applied. This field has the following -special meanings: - - * "0" or "NULL": A default element is chosen automatically based - on the event type, which should be reasonable most of the time. - - * "#window": The event listener is applied to the JavaScript - "window" object. - - * "#document": The event listener is applied to the JavaScript - "document" object. - - * "#screen": The event listener is applied to the JavaScript - "window.screen" object. - - * "#canvas": The event listener is applied to the Emscripten - default WebGL canvas element. - - * Any other string without a leading hash "#" sign: The event - listener is applied to the element on the page with the given ID. - -The "userData" parameter is a user-defined value that is passed -(unchanged) to the registered event callback. This can be used to, for -example, pass a pointer to a C++ class or similarly to enclose the C -API in a clean object-oriented manner. - -The "useCapture" parameter maps to "useCapture" in -EventTarget.addEventListener. It indicates whether or not to initiate -*capture*: if "true" the callback will be invoked only for the DOM -capture and target phases; if "false" the callback will be triggered -during the target and bubbling phases. See DOM Level 3 Events for a -more detailed explanation. - -Most functions return the result using the type "EMSCRIPTEN_RESULT". -Non-zero and positive values denote success. Negative values signal -failure. None of the functions fail or abort by throwing a JavaScript -or C++ exception. If a particular browser does not support the given -feature, the value "EMSCRIPTEN_RESULT_NOT_SUPPORTED" will be returned -at the time the callback is registered. - - -Callback functions ------------------- - -When the event occurs the callback is invoked with the relevant event -"type" (for example "EMSCRIPTEN_EVENT_CLICK"), a "struct" containing -the details of the event that occurred, and the "userData" that was -originally passed to the registration function. The general format of -the callback function is: - - typedef EM_BOOL (*em_someevent_callback_func) // Callback function. Return true if event is "consumed". - ( - int eventType, // The type of event. - const EmscriptenSomeEvent *someEvent, // Information about the event. - void *userData // User data passed from the registration function. - ); - -Callback handlers that return an "EM_BOOL" may specify "true" to -signal that the handler *consumed* the event (this suppresses the -default action for that event by calling its ".preventDefault();" -member). Returning "false" indicates that the event was not consumed — -the default browser event action is carried out and the event is -allowed to pass on/bubble up as normal. - -Calling a registration function with a "null" pointer for the callback -causes a de-registration of that callback from the given "target" -element. All event handlers are also automatically unregistered when -the C "exit()" function is invoked during the "atexit" handler pass. -Either use the function "emscripten_set_main_loop()" or set -"Module.noExitRuntime = true;" to make sure that leaving "main()" will -not immediately cause an "exit()" and clean up the event handlers. - - -Functions affected by web security ----------------------------------- - -Some functions, including "emscripten_request_pointerlock()" and -"emscripten_request_fullscreen()", are affected by web security. - -While the functions can be called anywhere, the actual "requests" can -only be raised inside the handler for a user-generated event (for -example a key, mouse or touch press/release). - -When porting code, it may be difficult to ensure that the functions -are called inside appropriate event handlers (so that the requests are -raised immediately). As a convenience, developers can set -"deferUntilInEventHandler=true" to automatically defer insecure -requests until the user next presses a keyboard or mouse button. This -simplifies porting, but often results in a poorer user experience. For -example, the user must click once on the canvas to hide the pointer or -transition to full screen. - -Where possible, the functions should only be called inside appropriate -event handlers. Setting "deferUntilInEventHandler=false" causes the -functions to abort with an error if the request is refused due to a -security restriction: this is a useful mechanism for discovering -instances where the functions are called outside the handler for a -user-generated event. - - -Test/Example code ------------------ - -The HTML5 test code demonstrates how to use this API: - - * test_html5.c - - * test_html5_fullscreen.c - - * test_html5_mouse.c - - -General types -============= - -EM_BOOL - - This is the Emscripten type for a "bool". - -EM_UTF8 - - This is the Emscripten type for a UTF8 string (maps to a "char"). - This is used for node names, element ids, etc. - - -Function result values -====================== - -Most functions in this API return a result of type -"EMSCRIPTEN_RESULT". None of the functions fail or abort by throwing a -JavaScript or C++ exception. If a particular browser does not support -the given feature, the value "EMSCRIPTEN_RESULT_NOT_SUPPORTED" will be -returned at the time the callback is registered. - -EMSCRIPTEN_RESULT - - This type is used to return the result of most functions in this - API. Positive values denote success, while zero and negative - values signal failure. Possible values are listed below. - - EMSCRIPTEN_RESULT_SUCCESS - - The operation succeeded. - - EMSCRIPTEN_RESULT_DEFERRED - - The requested operation cannot be completed now for web security - reasons, and has been deferred for completion in the next event - handler. - - EMSCRIPTEN_RESULT_NOT_SUPPORTED - - The given operation is not supported by this browser or the - target element. This value will be returned at the time the - callback is registered if the operation is not supported. - - EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED - - The requested operation could not be completed now for web - security reasons. It failed because the user requested the - operation not be deferred. - - EMSCRIPTEN_RESULT_INVALID_TARGET - - The operation failed because the specified target element is - invalid. - - EMSCRIPTEN_RESULT_UNKNOWN_TARGET - - The operation failed because the specified target element was - not found. - - EMSCRIPTEN_RESULT_INVALID_PARAM - - The operation failed because an invalid parameter was passed to - the function. - - EMSCRIPTEN_RESULT_FAILED - - Generic failure result message, returned if no specific result - is available. - - EMSCRIPTEN_RESULT_NO_DATA - - The operation failed because no data is currently available. - - -Keys -==== - - -Defines -------- - -EMSCRIPTEN_EVENT_KEYPRESS -EMSCRIPTEN_EVENT_KEYDOWN -EMSCRIPTEN_EVENT_KEYUP - - Emscripten key events. - -DOM_KEY_LOCATION - - The location of the key on the keyboard; one of the values below. - - DOM_KEY_LOCATION_STANDARD - DOM_KEY_LOCATION_LEFT - DOM_KEY_LOCATION_RIGHT - DOM_KEY_LOCATION_NUMPAD - - Locations of the key on the keyboard. - - -Struct ------- - -EmscriptenKeyboardEvent - - The event structure passed in keyboard events: "keypress", - "keydown" and "keyup". - - Note that since the DOM Level 3 Events spec is very recent at the - time of writing (2014-03), uniform support for the different fields - in the spec is still in flux. Be sure to check the results in - multiple browsers. See the unmerged pull request #2222 for an - example of how to interpret the legacy key events. - - EM_UTF8 key - - The printed representation of the pressed key. - - Maximum size 32 "char" (i.e. "EM_UTF8 key[32]"). - - EM_UTF8 code - - A string that identifies the physical key being pressed. The - value is not affected by the current keyboard layout or modifier - state, so a particular key will always return the same value. - - Maximum size 32 "char" (i.e. "EM_UTF8 code[32]"). - - unsigned long location - - Indicates the location of the key on the keyboard. One of the - "DOM_KEY_LOCATION" values. - - EM_BOOL ctrlKey - EM_BOOL shiftKey - EM_BOOL altKey - EM_BOOL metaKey - - Specifies which modifiers were active during the key event. - - EM_BOOL repeat - - Specifies if this keyboard event represents a repeated press. - - EM_UTF8 locale - - A locale string indicating the configured keyboard locale. This - may be an empty string if the browser or device doesn't know the - keyboard's locale. - - Maximum size 32 char (i.e. "EM_UTF8 locale[32]"). - - EM_UTF8 charValue - - The following fields are values from previous versions of the - DOM key events specifications. See the character representation - of the key. This is the field "char" from the docs, but renamed - to "charValue" to avoid a C reserved word. - - Maximum size 32 "char" (i.e. "EM_UTF8 charValue[32]"). - - Warning: This attribute has been dropped from DOM Level 3 - events. - - unsigned long charCode - - The Unicode reference number of the key; this attribute is used - only by the keypress event. For keys whose "char" attribute - contains multiple characters, this is the Unicode value of the - first character in that attribute. - - Warning: This attribute is deprecated, you should use the - field "key" instead, if available. - - unsigned long keyCode - - A system and implementation dependent numerical code identifying - the unmodified value of the pressed key. - - Warning: This attribute is deprecated, you should use the - field "key" instead, if available. - - unsigned long which - - A system and implementation dependent numeric code identifying - the unmodified value of the pressed key; this is usually the - same as "keyCode". - - Warning: This attribute is deprecated, you should use the - field "key" instead, if available. Note thought that while - this field is deprecated, the cross-browser support for - "which" may be better than for the other fields, so - experimentation is recommended. Read issue - https://github.com/kripken/emscripten/issues/2817 for more - information. - - -Callback functions ------------------- - -em_key_callback_func - - Function pointer for the "keypress callback functions", defined as: - - typedef EM_BOOL (*em_key_callback_func)(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData); - - Parameters: - * **eventType** (*int*) -- The type of "key event". - - * **keyEvent** (*const EmscriptenKeyboardEvent**) -- - Information about the key event that occurred. - - * **userData** (*void**) -- The "userData" originally passed - to the registration function. - - Returns: - "true" (non zero) to indicate that the event was consumed by the - callback handler. - - Return type: - "EM_BOOL" - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_set_keypress_callback(const char *target, void *userData, EM_BOOL useCapture, em_key_callback_func callback) -EMSCRIPTEN_RESULT emscripten_set_keydown_callback(const char *target, void *userData, EM_BOOL useCapture, em_key_callback_func callback) -EMSCRIPTEN_RESULT emscripten_set_keyup_callback(const char *target, void *userData, EM_BOOL useCapture, em_key_callback_func callback) - - Registers a callback function for receiving browser-generated - keyboard input events. - - Parameters: - * **target** (*const char**) -- Target HTML element id. - - * **userData** (*void**) -- User-defined data to be passed to - the callback (opaque to the API). - - * **useCapture** (*EM_BOOL*) -- Set "true" to use capture. - - * **callback** (*em_key_callback_func*) -- A callback - function. The function is called with the type of event, - information about the event, and user data passed from this - registration function. The callback should return "true" if - the event is consumed. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - - See also: - * https://developer.mozilla.org/en/DOM/Event/UIEvent/KeyEvent - - * http://www.javascriptkit.com/jsref/eventkeyboardmouse.shtml - - -Mouse -===== - - -Defines -------- - -EMSCRIPTEN_EVENT_CLICK -EMSCRIPTEN_EVENT_MOUSEDOWN -EMSCRIPTEN_EVENT_MOUSEUP -EMSCRIPTEN_EVENT_DBLCLICK -EMSCRIPTEN_EVENT_MOUSEMOVE -EMSCRIPTEN_EVENT_MOUSEENTER -EMSCRIPTEN_EVENT_MOUSELEAVE - - Emscripten mouse events. - - -Struct ------- - -EmscriptenMouseEvent - - The event structure passed in mouse events: click, mousedown, - mouseup, dblclick, mousemove, mouseenter and mouseleave. - - double timestamp; - - A timestamp of when this data was generated by the browser. This - is an absolute wallclock time in milliseconds. - - long screenX - long screenY - - The coordinates relative to the browser screen coordinate - system. - - long clientX - long clientY - - The coordinates relative to the viewport associated with the - event. - - EM_BOOL ctrlKey - EM_BOOL shiftKey - EM_BOOL altKey - EM_BOOL metaKey - - Specifies which modifiers were active during the mouse event. - - unsigned short button - - Identifies which pointer device button changed state (see - MouseEvent.button): - - * 0 : Left button - - * 1 : Middle button (if present) - - * 2 : Right button - - unsigned short buttons - - A bitmask that indicates which combinations of mouse buttons - were being held down at the time of the event. - - long movementX - long movementY; - - If pointer lock is active, these two extra fields give relative - mouse movement since the last event. - - long targetX - long targetY - - These fields give the mouse coordinates mapped relative to the - coordinate space of the target DOM element receiving the input - events (Emscripten-specific extension). - - long canvasX - long canvasY - - These fields give the mouse coordinates mapped to the Emscripten - canvas client area (Emscripten-specific extension). - - long padding - - Internal, and can be ignored. - - Note: Implementers only: pad this struct to multiple of 8 - bytes to make "WheelEvent" unambiguously align to 8 bytes. - - -Callback functions ------------------- - -em_mouse_callback_func - - Function pointer for the "mouse event callback functions", defined - as: - - typedef EM_BOOL (*em_mouse_callback_func)(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData); - - Parameters: - * **eventType** (*int*) -- The type of "mouse event". - - * **mouseEvent** (*const EmscriptenMouseEvent**) -- - Information about the mouse event that occurred. - - * **userData** (*void**) -- The "userData" originally passed - to the registration function. - - Returns: - "true" (non zero) to indicate that the event was consumed by the - callback handler. - - Return type: - "EM_BOOL" - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_set_click_callback(const char *target, void *userData, EM_BOOL useCapture, em_mouse_callback_func callback) -EMSCRIPTEN_RESULT emscripten_set_mousedown_callback(const char *target, void *userData, EM_BOOL useCapture, em_mouse_callback_func callback) -EMSCRIPTEN_RESULT emscripten_set_mouseup_callback(const char *target, void *userData, EM_BOOL useCapture, em_mouse_callback_func callback) -EMSCRIPTEN_RESULT emscripten_set_dblclick_callback(const char *target, void *userData, EM_BOOL useCapture, em_mouse_callback_func callback) -EMSCRIPTEN_RESULT emscripten_set_mousemove_callback(const char *target, void *userData, EM_BOOL useCapture, em_mouse_callback_func callback) -EMSCRIPTEN_RESULT emscripten_set_mouseenter_callback(const char *target, void *userData, EM_BOOL useCapture, em_mouse_callback_func callback) -EMSCRIPTEN_RESULT emscripten_set_mouseleave_callback(const char *target, void *userData, EM_BOOL useCapture, em_mouse_callback_func callback) - - Registers a callback function for receiving browser-generated mouse - input events. - - Parameters: - * **target** (*const char**) -- Target HTML element id. - - * **userData** (*void**) -- User-defined data to be passed to - the callback (opaque to the API). - - * **useCapture** (*EM_BOOL*) -- Set "true" to use capture. - - * **callback** (*em_mouse_callback_func*) -- A callback - function. The function is called with the type of event, - information about the event, and user data passed from this - registration function. The callback should return "true" if - the event is consumed. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EMSCRIPTEN_RESULT emscripten_get_mouse_status(EmscriptenMouseEvent *mouseState) - - Returns the most recently received mouse event state. - - Note that for this function call to succeed, - "emscripten_set_xxx_callback" must have first been called with one - of the mouse event types and a non-zero callback function pointer - to enable the Mouse state capture. - - Parameters: - * **mouseState** (*EmscriptenMouseEvent**) -- The most - recently received mouse event state. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - - -Wheel -===== - - -Defines -------- - -EMSCRIPTEN_EVENT_WHEEL - - Emscripten wheel event. - -DOM_DELTA_PIXEL - - The units of measurement for the delta must be pixels (from spec). - -DOM_DELTA_LINE - - The units of measurement for the delta must be individual lines of - text (from spec). - -DOM_DELTA_PAGE - - The units of measurement for the delta must be pages, either - defined as a single screen or as a demarcated page (from spec). - - -Struct ------- - -EmscriptenWheelEvent - - The event structure passed in mousewheel events. - - EmscriptenMouseEvent mouse - - Specifies general mouse information related to this event. - - double deltaX - double deltaY - double deltaZ - - Movement of the wheel on each of the axis. Note that these - values may be fractional, so you should avoid simply casting - them to integer, or it might result in scroll values of 0. The - positive Y scroll direction is when scrolling the page downwards - (page CSS pixel +Y direction), which corresponds to scrolling - the mouse wheel downwards (away from the screen) on Windows, - Linux, and also on OSX when the 'natural scroll' option is - disabled. - - unsigned long deltaMode - - One of the "DOM_DELTA_" values that indicates the units of - measurement for the delta values. - - -Callback functions ------------------- - -em_wheel_callback_func - - Function pointer for the "wheel event callback functions", defined - as: - - typedef EM_BOOL (*em_wheel_callback_func)(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData); - - Parameters: - * **eventType** (*int*) -- The type of wheel event - ("EMSCRIPTEN_EVENT_WHEEL"). - - * **wheelEvent** (*const EmscriptenWheelEvent**) -- - Information about the wheel event that occurred. - - * **userData** (*void**) -- The "userData" originally passed - to the registration function. - - Returns: - "true" (non zero) to indicate that the event was consumed by the - callback handler. - - Return type: - "EM_BOOL" - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_set_wheel_callback(const char *target, void *userData, EM_BOOL useCapture, em_wheel_callback_func callback) - - Registers a callback function for receiving browser-generated - mousewheel events. - - Parameters: - * **target** (*const char**) -- Target HTML element id. - - * **userData** (*void**) -- User-defined data to be passed to - the callback (opaque to the API). - - * **useCapture** (*EM_BOOL*) -- Set "true" to use capture. - - * **callback** (*em_wheel_callback_func*) -- A callback - function. The function is called with the type of event, - information about the event, and user data passed from this - registration function. The callback should return "true" if - the event is consumed. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - - -UI -== - - -Defines -------- - -EMSCRIPTEN_EVENT_RESIZE -EMSCRIPTEN_EVENT_SCROLL - - Emscripten UI events. - - -Struct ------- - -EmscriptenUiEvent - - The event structure passed in DOM element UIEvent events: resize - and scroll. - - long detail - - Specifies additional detail/information about this event. - - int documentBodyClientWidth - int documentBodyClientHeight - - The clientWidth/clientHeight of the "document.body" element. - - int windowInnerWidth - int windowInnerHeight - - The innerWidth/innerHeight of the browser window. - - int windowOuterWidth - int windowOuterHeight; - - The outerWidth/outerHeight of the browser window. - - int scrollTop - int scrollLeft - - The page scroll position. - - -Callback functions ------------------- - -em_ui_callback_func - - Function pointer for the "UI event callback functions", defined as: - - typedef EM_BOOL (*em_ui_callback_func)(int eventType, const EmscriptenUiEvent *uiEvent, void *userData); - - Parameters: - * **eventType** (*int*) -- The type of UI event - ("EMSCRIPTEN_EVENT_RESIZE"). - - * **uiEvent** (*const EmscriptenUiEvent**) -- Information - about the UI event that occurred. - - * **userData** (*void**) -- The "userData" originally passed - to the registration function. - - Returns: - "true" (non zero) to indicate that the event was consumed by the - callback handler. - - Return type: - "EM_BOOL" - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_set_resize_callback(const char *target, void *userData, EM_BOOL useCapture, em_ui_callback_func callback) -EMSCRIPTEN_RESULT emscripten_set_scroll_callback(const char *target, void *userData, EM_BOOL useCapture, em_ui_callback_func callback) - - Registers a callback function for receiving DOM element resize and - scroll events. - - Note: * For the "resize" callback, pass in target = 0 to get - "resize" - - events from the "Window" object. - - * The DOM3 Events specification only requires that the "Window" - object sends resize events. It is valid to register a "resize" - callback on other DOM elements, but the browser is not required - to fire "resize" events for these. - - Parameters: - * **target** (*const char**) -- Target HTML element id. - - * **userData** (*void**) -- User-defined data to be passed to - the callback (opaque to the API). - - * **useCapture** (*EM_BOOL*) -- Set "true" to use capture. - - * **callback** (*em_ui_callback_func*) -- A callback function. - The function is called with the type of event, information - about the event, and user data passed from this registration - function. The callback should return "true" if the event is - consumed. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - - -Focus -===== - - -Defines -------- - -EMSCRIPTEN_EVENT_BLUR -EMSCRIPTEN_EVENT_FOCUS -EMSCRIPTEN_EVENT_FOCUSIN -EMSCRIPTEN_EVENT_FOCUSOUT - - Emscripten focus events. - - -Struct ------- - -EmscriptenFocusEvent - - The event structure passed in DOM element blur, focus, focusin and - focusout events. - - EM_UTF8 nodeName - - The nodeName of the target HTML Element. - - Maximum size 128 "char" (i.e. "EM_UTF8 nodeName[128]"). - - EM_UTF8 id - - The ID of the target element. - - Maximum size 128 "char" (i.e. "EM_UTF8 id[128]"). - - -Callback functions ------------------- - -em_focus_callback_func - - Function pointer for the "focus event callback functions", defined - as: - - typedef EM_BOOL (*em_focus_callback_func)(int eventType, const EmscriptenFocusEvent *focusEvent, void *userData); - - Parameters: - * **eventType** (*int*) -- The type of focus event - ("EMSCRIPTEN_EVENT_BLUR"). - - * **focusEvent** (*const EmscriptenFocusEvent**) -- - Information about the focus event that occurred. - - * **userData** (*void**) -- The "userData" originally passed - to the registration function. - - Returns: - "true" (non zero) to indicate that the event was consumed by the - callback handler. - - Return type: - "EM_BOOL" - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_set_blur_callback(const char *target, void *userData, EM_BOOL useCapture, em_focus_callback_func callback) -EMSCRIPTEN_RESULT emscripten_set_focus_callback(const char *target, void *userData, EM_BOOL useCapture, em_focus_callback_func callback) -EMSCRIPTEN_RESULT emscripten_set_focusin_callback(const char *target, void *userData, EM_BOOL useCapture, em_focus_callback_func callback) -EMSCRIPTEN_RESULT emscripten_set_focusout_callback(const char *target, void *userData, EM_BOOL useCapture, em_focus_callback_func callback) - - Registers a callback function for receiving DOM element blur, - focus, focusin and focusout events. - - Parameters: - * **target** (*const char**) -- Target HTML element id. - - * **userData** (*void**) -- User-defined data to be passed to - the callback (opaque to the API). - - * **useCapture** (*EM_BOOL*) -- Set "true" to use capture. - - * **callback** (*em_focus_callback_func*) -- A callback - function. The function is called with the type of event, - information about the event, and user data passed from this - registration function. The callback should return "true" if - the event is consumed. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - - -Device orientation -================== - - -Defines -------- - -EMSCRIPTEN_EVENT_DEVICEORIENTATION - - Emscripten "deviceorientation" events. - - -Struct ------- - -EmscriptenDeviceOrientationEvent - - The event structure passed in the deviceorientation event. - - double timestamp - - Absolute wallclock time when the event occurred (in - milliseconds). - - double alpha - double beta - double gamma - - The orientation of the device in terms of the transformation - from a coordinate frame fixed on the Earth to a coordinate frame - fixed in the device. - - The image (source: dev.opera.com) and definitions below - illustrate the co-ordinate frame: - - * "alpha": the rotation of the device around the Z axis. - - * "beta": the rotation of the device around the X axis. - - * "gamma": the rotation of the device around the Y axis. - - [image: Image of device showing X, Y, Z axes][image] - - EM_BOOL absolute - - If "false", the orientation is only relative to some other base - orientation, not to the fixed coordinate frame. - - -Callback functions ------------------- - -em_deviceorientation_callback_func - - Function pointer for the "orientation event callback functions", - defined as: - - typedef EM_BOOL (*em_deviceorientation_callback_func)(int eventType, const EmscriptenDeviceOrientationEvent *deviceOrientationEvent, void *userData); - - Parameters: - * **eventType** (*int*) -- The type of orientation event - ("EMSCRIPTEN_EVENT_DEVICEORIENTATION"). - - * **deviceOrientationEvent** (*const - EmscriptenDeviceOrientationEvent**) -- Information about the - orientation event that occurred. - - * **userData** (*void**) -- The "userData" originally passed - to the registration function. - - Returns: - "true" (non zero) to indicate that the event was consumed by the - callback handler. - - Return type: - "EM_BOOL" - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_set_deviceorientation_callback(void *userData, EM_BOOL useCapture, em_deviceorientation_callback_func callback) - - Registers a callback function for receiving the deviceorientation - event. - - Parameters: - * **userData** (*void**) -- User-defined data to be passed to - the callback (opaque to the API). - - * **useCapture** (*EM_BOOL*) -- Set "true" to use capture. - - * **callback** (*em_deviceorientation_callback_func*) -- A - callback function. The function is called with the type of - event, information about the event, and user data passed from - this registration function. The callback should return "true" - if the event is consumed. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EMSCRIPTEN_RESULT emscripten_get_deviceorientation_status(EmscriptenDeviceOrientationEvent *orientationState) - - Returns the most recently received "deviceorientation" event state. - - Note that for this function call to succeed, - "emscripten_set_deviceorientation_callback()" must have first been - called with one of the mouse event types and a non-zero callback - function pointer to enable the "deviceorientation" state capture. - - Parameters: - * **orientationState** (*EmscriptenDeviceOrientationEvent**) - -- The most recently received "deviceorientation" event state. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - - -Device motion -============= - - -Defines -------- - -EMSCRIPTEN_EVENT_DEVICEMOTION - - Emscripten devicemotion event. - - -Struct ------- - -EmscriptenDeviceMotionEvent - - The event structure passed in the devicemotion event. - - double timestamp - - Absolute wallclock time when the event occurred (milliseconds). - - double accelerationX - double accelerationY - double accelerationZ - - Acceleration of the device excluding gravity. - - double accelerationIncludingGravityX - double accelerationIncludingGravityY - double accelerationIncludingGravityZ - - Acceleration of the device including gravity. - - double rotationRateAlpha - double rotationRateBeta - double rotationRateGamma - - The rotational delta of the device. - - -Callback functions ------------------- - -em_devicemotion_callback_func - - Function pointer for the "devicemotion event callback functions", - defined as: - - typedef EM_BOOL (*em_devicemotion_callback_func)(int eventType, const EmscriptenDeviceMotionEvent *deviceMotionEvent, void *userData); - - Parameters: - * **eventType** (*int*) -- The type of devicemotion event - ("EMSCRIPTEN_EVENT_DEVICEMOTION"). - - * **deviceMotionEvent** (*const EmscriptenDeviceMotionEvent**) - -- Information about the devicemotion event that occurred. - - * **userData** (*void**) -- The "userData" originally passed - to the registration function. - - Returns: - "true" (non zero) to indicate that the event was consumed by the - callback handler. - - Return type: - "EM_BOOL" - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_set_devicemotion_callback(void *userData, EM_BOOL useCapture, em_devicemotion_callback_func callback) - - Registers a callback function for receiving the devicemotion event. - - Parameters: - * **userData** (*void**) -- User-defined data to be passed to - the callback (opaque to the API). - - * **useCapture** (*EM_BOOL*) -- Set "true" to use capture. - - * **callback** (*em_devicemotion_callback_func*) -- A callback - function. The function is called with the type of event, - information about the event, and user data passed from this - registration function. The callback should return "true" if - the event is consumed. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EMSCRIPTEN_RESULT emscripten_get_devicemotion_status(EmscriptenDeviceMotionEvent *motionState) - - Returns the most recently received devicemotion event state. - - Note that for this function call to succeed, - "emscripten_set_devicemotion_callback()" must have first been - called with one of the mouse event types and a non-zero callback - function pointer to enable the "devicemotion" state capture. - - Parameters: - * **motionState** (*EmscriptenDeviceMotionEvent**) -- The most - recently received "devicemotion" event state. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - - -Orientation -=========== - - -Defines -------- - -EMSCRIPTEN_EVENT_ORIENTATIONCHANGE - - Emscripten orientationchange event. - -EMSCRIPTEN_ORIENTATION_PORTRAIT_PRIMARY - - Primary portrait mode orientation. - -EMSCRIPTEN_ORIENTATION_PORTRAIT_SECONDARY - - Secondary portrait mode orientation. - -EMSCRIPTEN_ORIENTATION_LANDSCAPE_PRIMARY - - Primary landscape mode orientation. - -EMSCRIPTEN_ORIENTATION_LANDSCAPE_SECONDARY - - Secondary landscape mode orientation. - - -Struct ------- - -EmscriptenOrientationChangeEvent - - The event structure passed in the orientationchange event. - - int orientationIndex - - One of the "EM_ORIENTATION_PORTRAIT_xxx" fields, or -1 if - unknown. - - int orientationAngle - - Emscripten-specific extension: Some browsers refer to - "window.orientation", so report that as well. - - Orientation angle in degrees. 0: "default orientation", i.e. - default upright orientation to hold the mobile device in. Could - be either landscape or portrait. - - -Callback functions ------------------- - -em_orientationchange_callback_func - - Function pointer for the "orientationchange event callback - functions", defined as: - - typedef EM_BOOL (*em_orientationchange_callback_func)(int eventType, const EmscriptenOrientationChangeEvent *orientationChangeEvent, void *userData); - - Parameters: - * **eventType** (*int*) -- The type of orientationchange event - ("EMSCRIPTEN_EVENT_ORIENTATIONCHANGE"). - - * **orientationChangeEvent** (*const - EmscriptenOrientationChangeEvent**) -- Information about the - orientationchange event that occurred. - - * **userData** (*void**) -- The "userData" originally passed - to the registration function. - - Returns: - "true" (non zero) to indicate that the event was consumed by the - callback handler. - - Return type: - "EM_BOOL" - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_set_orientationchange_callback(void *userData, EM_BOOL useCapture, em_orientationchange_callback_func callback) - - Registers a callback function for receiving the orientationchange - event. - - Parameters: - * **userData** (*void**) -- User-defined data to be passed to - the callback (opaque to the API). - - * **useCapture** (*EM_BOOL*) -- Set "true" to use capture. - - * **callback** (*em_orientationchange_callback_func*) -- A - callback function. The function is called with the type of - event, information about the event, and user data passed from - this registration function. The callback should return "true" - if the event is consumed. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EMSCRIPTEN_RESULT emscripten_get_orientation_status(EmscriptenOrientationChangeEvent *orientationStatus) - - Returns the current device orientation state. - - Parameters: - * **orientationStatus** (*EmscriptenOrientationChangeEvent**) - -- The most recently received orientation state. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EMSCRIPTEN_RESULT emscripten_lock_orientation(int allowedOrientations) - - Locks the screen orientation to the given set of "allowed - orientations". - - Parameters: - * **allowedOrientations** (*int*) -- A bitfield set of - "EMSCRIPTEN_ORIENTATION_xxx" flags. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EMSCRIPTEN_RESULT emscripten_unlock_orientation(void) - - Removes the orientation lock so the screen can turn to any - orientation. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - - -Fullscreen -========== - - -Defines -------- - -EMSCRIPTEN_EVENT_FULLSCREENCHANGE - - Emscripten fullscreenchange event. - -EMSCRIPTEN_FULLSCREEN_SCALE - - An enum-like type which specifies how the Emscripten runtime should - treat the CSS size of the target element when displaying it in - fullscreen mode via calls to functions - "emscripten_request_fullscreen_strategy()" and - "emscripten_enter_soft_fullscreen()". - -EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT - - Specifies that the DOM element should not be resized by Emscripten - runtime when transitioning between fullscreen and windowed modes. - The browser will be responsible for scaling the DOM element to the - fullscreen size. The proper browser behavior in this mode is to - stretch the element to fit the full display ignoring aspect ratio, - but at the time of writing, browsers implement different behavior - here. See the discussion at - https://github.com/kripken/emscripten/issues/2556 for more - information. - -EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH - - Specifies that the Emscripten runtime should explicitly stretch the - CSS size of the target element to cover the whole screen when - transitioning to fullscreen mode. This will change the aspect ratio - of the displayed content. - -EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT - - Specifies that the Emscripten runtime should explicitly scale the - CSS size of the target element to cover the whole screen, while - adding either vertical or horizontal black letterbox padding to - preserve the aspect ratio of the content. The aspect ratio that is - used here is the render target size of the canvas element. To - change the desired aspect ratio, call - "emscripten_set_canvas_size()" before entering fullscreen mode. - -EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE - - An enum-like type which specifies how the Emscripten runtime should - treat the pixel size (render target resolution) of the target - canvas element when displaying it in fullscreen mode via calls to - functions "emscripten_request_fullscreen_strategy()" and - "emscripten_enter_soft_fullscreen()". To better understand the - underlying distinction between the CSS size of a canvas element - versus the render target size of a canvas element, see - https://www.khronos.org/webgl/wiki/HandlingHighDPI. - -EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE - - Specifies that the Emscripten runtime should not do any changes to - the render target resolution of the target canvas element that is - displayed in fullscreen mode. Use this mode when your application - is set up to render to a single fixed resolution that cannot be - changed under any condition. - -EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF - - Specifies that the Emscripten runtime should resize the render - target of the canvas element to match 1:1 with the CSS size of the - element in fullscreen mode. On high DPI displays - (*window.devicePixelRatio* > 1), the CSS size is not the same as - the physical screen resolution of the device. Call - "emscripten_get_device_pixel_ratio()" to obtain the pixel ratio - between CSS pixels and actual device pixels of the screen. Use this - mode when you want to render to a pixel resolution that is DPI- - independent. - -EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF - - Specifies that the Emscripten runtime should resize the canvas - render target size to match 1:1 with the physical screen resolution - on the device. This corresponds to high definition displays on - retina iOS and other mobile and desktop devices with high DPI. Use - this mode to match and render 1:1 to the native display resolution. - -EMSCRIPTEN_FULLSCREEN_FILTERING - - An enum-like type that specifies what kind of image filtering - algorithm to apply to the element when it is presented in - fullscreen mode. - -EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT - - Specifies that the image filtering mode should not be changed from - the existing setting in the CSS style. - -EMSCRIPTEN_FULLSCREEN_FILTERING_NEAREST - - Applies a CSS style to the element that displays the content using - a nearest-neighbor image filtering algorithm in fullscreen mode. - -EMSCRIPTEN_FULLSCREEN_FILTERING_BILINEAR - - Applies a CSS style to the element that displays the content using - a bilinear image filtering algorithm in fullscreen mode. This is - the default browser behavior. - - -Struct ------- - -EmscriptenFullscreenChangeEvent - - The event structure passed in the fullscreenchange event. - - EM_BOOL isFullscreen - - Specifies whether an element on the browser page is currently - fullscreen. - - EM_BOOL fullscreenEnabled - - Specifies if the current page has the ability to display - elements fullscreen. - - EM_UTF8 nodeName - - The nodeName of the target HTML Element that is in full screen - mode. - - Maximum size 128 "char" (i.e. "EM_UTF8 nodeName[128]"). - - If "isFullscreen" is "false", then "nodeName", "id" and - "elementWidth" and "ElementHeight" specify information about the - element that just exited fullscreen mode. - - EM_UTF8 id - - The ID of the target HTML element that is in full screen mode. - - Maximum size 128 "char" (i.e. "EM_UTF8 id[128]"). - - int elementWidth - int elementHeight - - The new pixel size of the element that changed fullscreen - status. - - int screenWidth - int screenHeight - - The size of the whole screen, in pixels. - -EmscriptenFullscreenStrategy - - The options structure that is passed in to functions - "emscripten_request_fullscreen_strategy()" and - "emscripten_enter_soft_fullscreen()" to configure how the target - element should be displayed in fullscreen mode. - - EMSCRIPTEN_FULLSCREEN_SCALE scaleMode - - Specifies the rule how the CSS size (the displayed size) of the - target element is resized when displayed in fullscreen mode. - - EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE canvasResolutionScaleMode - - Specifies how the render target size (the pixel resolution) of - the target element is adjusted when displayed in fullscreen - mode. - - EMSCRIPTEN_FULLSCREEN_FILTERING filteringMode - - Specifies the image filtering algorithm to apply to the element - in fullscreen mode. - - em_canvasresized_callback_func canvasResizedCallback - - If nonzero, points to a user-provided callback function which - will be called whenever either the CSS or the canvas render - target size changes. Use this callback to reliably obtain - information about canvas resize events. - - void *canvasResizedCallbackUserData - - Stores a custom data field which will be passed to all calls to - the user-provided callback function. - - -Callback functions ------------------- - -em_fullscreenchange_callback_func - - Function pointer for the "fullscreen event callback functions", - defined as: - - typedef EM_BOOL (*em_fullscreenchange_callback_func)(int eventType, const EmscriptenFullscreenChangeEvent *fullscreenChangeEvent, void *userData); - - Parameters: - * **eventType** (*int*) -- The type of fullscreen event - ("EMSCRIPTEN_EVENT_FULLSCREENCHANGE"). - - * **fullscreenChangeEvent** (*const - EmscriptenFullscreenChangeEvent**) -- Information about the - fullscreen event that occurred. - - * **userData** (*void**) -- The "userData" originally passed - to the registration function. - - Returns: - "true" (non zero) to indicate that the event was consumed by the - callback handler. - - Return type: - "EM_BOOL" - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_set_fullscreenchange_callback(const char *target, void *userData, EM_BOOL useCapture, em_fullscreenchange_callback_func callback) - - Registers a callback function for receiving the fullscreenchange - event. - - Parameters: - * **target** (*const char**) -- Target HTML element id. - - * **userData** (*void**) -- User-defined data to be passed to - the callback (opaque to the API). - - * **useCapture** (*EM_BOOL*) -- Set "true" to use capture. - - * **callback** (*em_fullscreenchange_callback_func*) -- A - callback function. The function is called with the type of - event, information about the event, and user data passed from - this registration function. The callback should return "true" - if the event is consumed. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EMSCRIPTEN_RESULT emscripten_get_fullscreen_status(EmscriptenFullscreenChangeEvent *fullscreenStatus) - - Returns the current page fullscreen state. - - Parameters: - * **fullscreenStatus** (*EmscriptenFullscreenChangeEvent**) -- - The most recently received fullscreen state. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EMSCRIPTEN_RESULT emscripten_request_fullscreen(const char *target, EM_BOOL deferUntilInEventHandler) - - Requests the given target element to transition to full screen - mode. - - Note: This function can be called anywhere, but for web security - reasons its associated *request* can only be raised inside the - event handler for a user-generated event (for example a key, - mouse or touch press/release). This has implications for porting - and the value of "deferUntilInEventHandler" — see Functions - affected by web security for more information. - - Note: This function only performs a fullscreen request without - changing any parameters of the DOM element that is to be - displayed in fullscreen mode. At the time of writing, there are - differences in how browsers present elements in fullscreen mode. - For more information, read the discussion at - https://github.com/kripken/emscripten/issues/2556. To display an - element in fullscreen mode in a way that is consistent across - browsers, prefer calling the function - "emscripten_request_fullscreen_strategy()" instead. This function - is best called only in scenarios where the preconfigured presets - defined by "emscripten_request_fullscreen_strategy()" conflict - with the developer's use case in some way. - - Parameters: - * **target** (*const char**) -- Target HTML element id. - - * **deferUntilInEventHandler** (*EM_BOOL*) -- If "true" - requests made outside of a user-generated event handler are - automatically deferred until the user next presses a keyboard - or mouse button. If "false" the request will fail if called - outside of a user-generated event handler. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - **EMSCRIPTEN_RESULT** - -EMSCRIPTEN_RESULT emscripten_request_fullscreen_strategy(const char *target, EM_BOOL deferUntilInEventHandler, const EmscriptenFullscreenStrategy *fullscreenStrategy) - - Requests the given target element to transition to full screen - mode, using a custom presentation mode for the element. This - function is otherwise the same as - "emscripten_request_fullscreen()", but this function adds options - to control how resizing and aspect ratio, and ensures that the - behavior is consistent across browsers. - - Note: This function makes changes to the DOM to satisfy - consistent presentation across browsers. These changes have been - designed to intrude as little as possible, and the changes are - cleared once windowed browsing is restored. If any of these - changes are conflicting, see the function - "emscripten_request_fullscreen()" instead, which performs a bare - fullscreen request without any modifications to the DOM. - - Parameters: - * **fullscreenStrategy** (*const - EmscriptenFullscreenStrategy**) -- [in] Points to a - configuration structure filled by the caller which specifies - display options for the fullscreen mode. - -EMSCRIPTEN_RESULT emscripten_exit_fullscreen(void) - - Returns back to windowed browsing mode from a proper fullscreen - mode. - - Do not call this function to attempt to return to windowed browsing - mode from a soft fullscreen mode, or vice versa. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EMSCRIPTEN_RESULT emscripten_enter_soft_fullscreen(const char *target, const EmscriptenFullscreenStrategy *fullscreenStrategy) - - Enters a "soft" fullscreen mode, where the given target element is - displayed in the whole client area of the page and all other - elements are hidden, but does not actually request fullscreen mode - for the browser. This function is useful in cases where the actual - Fullscreen API is not desirable or needed, for example in packaged - apps for Firefox OS, where applications essentially already cover - the whole screen. - - Pressing the esc button does not automatically exit the soft - fullscreen mode. To return to windowed presentation mode, manually - call the function "emscripten_exit_soft_fullscreen()". - -EMSCRIPTEN_RESULT emscripten_exit_soft_fullscreen() - - Returns back to windowed browsing mode from a soft fullscreen mode. - Do not call this function to attempt to return to windowed browsing - mode from a real fullscreen mode, or vice versa. - - -Pointerlock -=========== - - -Defines -------- - -EMSCRIPTEN_EVENT_POINTERLOCKCHANGE - - Emscripten pointerlockchange events. - - -Struct ------- - -EmscriptenPointerlockChangeEvent - - The event structure passed in the pointerlockchange event. - - EM_BOOL isActive - - Specifies whether an element on the browser page currently has - pointer lock enabled. - - EM_UTF8 nodeName - - The nodeName of the target HTML Element that has the pointer - lock active. - - Maximum size 128 "char" (i.e. "EM_UTF8 nodeName[128]"). - - EM_UTF8 id - - The ID of the target HTML element that has the pointer lock - active. - - Maximum size 128 "char" (i.e. "EM_UTF8 id[128]"). - - -Callback functions ------------------- - -em_pointerlockchange_callback_func - - Function pointer for the "pointerlockchange event callback - functions", defined as: - - typedef EM_BOOL (*em_pointerlockchange_callback_func)(int eventType, const EmscriptenPointerlockChangeEvent *pointerlockChangeEvent, void *userData); - - Parameters: - * **eventType** (*int*) -- The type of pointerlockchange event - ("EMSCRIPTEN_EVENT_POINTERLOCKCHANGE"). - - * **pointerlockChangeEvent** (*const - EmscriptenPointerlockChangeEvent**) -- Information about the - pointerlockchange event that occurred. - - * **userData** (*void**) -- The "userData" originally passed - to the registration function. - - Returns: - "true" (non zero) to indicate that the event was consumed by the - callback handler. - - Return type: - "EM_BOOL" - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_set_pointerlockchange_callback(const char *target, void *userData, EM_BOOL useCapture, em_pointerlockchange_callback_func callback) - - Registers a callback function for receiving the pointerlockchange - event. - - Pointer lock hides the mouse cursor and exclusively gives the - target element relative mouse movement events via the mousemove - event. - - Parameters: - * **target** (*const char**) -- Target HTML element id. - - * **userData** (*void**) -- User-defined data to be passed to - the callback (opaque to the API). - - * **useCapture** (*EM_BOOL*) -- Set "true" to use capture. - - * **callback** (*em_pointerlockchange_callback_func*) -- A - callback function. The function is called with the type of - event, information about the event, and user data passed from - this registration function. The callback should return "true" - if the event is consumed. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EMSCRIPTEN_RESULT emscripten_get_pointerlock_status(EmscriptenPointerlockChangeEvent *pointerlockStatus) - - Returns the current page pointerlock state. - - Parameters: - * **pointerlockStatus** (*EmscriptenPointerlockChangeEvent**) - -- The most recently received pointerlock state. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EMSCRIPTEN_RESULT emscripten_request_pointerlock(const char *target, EM_BOOL deferUntilInEventHandler) - - Requests the given target element to grab pointerlock. - - Note: This function can be called anywhere, but for web security - reasons its associated *request* can only be raised inside the - event handler for a user-generated event (for example a key, - mouse or touch press/release). This has implications for porting - and the value of "deferUntilInEventHandler" — see Functions - affected by web security for more information. - - Parameters: - * **target** (*const char**) -- Target HTML element id. - - * **deferUntilInEventHandler** (*EM_BOOL*) -- If "true" - requests made outside of a user-generated event handler are - automatically deferred until the user next presses a keyboard - or mouse button. If "false" the request will fail if called - outside of a user-generated event handler. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EMSCRIPTEN_RESULT emscripten_exit_pointerlock(void) - - Exits pointer lock state and restores the mouse cursor to be - visible again. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - - -Visibility -========== - - -Defines -------- - -EMSCRIPTEN_EVENT_VISIBILITYCHANGE - - Emscripten visibilitychange event. - -EMSCRIPTEN_VISIBILITY_HIDDEN - - The document is hidden (not visible). - -EMSCRIPTEN_VISIBILITY_VISIBLE - - The document is at least partially visible. - -EMSCRIPTEN_VISIBILITY_PRERENDER - - The document is loaded off screen and not visible (prerender). - -EMSCRIPTEN_VISIBILITY_UNLOADED - - The document is to be unloaded. - - -Struct ------- - -EmscriptenVisibilityChangeEvent - - The event structure passed in the visibilitychange event. - - EM_BOOL hidden - - If true, the current browser page is now hidden. - - int visibilityState - - Specifies a more fine-grained state of the current page - visibility status. One of the "EMSCRIPTEN_VISIBILITY_" values. - - -Callback functions ------------------- - -em_visibilitychange_callback_func - - Function pointer for the "visibilitychange event callback - functions", defined as: - - typedef EM_BOOL (*em_visibilitychange_callback_func)(int eventType, const EmscriptenVisibilityChangeEvent *visibilityChangeEvent, void *userData); - - Parameters: - * **eventType** (*int*) -- The type of "visibilitychange" - event ("EMSCRIPTEN_VISIBILITY_HIDDEN"). - - * **visibilityChangeEvent** (*const - EmscriptenVisibilityChangeEvent**) -- Information about the - "visibilitychange" event that occurred. - - * **userData** (*void**) -- The "userData" originally passed - to the registration function. - - Returns: - "true" (non zero) to indicate that the event was consumed by the - callback handler. - - Return type: - "EM_BOOL" - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_set_visibilitychange_callback(void *userData, EM_BOOL useCapture, em_visibilitychange_callback_func callback) - - Registers a callback function for receiving the visibilitychange - event. - - Parameters: - * **userData** (*void**) -- User-defined data to be passed to - the callback (opaque to the API). - - * **useCapture** (*EM_BOOL*) -- Set "true" to use capture. - - * **callback** (*em_visibilitychange_callback_func*) -- A - callback function. The function is called with the type of - event, information about the event, and user data passed from - this registration function. The callback should return "true" - if the event is consumed. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EMSCRIPTEN_RESULT emscripten_get_visibility_status(EmscriptenVisibilityChangeEvent *visibilityStatus) - - Returns the current page visibility state. - - Parameters: - * **visibilityStatus** (*EmscriptenVisibilityChangeEvent**) -- - The most recently received page visibility state. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - - -Touch -===== - - -Defines -------- - -EMSCRIPTEN_EVENT_TOUCHSTART -EMSCRIPTEN_EVENT_TOUCHEND -EMSCRIPTEN_EVENT_TOUCHMOVE -EMSCRIPTEN_EVENT_TOUCHCANCEL - - Emscripten touch events. - - -Struct ------- - -EmscriptenTouchPoint - - Specifies the status of a single touch point on the page. - - long identifier - - An identification number for each touch point. - - long screenX - long screenY - - The touch coordinate relative to the whole screen origin, in - pixels. - - long clientX - long clientY - - The touch coordinate relative to the viewport, in pixels. - - long pageX - long pageY - - The touch coordinate relative to the viewport, in pixels, and - including any scroll offset. - - EM_BOOL isChanged - - Specifies whether the touch point changed during this event. - - EM_BOOL onTarget - - Specifies whether this touch point is still above the original - target on which it was initially pressed. - - long targetX - long targetY - - These fields give the touch coordinates mapped relative to the - coordinate space of the target DOM element receiving the input - events (Emscripten-specific extension). - - long canvasX - long canvasY - - The touch coordinates mapped to the Emscripten canvas client - area, in pixels (Emscripten-specific extension). - -EmscriptenTouchEvent - - Specifies the data of a single touchevent. - - int numTouches - - The number of valid elements in the touches array. - - EM_BOOL ctrlKey - EM_BOOL shiftKey - EM_BOOL altKey - EM_BOOL metaKey - - Specifies which modifiers were active during the touch event. - - EmscriptenTouchPoint touches[32] - - An array of currently active touches, one for each finger. - - -Callback functions ------------------- - -em_touch_callback_func - - Function pointer for the "touch event callback functions", defined - as: - - typedef EM_BOOL (*em_touch_callback_func)(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData); - - Parameters: - * **eventType** (*int*) -- The type of touch event - ("EMSCRIPTEN_EVENT_TOUCHSTART"). - - * **touchEvent** (*const EmscriptenTouchEvent**) -- - Information about the touch event that occurred. - - * **userData** (*void**) -- The "userData" originally passed - to the registration function. - - Returns: - "true" (non zero) to indicate that the event was consumed by the - callback handler. - - Return type: - "EM_BOOL" - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_set_touchstart_callback(const char *target, void *userData, EM_BOOL useCapture, em_touch_callback_func callback) -EMSCRIPTEN_RESULT emscripten_set_touchend_callback(const char *target, void *userData, EM_BOOL useCapture, em_touch_callback_func callback) -EMSCRIPTEN_RESULT emscripten_set_touchmove_callback(const char *target, void *userData, EM_BOOL useCapture, em_touch_callback_func callback) -EMSCRIPTEN_RESULT emscripten_set_touchcancel_callback(const char *target, void *userData, EM_BOOL useCapture, em_touch_callback_func callback) - - Registers a callback function for receiving touch events : - touchstart, touchend, touchmove and touchcancel. - - Parameters: - * **target** (*const char**) -- Target HTML element id. - - * **userData** (*void**) -- User-defined data to be passed to - the callback (opaque to the API). - - * **useCapture** (*EM_BOOL*) -- Set "true" to use capture. - - * **callback** (*em_touch_callback_func*) -- A callback - function. The function is called with the type of event, - information about the event, and user data passed from this - registration function. The callback should return "true" if - the event is consumed. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - - -Gamepad -======= - - -Defines -------- - -EMSCRIPTEN_EVENT_GAMEPADCONNECTED -EMSCRIPTEN_EVENT_GAMEPADDISCONNECTED - - Emscripten gamepad events. - - -Struct ------- - -EmscriptenGamepadEvent - - Represents the current snapshot state of a gamepad. - - double timestamp - - Absolute wallclock time when the data was recorded - (milliseconds). - - int numAxes - - The number of valid axis entries in the "axis" array. - - int numButtons - - The number of valid button entries in the analogButton and - digitalButton arrays. - - double axis[64] - - The analog state of the gamepad axes, in the range [-1, 1]. - - double analogButton[64] - - The analog state of the gamepad buttons, in the range [0, 1]. - - EM_BOOL digitalButton[64] - - The digital state of the gamepad buttons, either 0 or 1. - - EM_BOOL connected - - Specifies whether this gamepad is connected to the browser page. - - long index - - An ordinal associated with this gamepad, zero-based. - - EM_UTF8 id - - An ID for the brand or style of the connected gamepad device. - Typically, this will include the USB vendor and a product ID. - - Maximum size 64 "char" (i.e. "EM_UTF8 id[128]"). - - EM_UTF8 mapping - - A string that identifies the layout or control mapping of this - device. - - Maximum size 128 "char" (i.e. "EM_UTF8 mapping[128]"). - - -Callback functions ------------------- - -em_gamepad_callback_func - - Function pointer for the "gamepad event callback functions", - defined as: - - typedef EM_BOOL (*em_gamepad_callback_func)(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData) - - Parameters: - * **eventType** (*int*) -- The type of gamepad event - ("EMSCRIPTEN_EVENT_GAMEPADCONNECTED"). - - * **gamepadEvent** (*const EmscriptenGamepadEvent**) -- - Information about the gamepad event that occurred. - - * **userData** (*void**) -- The "userData" originally passed - to the registration function. - - Returns: - "true" (non zero) to indicate that the event was consumed by the - callback handler. - - Return type: - "EM_BOOL" - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_set_gamepadconnected_callback(void *userData, EM_BOOL useCapture, em_gamepad_callback_func callback) -EMSCRIPTEN_RESULT emscripten_set_gamepaddisconnected_callback(void *userData, EM_BOOL useCapture, em_gamepad_callback_func callback) - - Registers a callback function for receiving the gamepad events: - gamepadconnected and gamepaddisconnected. - - Parameters: - * **userData** (*void**) -- User-defined data to be passed to - the callback (opaque to the API). - - * **useCapture** (*EM_BOOL*) -- Set "true" to use capture. - - * **callback** (*em_gamepad_callback_func*) -- A callback - function. The function is called with the type of event, - information about the event, and user data passed from this - registration function. The callback should return "true" if - the event is consumed. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -int emscripten_get_num_gamepads(void) - - Returns the number of gamepads connected to the system or - "EMSCRIPTEN_RESULT_NOT_SUPPORTED" if the current browser does not - support gamepads. - - Note: A gamepad does not show up as connected until a button on - it is pressed. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - int - -EMSCRIPTEN_RESULT emscripten_get_gamepad_status(int index, EmscriptenGamepadEvent *gamepadState) - - Returns a snapshot of the current gamepad state. - - Parameters: - * **index** (*int*) -- The index of the gamepad to check (in - the array of connected gamepads). - - * **gamepadState** (*EmscriptenGamepadEvent**) -- The most - recently received gamepad state. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - - -Battery -======= - - -Defines -------- - -EMSCRIPTEN_EVENT_BATTERYCHARGINGCHANGE -EMSCRIPTEN_EVENT_BATTERYLEVELCHANGE - - Emscripten batterymanager events. - - -Struct ------- - -EmscriptenBatteryEvent - - The event structure passed in the batterymanager events: - "chargingchange" and "levelchange". - - double chargingTime - - Time remaining until the battery is fully charged (seconds). - - double dischargingTime - - Time remaining until the battery is empty and the system will be - suspended (seconds). - - double level - - Current battery level, on a scale of 0 to 1.0. - - EM_BOOL charging; - - "true" if the battery is charging, "false" otherwise. - - -Callback functions ------------------- - -em_battery_callback_func - - Function pointer for the "batterymanager event callback functions", - defined as: - - typedef EM_BOOL (*em_battery_callback_func)(int eventType, const EmscriptenBatteryEvent *batteryEvent, void *userData); - - Parameters: - * **eventType** (*int*) -- The type of "batterymanager" event - ("EMSCRIPTEN_EVENT_BATTERYCHARGINGCHANGE"). - - * **batteryEvent** (*const EmscriptenBatteryEvent**) -- - Information about the "batterymanager" event that occurred. - - * **userData** (*void**) -- The "userData" originally passed - to the registration function. - - Returns: - "true" (non zero) to indicate that the event was consumed by the - callback handler. - - Return type: - "EM_BOOL" - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_set_batterychargingchange_callback(void *userData, em_battery_callback_func callback) -EMSCRIPTEN_RESULT emscripten_set_batterylevelchange_callback(void *userData, em_battery_callback_func callback) - - Registers a callback function for receiving the batterymanager - events: "chargingchange" and "levelchange". - - Parameters: - * **userData** (*void**) -- User-defined data to be passed to - the callback (opaque to the API). - - * **useCapture** (*EM_BOOL*) -- Set "true" to use capture. - - * **callback** (*em_battery_callback_func*) -- A callback - function. The function is called with the type of event, - information about the event, and user data passed from this - registration function. The callback should return "true" if - the event is consumed. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EMSCRIPTEN_RESULT emscripten_get_battery_status(EmscriptenBatteryEvent *batteryState) - - Returns the current battery status. - - Parameters: - * **batteryState** (*EmscriptenBatteryEvent**) -- The most - recently received battery state. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - - -Vibration -========= - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_vibrate(int msecs) - - Produces a vibration for the specified time, in milliseconds. - - Parameters: - * **msecs** (*int*) -- The amount of time for which the - vibration is required (milliseconds). - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EMSCRIPTEN_RESULT emscripten_vibrate_pattern(int *msecsArray, int numEntries) - - Produces a complex vibration feedback pattern. - - Parameters: - * **msecsArray** (*int**) -- An array of timing entries [on, - off, on, off, on, off, ...] where every second one specifies a - duration of vibration, and every other one specifies a - duration of silence. - - * **numEntries** (*int*) -- The number of integers in the - array "msecsArray". - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - - -Page unload -=========== - - -Defines -------- - -EMSCRIPTEN_EVENT_BEFOREUNLOAD - - Emscripten beforeunload event. - - -Callback functions ------------------- - -em_beforeunload_callback - - Function pointer for the "beforeunload event callback functions", - defined as: - - typedef const char *(*em_beforeunload_callback)(int eventType, const void *reserved, void *userData); - - Parameters: - * **eventType** (*int*) -- The type of "beforeunload" event - ("EMSCRIPTEN_EVENT_BEFOREUNLOAD"). - - * **reserved** (*const void**) -- Reserved for future use; - pass in 0. - - * **userData** (*void**) -- The "userData" originally passed - to the registration function. - - Returns: - Return a string to be displayed to the user. - - Return type: - char* - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_set_beforeunload_callback(void *userData, em_beforeunload_callback callback) - - Registers a callback function for receiving the page beforeunload - event. - - Hook into this event to perform actions immediately prior to page - close (for example, to display a notification to ask if the user - really wants to leave the page). - - Parameters: - * **userData** (*void**) -- User-defined data to be passed to - the callback (opaque to the API). - - * **callback** (*em_beforeunload_callback*) -- A callback - function. The function is called with the type of event, - information about the event, and user data passed from this - registration function. The callback should return "true" if - the event is consumed. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - - -WebGL context -============= - - -Defines -------- - -EMSCRIPTEN_EVENT_WEBGLCONTEXTLOST -EMSCRIPTEN_EVENT_WEBGLCONTEXTRESTORED - - Emscripten WebGL context events. - -EMSCRIPTEN_WEBGL_CONTEXT_HANDLE - - Represents a handle to an Emscripten WebGL context object. The - value 0 denotes an invalid/no context (this is a typedef to an - "int"). - - -Struct ------- - -EmscriptenWebGLContextAttributes - - Specifies WebGL context creation parameters. - - EM_BOOL alpha - - If "true", request an alpha channel for the context. If you - create an alpha channel, you can blend the canvas rendering with - the underlying web page contents. Default value: "true". - - EM_BOOL depth - - If "true", request a depth buffer of at least 16 bits. If - "false", no depth buffer will be initialized. Default value: - "true". - - EM_BOOL stencil - - If "true", request a stencil buffer of at least 8 bits. If - "false", no stencil buffer will be initialized. Default value: - "false". - - EM_BOOL antialias - - If "true", antialiasing will be initialized with a browser- - specified algorithm and quality level. If "false", antialiasing - is disabled. Default value: "true". - - EM_BOOL premultipliedAlpha - - If "true", the alpha channel of the rendering context will be - treated as representing premultiplied alpha values. If "false", - the alpha channel represents non-premultiplied alpha. Default - value: "true". - - EM_BOOL preserveDrawingBuffer - - If "true", the contents of the drawing buffer are preserved - between consecutive "requestAnimationFrame()" calls. If "false", - color, depth and stencil are cleared at the beginning of each - "requestAnimationFrame()". Generally setting this to "false" - gives better performance. Default value: "false". - - EM_BOOL preferLowPowerToHighPerformance - - If "true", hints the browser to initialize a low-power GPU - rendering context. If "false", prefers to initialize a high- - performance rendering context. Default value: "false". - - EM_BOOL failIfMajorPerformanceCaveat - - If "true", requests context creation to abort if the browser is - only able to create a context that does not give good hardware- - accelerated performance. Default value: "false". - - int majorVersion - int minorVersion - - Emscripten-specific extensions which specify the WebGL context - version to initialize. - - For example, pass in "majorVersion=1", "minorVersion=0" to - request a WebGL 1.0 context, and "majorVersion=2", - "minorVersion=0" to request a WebGL 2.0 context. - - Default value: "majorVersion=1", "minorVersion=0" - - EM_BOOL enableExtensionsByDefault - - If "true", all GLES2-compatible non-performance-impacting WebGL - extensions will automatically be enabled for you after the - context has been created. If "false", no extensions are enabled - by default, and you need to manually call - "emscripten_webgl_enable_extension()" to enable each extension - that you want to use. Default value: "true". - - -Callback functions ------------------- - -em_webgl_context_callback - - Function pointer for the "WebGL Context event callback functions", - defined as: - - typedef EM_BOOL (*em_webgl_context_callback)(int eventType, const void *reserved, void *userData); - - Parameters: - * **eventType** (*int*) -- The type of "WebGL context event". - - * **reserved** (*const void**) -- Reserved for future use; - pass in 0. - - * **userData** (*void**) -- The "userData" originally passed - to the registration function. - - Returns: - "true" (non zero) to indicate that the event was consumed by the - callback handler. - - Return type: - "EM_BOOL" - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_set_webglcontextlost_callback(const char *target, void *userData, EM_BOOL useCapture, em_webgl_context_callback callback) -EMSCRIPTEN_RESULT emscripten_set_webglcontextrestored_callback(const char *target, void *userData, EM_BOOL useCapture, em_webgl_context_callback callback) - - Registers a callback function for the canvas WebGL context events: - "webglcontextlost" and "webglcontextrestored". - - Parameters: - * **target** (*const char**) -- Target HTML element id. - - * **userData** (*void**) -- User-defined data to be passed to - the callback (opaque to the API). - - * **useCapture** (*EM_BOOL*) -- Set "true" to use capture. - - * **callback** (*em_webgl_context_callback*) -- A callback - function. The function is called with the type of event, - information about the event, and user data passed from this - registration function. The callback should return "true" if - the event is consumed. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EM_BOOL emscripten_is_webgl_context_lost(const char *target) - - Queries the given canvas element for whether its WebGL context is - in a lost state. - - Parameters: - * **target** (*const char**) -- Reserved for future use, pass - in 0. - - Returns: - "true" if the WebGL context is in a lost state. - - Return type: - "EM_BOOL" - -void emscripten_webgl_init_context_attributes(EmscriptenWebGLContextAttributes *attributes) - - Populates all fields of the given - "EmscriptenWebGLContextAttributes" structure to their default - values for use with WebGL 1.0. - - Call this function as a forward-compatible way to ensure that if - there are new fields added to the - "EmscriptenWebGLContextAttributes" structure in the future, that - they also will get default-initialized without having to change any - code. - - Parameters: - * **attributes** (*EmscriptenWebGLContextAttributes**) -- The - structure to be populated. - -EMSCRIPTEN_WEBGL_CONTEXT_HANDLE emscripten_webgl_create_context(const char *target, const EmscriptenWebGLContextAttributes *attributes) - - Creates and returns a new WebGL context. - - Note: * A successful call to this function will not immediately - make - - that rendering context active. Call - "emscripten_webgl_make_context_current()" after creating a - context to activate it. - - * This function will try to initialize the context version that - was *exactly* requested. It will not e.g. initialize a newer - backwards-compatible version or similar. - - Parameters: - * **target** (*const char**) -- The DOM canvas element in - which to initialize the WebGL context. If 0 is passed, the - element specified by "Module.canvas" will be used. - - * **attributes** (*const EmscriptenWebGLContextAttributes**) -- The - attributes of the requested context version. - - Returns: - On success, a strictly positive value that represents a handle - to the created context. On failure, a negative number that can - be cast to an "EMSCRIPTEN_RESULT" field to get the reason why - the context creation failed. - - Return type: - "EMSCRIPTEN_WEBGL_CONTEXT_HANDLE" - -EMSCRIPTEN_RESULT emscripten_webgl_make_context_current(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context) - - Activates the given WebGL context for rendering. After calling this - function, all OpenGL functions ("glBindBuffer()", "glDrawArrays()", - etc.) can be applied to the given GL context. - - Parameters: - * **context** (*EMSCRIPTEN_WEBGL_CONTEXT_HANDLE*) -- The WebGL - context to activate. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EMSCRIPTEN_WEBGL_CONTEXT_HANDLE emscripten_webgl_get_current_context() - - Returns the currently active WebGL rendering context, or 0 if no - context is active. Calling any WebGL functions when there is no - active rendering context is undefined and may throw a JavaScript - exception. - - Returns: - The currently active WebGL rendering context, or 0 if no context - is active. - - Return type: - "EMSCRIPTEN_WEBGL_CONTEXT_HANDLE" - -EMSCRIPTEN_RESULT emscripten_webgl_destroy_context(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context) - - Deletes the given WebGL context. If that context was active, then - the no context is set to active. - - Parameters: - * **context** (*EMSCRIPTEN_WEBGL_CONTEXT_HANDLE*) -- The WebGL - context to delete. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EM_BOOL emscripten_webgl_enable_extension(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context, const char *extension) - - Enables the given extension on the given context. - - Parameters: - * **context** (*EMSCRIPTEN_WEBGL_CONTEXT_HANDLE*) -- The WebGL - context on which the extension is to be enabled. - - * **extension** (*const char**) -- A string identifying the - WebGL extension. For example "OES_texture_float". - - Returns: - EM_TRUE if the given extension is supported by the context, and - EM_FALSE if the extension was not available. - - Return type: - "EM_BOOL" - - -CSS -=== - - -Functions ---------- - -EMSCRIPTEN_RESULT emscripten_set_element_css_size(const char * target, double width, double height) - - Resizes the css width and height of the element specified by - "target" on the Emscripten web page. - - Parameters: - * **target** (*const char**) -- Element to resize. If 0 is - passed, the element specified by "Module.canvas" will be used. - - * **width** (*double*) -- New width of the element. - - * **height** (*double*) -- New height of the element. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" - -EMSCRIPTEN_RESULT emscripten_get_element_css_size(const char * target, double * width, double * height) - - Gets the current css width and height of the element specified by - "target". - - Parameters: - * **target** (*const char**) -- Element to get size of. If 0 - is passed, the element specified by "Module.canvas" will be - used. - - * **width** (*double**) -- Width of the element. - - * **height** (*double**) -- Height of the element. - - Returns: - "EMSCRIPTEN_RESULT_SUCCESS", or one of the other result values. - - Return type: - "EMSCRIPTEN_RESULT" diff --git a/site/build/text/docs/api_reference/preamble.js.txt b/site/build/text/docs/api_reference/preamble.js.txt deleted file mode 100644 index bb446710811e3..0000000000000 --- a/site/build/text/docs/api_reference/preamble.js.txt +++ /dev/null @@ -1,517 +0,0 @@ - -preamble.js -*********** - -The JavaScript APIs in preamble.js provide programmatic access for -interacting with the compiled C code, including: calling compiled C -functions, accessing memory, converting pointers to JavaScript -"Strings" and "Strings" to pointers (with different -encodings/formats), and other convenience functions. - -Note: All functions should be called though the Module object (for - example: "Module.functionName"). At optimisation "-O2" (and higher) - function names are minified by the closure compiler, and calling - them directly will fail. - - -Table of Contents -^^^^^^^^^^^^^^^^^ - -* Calling compiled C functions from JavaScript - -* Accessing memory - -* Conversion functions — strings, pointers and arrays - -* Run dependencies - -* Stack trace - -* Type accessors for the memory model - - -Calling compiled C functions from JavaScript -============================================ - -ccall(ident, returnType, argTypes, args, opts) - - Call a compiled C function from JavaScript. - - The function executes a compiled C function from JavaScript and - returns the result. C++ name mangling means that "normal" C++ - functions cannot be called; the function must either be defined in - a **.c** file or be a C++ function defined with "extern "C"". - - // Call C from JavaScript - var result = Module.ccall('c_add', // name of C function - 'number', // return type - ['number', 'number'], // argument types - [10, 20]); // arguments - - // result is 30 - - Note: * "ccall" uses the C stack for temporary values. If you - pass a - - string then it is only "alive" until the call is complete. If - the code being called saves the pointer to be used later, it - may point to invalid data. - - * If you need a string to live forever, you can create it, for - example, using "_malloc" and "writeStringToMemory()". However, - you must later delete it manually! - - * LLVM optimizations can inline and remove functions, after - which you will not be able to call them. Similarly, function - names minified by the *Closure Compiler* are inaccessible. In - either case, the solution is to add the functions to the - "EXPORTED_FUNCTIONS" list when you invoke *emcc* : - - -s EXPORTED_FUNCTIONS="['_main', '_myfunc']" - - Exported functions can be called as normal: - - a_result = Module.ccall('myfunc', 'number', ['number'], 10) - - Arguments: - * **ident** -- The name of the C function to be called. - - * **returnType** -- The return type of the function. This can - be ""number"", ""string"" or ""array"", which correspond to - the appropriate JavaScript types (use ""number"" for any C - pointer, and ""array"" for JavaScript arrays and typed arrays; - note that arrays are 8-bit), or for a void function it can be - "null" (note: the JavaScript "null" value, not a string - containing the word "null"). - - Note: 64-bit integers become two 32-bit parameters, for the low - and high bits (since 64-bit integers cannot be represented in - JavaScript numbers). - - Arguments: - * **argTypes** -- An array of the types of arguments for the - function (if there are no arguments, this can be omitted). - Types are as in "returnType", except that "array" is not - supported as there is no way for us to know the length of the - array). - - * **args** -- An array of the arguments to the function, as - native JavaScript values (as in "returnType"). Note that - string arguments will be stored on the stack (the JavaScript - string will become a C string on the stack). - - Returns: - The result of the function call as a native JavaScript value (as - in "returnType"). - - Opts: - An optional options object. It can contain the following - properties: - - * "async": Implies that the ccall will perform an async - operation. This assumes you are using the Emterpreter-Async - option for your code. When using this option, the ccalled - function cannot return a value (it can't be received - synchronously anyhow). - -cwrap(ident, returnType, argTypes) - - Returns a native JavaScript wrapper for a C function. - - This is similar to "ccall()", but returns a JavaScript function - that can be reused as many time as needed. The C function can be - defined in a C file, or be a C-compatible C++ function defined - using "extern "C"" (to prevent name mangling). - - // Call C from JavaScript - var c_javascript_add = Module.cwrap('c_add', // name of C function - 'number', // return type - ['number', 'number']); // argument types - - // Call c_javascript_add normally - console.log(c_javascript_add(10, 20)); // 30 - console.log(c_javascript_add(20, 30)); // 50 - - Note: * "cwrap" uses the C stack for temporary values. If you - pass a - - string then it is only "alive" until the call is complete. If - the code being called saves the pointer to be used later, it - may point to invalid data. - - * If you need a string to live forever, you can create it, for - example, using "_malloc" and "writeStringToMemory()". However, - you must later delete it manually! - - * LLVM optimizations can inline and remove functions, after - which you will not be able to "wrap" them. Similarly, function - names minified by the *Closure Compiler* are inaccessible. In - either case, the solution is to add the functions to the - "EXPORTED_FUNCTIONS" list when you invoke *emcc* : - - -s EXPORTED_FUNCTIONS="['_main', '_myfunc']" - - Exported functions can be called as normal: - - my_func = Module.cwrap('myfunc', 'number', ['number']) - my_func(12) - - Arguments: - * **ident** -- The name of the C function to be called. - - * **returnType** -- The return type of the function. This will - be one of the JavaScript types "number", "string" or "array" - (use "number" for any C pointer, and "array" for JavaScript - arrays and typed arrays; note that arrays are 8-bit). - - * **argTypes** -- An array of the types of arguments for the - function (if there are no arguments, this can be omitted). - Types are as in "returnType", except that "array" is not - supported as there is no way for us to know the length of the - array). - - Returns: - A JavaScript function that can be used for running the C - function. - - -Accessing memory -================ - -setValue(ptr, value, type[, noSafe]) - - Sets a value at a specific memory address at run-time. - - Note: * "setValue()" and "getValue()" only do *aligned* writes - and - - reads. - - * The "type" is an LLVM IR type (one of "i8", "i16", "i32", - "i64", "float", "double", or a pointer type like "i8*" or just - "*"), not JavaScript types as used in "ccall()" or "cwrap()". - This is a lower-level operation, and we do need to care what - specific type is being used. - - Arguments: - * **ptr** -- A pointer (number) representing the memory - address. - - * **value** -- The value to be stored - - * **type** -- An LLVM IR type as a string (see "note" above). - - * **noSafe** (*bool*) -- Developers should ignore this - variable. It is only used in "SAFE_HEAP" compilation mode, - where it can help avoid infinite recursion in some specialist - use cases. - -getValue(ptr, type[, noSafe]) - - Gets a value at a specific memory address at run-time. - - Note: * "setValue()" and "getValue()" only do *aligned* writes - and - - reads! - - * The "type" is an LLVM IR type (one of "i8", "i16", "i32", - "i64", "float", "double", or a pointer type like "i8*" or just - "*"), not JavaScript types as used in "ccall()" or "cwrap()". - This is a lower-level operation, and we do need to care what - specific type is being used. - - Arguments: - * **ptr** -- A pointer (number) representing the memory - address. - - * **type** -- An LLVM IR type as a string (see "note" above). - - * **noSafe** (*bool*) -- Developers should ignore this - variable. It is only used in "SAFE_HEAP" compilation mode, - where it can help avoid infinite recursion in some specialist - use cases. - - Returns: - The value stored at the specified memory address. - - -Conversion functions — strings, pointers and arrays -=================================================== - -Pointer_stringify(ptr[, length]) - - Returns a JavaScript String from a pointer, for use in compiled - code. - - Arguments: - * **ptr** -- The pointer to be converted to a "String". - - * **length** -- The length of the data in the pointer - (optional). - - Returns: - A JavaScript "String" containing the data from "ptr". - - Return type: - String - -UTF8ToString(ptr) - - Given a pointer "ptr" to a null-terminated UTF8-encoded string in - the Emscripten HEAP, returns a copy of that string as a JavaScript - "String" object. - - Arguments: - * **ptr** -- A pointer to a null-terminated UTF8-encoded - string in the Emscripten HEAP. - - Returns: - A JavaScript "String" object - -stringToUTF8(str, outPtr[, maxBytesToWrite]) - - Copies the given JavaScript "String" object "str" to the Emscripten - HEAP at address "outPtr", null-terminated and encoded in UTF8 form. - - Arguments: - * **str** (*String*) -- A JavaScript "String" object. - - * **outPtr** -- Pointer to data copied from "str", encoded in - UTF8 format and null-terminated. - - * **maxBytesToWrite** -- A limit on the number of bytes to - write out. - -UTF16ToString(ptr) - - Given a pointer "ptr" to a null-terminated UTF16LE-encoded string - in the Emscripten HEAP, returns a copy of that string as a - JavaScript "String" object. - - Arguments: - * **ptr** -- A pointer to a null-terminated UTF16LE-encoded - string in the Emscripten HEAP. - - Returns: - A JavaScript "String" object - -stringToUTF16(str, outPtr[, maxBytesToWrite]) - - Copies the given JavaScript "String" object "str" to the Emscripten - HEAP at address "outPtr", null-terminated and encoded in UTF16LE - form. - - The copy will require at most "(str.length*2+1)*2" bytes of space - in the HEAP. - - Arguments: - * **str** (*String*) -- A JavaScript "String" object. - - * **outPtr** -- Pointer to data copied from "str", encoded in - UTF16LE format and null-terminated. - - * **maxBytesToWrite** -- A limit on the number of bytes to - write out. - -UTF32ToString(ptr) - - Given a pointer "ptr" to a null-terminated UTF32LE-encoded string - in the Emscripten HEAP, returns a copy of that string as a - JavaScript "String" object. - - Arguments: - * **ptr** -- A pointer to a null-terminated UTF32LE-encoded - string in the Emscripten HEAP. - - Returns: - A JavaScript "String" object. - -stringToUTF32(str, outPtr[, maxBytesToWrite]) - - Copies the given JavaScript "String" object "str" to the Emscripten - HEAP at address "outPtr", null-terminated and encoded in UTF32LE - form. - - The copy will require at most "(str.length+1)*4" bytes of space in - the HEAP, but can use less, since "str.length" does not return the - number of characters in the string, but the number of UTF-16 code - units in the string. - - Arguments: - * **str** (*String*) -- A JavaScript "String" object. - - * **outPtr** -- Pointer to data copied from "str", encoded in - encoded in UTF32LE format and null-terminated. - - * **maxBytesToWrite** -- A limit on the number of bytes to - write out. - -intArrayFromString(stringy, dontAddNull[, length]) - - This converts a JavaScript string into a C-line array of numbers, - 0-terminated. - - Arguments: - * **stringy** (*String*) -- The string to be converted. - - * **dontAddNull** (*bool*) -- If "true", the new array is not - zero-terminated. - - * **length** -- The length of the array (optional). - - Returns: - The array created from "stringy". - -intArrayToString(array) - - This creates a JavaScript string from a zero-terminated C-line - array of numbers. - - Arguments: - * **array** -- The array to convert. - - Returns: - A "String", containing the content of "array". - -writeStringToMemory(string, buffer, dontAddNull) - - Writes a JavaScript string to a specified address in the heap. - - // Allocate space for string and extra '0' at the end - var buffer = Module._malloc(myString.length+1); - - // Write the string to memory - Module.writeStringToMemory(myString, buffer); - - // We can now send buffer into a C function, it is just a normal char* pointer - - Arguments: - * **string** (*String*) -- The string to write into memory. - - * **buffer** (*Number*) -- The address (number) where "string" - is to be written. - - * **dontAddNull** (*bool*) -- If "true", the new array is not - zero-terminated. - -writeArrayToMemory(array, buffer) - - Writes an array to a specified address in the heap. Note that - memory should to be allocated for the array before it is written. - - Arguments: - * **array** -- The array to write to memory. - - * **buffer** (*Number*) -- The address (number) where "array" - is to be written. - -writeAsciiToMemory(str, buffer, dontAddNull) - - Writes an ASCII string to a specified address in the heap. Note - that memory should to be allocated for the string before it is - written. - - The string is assumed to only have characters in the ASCII - character set. If ASSERTIONS are enabled and this is not the case, - it will fail. - - // Allocate space for string - var buffer = Module._malloc(myString.length); - - // Write the string to memory - Module.writeStringToMemory(myString, buffer); - - Arguments: - * **string** -- The string to write into memory. - - * **buffer** -- The address where "string" is to be written. - - * **dontAddNull** (*bool*) -- If "true", the new string is not - zero-terminated. - - -Run dependencies -================ - -Note that generally run dependencies are managed by the file packager -and other parts of the system. It is rare for developers to use this -API directly. - -addRunDependency(id) - - Adds an "id" to the list of run dependencies. - - This adds a run dependency and increments the run dependency - counter. - - Arguments: - * **id** (*String*) -- An arbitrary id representing the - operation. - -removeRunDependency(id) - - Removes a specified "id" from the list of run dependencies. - - Arguments: - * **id** (*String*) -- The identifier for the specific - dependency to be removed (added with "addRunDependency()") - - -Stack trace -=========== - -stackTrace() - - Returns the current stack track. - - Note: The stack trace is not available at least on IE10 and - Safari 6. - - Returns: - The current stack trace, if available. - - -Type accessors for the memory model -=================================== - -The Emscripten memory representation uses a typed array buffer -("ArrayBuffer") to represent memory, with different views into it -giving access to the different types. The views for accessing -different types of memory are listed below. - -HEAP8 - - View for 8-bit signed memory. - -HEAP16 - - View for 16-bit signed memory. - -HEAP32 - - View for 32-bit signed memory. - -HEAPU8 - - View for 32-bit unsigned memory. - -HEAPU8 - - View for 32-bit unsigned memory. - -HEAPU16 - - View for 16-bit unsigned memory. - -HEAPU32 - - View for 32-bit unsigned memory. - -HEAPF32 - - View for 32-bit float memory. - -HEAPF64 - - View for 64-bit float memory. From b0fdc8716e015ed7449dc14a499cb94d2850bf9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Thu, 23 Jun 2016 00:31:17 +0300 Subject: [PATCH 040/102] Avoid address 0 integrity checking in SAFE_SPLIT_MEMORY mode, since that mode has its own checks. --- src/preamble.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/preamble.js b/src/preamble.js index dccf7e80309c9..0dd58ebed99d6 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -912,8 +912,10 @@ 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 !SAFE_SPLIT_MEMORY + // Also test the global address 0 for integrity. This check is not compatible with SAFE_SPLIT_MEMORY though, since that mode already tests all address 0 accesses on its own. if (HEAP32[0] !== 0x63736d65 /* 'emsc' */) throw 'Runtime error: The application has corrupted its heap memory area (address zero)!'; +#endif } function abortStackOverflow(allocSize) { From e2276a93cde6af63dcf425626c29ee40d2a8bb88 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 23 Jun 2016 13:16:02 -0700 Subject: [PATCH 041/102] update binaryen to 11 --- 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 d86565c9cdea6..5b2d5f80a5361 100644 --- a/tools/ports/binaryen.py +++ b/tools/ports/binaryen.py @@ -1,6 +1,6 @@ import os, shutil, logging -TAG = 'version_10' +TAG = 'version_11' def needed(settings, shared, ports): if not settings.BINARYEN: return False From 20ea73776fdaccb9b717a7b16cd9954f23b794c6 Mon Sep 17 00:00:00 2001 From: Philipp Wiesemann Date: Fri, 24 Jun 2016 18:21:17 +0200 Subject: [PATCH 042/102] Fix typos and function descriptions in documentation (#4413) --- site/source/docs/api_reference/Filesystem-API.rst | 2 +- site/source/docs/api_reference/emscripten.h.rst | 4 ++-- site/source/docs/api_reference/html5.h.rst | 5 ++--- site/source/docs/api_reference/trace.h.rst | 4 ++-- site/source/docs/debugging/CyberDWARF.rst | 8 ++++---- site/source/docs/optimizing/Optimizing-Code.rst | 8 ++++---- .../Interacting-with-code.rst | 8 ++++---- site/source/docs/porting/emterpreter.rst | 4 ++-- 8 files changed, 21 insertions(+), 22 deletions(-) diff --git a/site/source/docs/api_reference/Filesystem-API.rst b/site/source/docs/api_reference/Filesystem-API.rst index ccaa1d4f724d9..c7b306af778ba 100644 --- a/site/source/docs/api_reference/Filesystem-API.rst +++ b/site/source/docs/api_reference/Filesystem-API.rst @@ -72,7 +72,7 @@ This is provided to overcome the limitation that browsers do not offer synchrono .. _filesystem-api-workerfs: WORKERFS ------ +-------- .. note:: This file system is only for use when running code inside a worker. diff --git a/site/source/docs/api_reference/emscripten.h.rst b/site/source/docs/api_reference/emscripten.h.rst index 1be380628c3a8..6deb379aedd76 100644 --- a/site/source/docs/api_reference/emscripten.h.rst +++ b/site/source/docs/api_reference/emscripten.h.rst @@ -573,7 +573,7 @@ Functions :returns: A handle to request (``int``) that can be used to :c:func:`abort ` the request. -.. c:function:: emscripten_async_wget2_abort(int handle) +.. c:function:: void emscripten_async_wget2_abort(int handle) Abort an asynchronous request raised using :c:func:`emscripten_async_wget2` or :c:func:`emscripten_async_wget2_data`. @@ -637,7 +637,7 @@ Emscripten Asynchronous IndexedDB API :param ptr: A pointer to the data to store. :param num: How many bytes to store. :param void* arg: User-defined data that is passed to the callbacks, untouched by the API itself. This may be used by a callback to identify the associated call. - :param em_arg_callback_func onload: Callback on successful load of the URL into the buffer. The callback function parameter values are: + :param em_arg_callback_func onstore: Callback on successful store of the data buffer to the URL. The callback function parameter values are: - *(void*)* : Equal to ``arg`` (user defined data). diff --git a/site/source/docs/api_reference/html5.h.rst b/site/source/docs/api_reference/html5.h.rst index f30ddf978fff8..129b187610580 100644 --- a/site/source/docs/api_reference/html5.h.rst +++ b/site/source/docs/api_reference/html5.h.rst @@ -1779,7 +1779,6 @@ Functions Registers a callback function for receiving the `batterymanager `_ events: ``chargingchange`` and ``levelchange``. :param void* userData: |userData-parameter-doc| - :param EM_BOOL useCapture: |useCapture-parameter-doc| :param em_battery_callback_func callback: |callback-function-parameter-doc| :returns: :c:data:`EMSCRIPTEN_RESULT_SUCCESS`, or one of the other result values. :rtype: |EMSCRIPTEN_RESULT| @@ -2070,7 +2069,7 @@ Functions .. c:function:: EMSCRIPTEN_RESULT emscripten_set_element_css_size(const char * target, double width, double height) - Resizes the css width and height of the element specified by ``target`` on the Emscripten web page. + Resizes the CSS width and height of the element specified by ``target`` on the Emscripten web page. :param target: Element to resize. If 0 is passed, the element specified by ``Module.canvas`` will be used. :type target: const char* @@ -2082,7 +2081,7 @@ Functions .. c:function:: EMSCRIPTEN_RESULT emscripten_get_element_css_size(const char * target, double * width, double * height) - Gets the current css width and height of the element specified by ``target``. + Gets the current CSS width and height of the element specified by ``target``. :param target: Element to get size of. If 0 is passed, the element specified by ``Module.canvas`` will be used. :type target: const char* diff --git a/site/source/docs/api_reference/trace.h.rst b/site/source/docs/api_reference/trace.h.rst index a42730516ba26..fbecc6d92a084 100644 --- a/site/source/docs/api_reference/trace.h.rst +++ b/site/source/docs/api_reference/trace.h.rst @@ -302,7 +302,7 @@ Functions In most cases, the ``collector_url`` will be ``http://127.0.0.1:5000/``. -.. c:function:: void emscripten_configure_for_google_wtf(void) +.. c:function:: void emscripten_trace_configure_for_google_wtf(void) :rtype: void @@ -460,7 +460,7 @@ Functions :param address: Memory address which should be annotated. :type address: const void* :param size: Size of the memory associated with this allocation. - :type type: int32_t + :type size: int32_t :rtype: void Associate an amount of additional storage with this address. This diff --git a/site/source/docs/debugging/CyberDWARF.rst b/site/source/docs/debugging/CyberDWARF.rst index 33831b8a39655..f3bd2a9b89570 100644 --- a/site/source/docs/debugging/CyberDWARF.rst +++ b/site/source/docs/debugging/CyberDWARF.rst @@ -7,17 +7,17 @@ CyberDWARF Debugging Building ======== -To add CyberDWARF support to a build, pass ``-s CYBERDWARF=1`` to ``emcc``. This generates a ``.cd`` file containing type information for debugging and adds a debugging toolkit to the output Javascript. +To add CyberDWARF support to a build, pass ``-s CYBERDWARF=1`` to ``emcc``. This generates a ``.cd`` file containing type information for debugging and adds a debugging toolkit to the output JavaScript. Using ===== -The CyberDWARF debugger is designed to be used from the Javascript devtool console available in most modern browsers. +The CyberDWARF debugger is designed to be used from the JavaScript devtool console available in most modern browsers. Heap Pretty Printer ------------------- -This small example will show how to use CyberDWARF to visualize a simple struct +This small example will show how to use CyberDWARF to visualize a simple struct. .. code-block:: cpp @@ -57,7 +57,7 @@ This small example will show how to use CyberDWARF to visualize a simple struct **Visualizing** -After the page loads, open a Javascript console. +After the page loads, open a JavaScript console. .. code-block:: bash diff --git a/site/source/docs/optimizing/Optimizing-Code.rst b/site/source/docs/optimizing/Optimizing-Code.rst index d0e494684c82f..74ff639f979fe 100644 --- a/site/source/docs/optimizing/Optimizing-Code.rst +++ b/site/source/docs/optimizing/Optimizing-Code.rst @@ -84,8 +84,8 @@ In addition to the above (defining a separate memory initialization file as :ref - Use :ref:`llvm-lto ` when compiling from bitcode to JavaScript: ``--llvm-lto 1``. This can break some code as the LTO code path is less tested. - Disable :ref:`optimizing-code-inlining`: ``-s INLINING_LIMIT=1``. Compiling with -Os or -Oz generally avoids inlining too. - Use :ref:`closure ` on the outside non-asm.js code: ``--closure 1``. This can break code that doesn't use `closure annotations properly `_. -- You can use the ``NO_FILESYSTEM`` option to disable bundling of filesystem support code (the compiler should optimize it out if not used, but may not always succeed). This can be useful if you are building a pure computational library, for example. See ``settings.js`` for more detals. -- You can use ``EXPORTED_RUNTIME_METHODS`` to define which runtime methods are exported. By default a bunch of useful methods are exported, which you may not need; setting this to a smaller list will cause fewer methods to be exported. In conjunction with the closure compiler, this can be very effective, since closure can eliminate non-exported code. See ``settings.js`` for more detals. See ``test_no_nuthin`` in ``tests/test_other.py`` for an example usage in the test suite. +- You can use the ``NO_FILESYSTEM`` option to disable bundling of filesystem support code (the compiler should optimize it out if not used, but may not always succeed). This can be useful if you are building a pure computational library, for example. See ``settings.js`` for more details. +- You can use ``EXPORTED_RUNTIME_METHODS`` to define which runtime methods are exported. By default a bunch of useful methods are exported, which you may not need; setting this to a smaller list will cause fewer methods to be exported. In conjunction with the closure compiler, this can be very effective, since closure can eliminate non-exported code. See ``settings.js`` for more details. See ``test_no_nuthin`` in ``tests/test_other.py`` for an example usage in the test suite. - You can use ``ELIMINATE_DUPLICATE_FUNCTIONS`` to remove duplicate functions, which C++ templates often create. See ``settings.js`` for more details. - You can move some of your code into the `Emterpreter `_, which will then run much slower (as it is interpreted), but it will transfer all that code into a smaller amount of data. - You can use separate modules through `dynamic linking `_. That can increase the total code size of everything, but reduces the maximum size of a single module, which can help in some cases (e.g. if a single big module hits a memory limit). @@ -126,7 +126,7 @@ You can also do this manually, as follows: Running by itself ----------------- -If you hit memory limits in browsers, it can help to run your project by itself, as opposed to inside a web page containing other content. If you open a new web page (as a new tab, or a new window) that contains just your project, then you have the best chance at avoiding memory framentation issues. +If you hit memory limits in browsers, it can help to run your project by itself, as opposed to inside a web page containing other content. If you open a new web page (as a new tab, or a new window) that contains just your project, then you have the best chance at avoiding memory fragmentation issues. Outlining @@ -134,7 +134,7 @@ Outlining JavaScript engines will often compile very large functions slowly (relative to their size), and fail to optimize them effectively (or at all). One approach to this problem is to use "outlining": breaking them into smaller functions that can be compiled and optimized more effectively. -Outlining increases overall code size, and can itself make some code less optimised. Despite this, outlining can sometimes improve both startup and runtime speed. For more information see For more information read `Outlining: a workaround for JITs and big functions `_. +Outlining increases overall code size, and can itself make some code less optimised. Despite this, outlining can sometimes improve both startup and runtime speed. For more information read `Outlining: a workaround for JITs and big functions `_. The ``OUTLINING_LIMIT`` setting defines the function size at which Emscripten will try to break large functions into smaller ones. Search for this setting in `settings.js `_ for information on how to determine what functions may need to be outlined and how to choose an appropriate function size. diff --git a/site/source/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.rst b/site/source/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.rst index e0fc28c8f9abb..9f3c6a096cfed 100644 --- a/site/source/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.rst +++ b/site/source/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.rst @@ -376,10 +376,10 @@ If you add it to your own file, you should write something like first, so this add ``my_js`` onto ``LibraryManager.library``, the global object where all JavaScript library code should be. -JavaScript Limits in library files +JavaScript limits in library files ---------------------------------- -If you're not familar with JavaScript, say if you're a C/C++ programmer +If you're not familiar with JavaScript, say if you're a C/C++ programmer and just using emscripten, then the following issues probably won't come up, but if you're an experienced JavaScript programmer you need to be aware some common JavaScript practices can not be used in certain ways in emscripten @@ -397,7 +397,7 @@ key-value pairs are special. Interior code inside a function can have arbitrary JS, of course). To avoid this limitation of JS libraries, you can put code in another file using -the ``--pre-js`` or ``--post-js`` options, which allow arbitary normal +the ``--pre-js`` or ``--post-js`` options, which allow arbitrary normal JS, and it is included and optimized with the rest of the output. That is the recommended approach for most cases. Another option is another ``