diff --git a/emcc.py b/emcc.py index 70a82eebe65f2..656383f10361e 100755 --- a/emcc.py +++ b/emcc.py @@ -1764,7 +1764,7 @@ def do_minify(): # minifies the code. this is also when we do certain optimizati combined.close() if not shared.Settings.WASM_BACKEND: # generate .wast file - subprocess.check_call([os.path.join(binaryen_bin, 'asm2wasm'), asm_target, wasm_target + '.mappedGlobals'], stdout=open(wasm_target, 'w')) + subprocess.check_call([os.path.join(binaryen_bin, 'asm2wasm'), asm_target, '--mapped-globals=' + wasm_target + '.mappedGlobals'], stdout=open(wasm_target, 'w')) # If we were asked to also generate HTML, do that if final_suffix == 'html': diff --git a/emranlib b/emranlib index 35cb44c950d91..1405320b32b6a 100755 --- a/emranlib +++ b/emranlib @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python ''' emcc - ranlib helper script diff --git a/emscripten-version.txt b/emscripten-version.txt index acf3091b15647..8000dfef96e58 100644 --- a/emscripten-version.txt +++ b/emscripten-version.txt @@ -1,2 +1,2 @@ -"1.35.20" +"1.35.21" diff --git a/src/jsifier.js b/src/jsifier.js index 21b2cbc084548..1b95e8e5a4ca2 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -87,7 +87,10 @@ function JSify(data, functionsOnly) { } function processLibraryFunction(snippet, ident, finalName) { - snippet = snippet.toString(); + // It is possible that when printing the function as a string on Windows, the js interpreter we are in returns the string with Windows + // line endings \r\n. This is undesirable, since line endings are managed in the form \n in the output for binary file writes, so + // make sure the endings are uniform. + snippet = snippet.toString().replace(/\r\n/gm,"\n"); assert(snippet.indexOf('XXX missing C define') == -1, 'Trying to include a library function with missing C defines: ' + finalName + ' | ' + snippet); diff --git a/src/library_glfw.js b/src/library_glfw.js index 5b223364ca5a5..97eb52735b029 100644 --- a/src/library_glfw.js +++ b/src/library_glfw.js @@ -129,6 +129,7 @@ var LibraryGLFW = { /* https://developer.mozilla.org/en/Document_Object_Model_%28DOM%29/KeyboardEvent and GLFW/glfw3.h */ DOMToGLFWKeyCode: function(keycode) { switch (keycode) { + // these keycodes are only defined for GLFW3, assume they are the same for GLFW2 case 0x20:return 32; // DOM_VK_SPACE -> GLFW_KEY_SPACE case 0xDE:return 39; // DOM_VK_QUOTE -> GLFW_KEY_APOSTROPHE case 0xBC:return 44; // DOM_VK_COMMA -> GLFW_KEY_COMMA @@ -177,6 +178,81 @@ var LibraryGLFW = { case 0xDC:return 92; // DOM_VK_BACKSLASH -> GLFW_KEY_BACKSLASH case 0xDD:return 93; // DOM_VK_CLOSE_BRACKET -> GLFW_KEY_RIGHT_BRACKET case 0xC0:return 94; // DOM_VK_BACK_QUOTE -> GLFW_KEY_GRAVE_ACCENT + +#if USE_GLFW == 2 + //#define GLFW_KEY_SPECIAL 256 + case 0x1B:return (256+1); // DOM_VK_ESCAPE -> GLFW_KEY_ESC + case 0x70:return (256+2); // DOM_VK_F1 -> GLFW_KEY_F1 + case 0x71:return (256+3); // DOM_VK_F2 -> GLFW_KEY_F2 + case 0x72:return (256+4); // DOM_VK_F3 -> GLFW_KEY_F3 + case 0x73:return (256+5); // DOM_VK_F4 -> GLFW_KEY_F4 + case 0x74:return (256+6); // DOM_VK_F5 -> GLFW_KEY_F5 + case 0x75:return (256+7); // DOM_VK_F6 -> GLFW_KEY_F6 + case 0x76:return (256+8); // DOM_VK_F7 -> GLFW_KEY_F7 + case 0x77:return (256+9); // DOM_VK_F8 -> GLFW_KEY_F8 + case 0x78:return (256+10); // DOM_VK_F9 -> GLFW_KEY_F9 + case 0x79:return (256+11); // DOM_VK_F10 -> GLFW_KEY_F10 + case 0x7A:return (256+12); // DOM_VK_F11 -> GLFW_KEY_F11 + case 0x7B:return (256+13); // DOM_VK_F12 -> GLFW_KEY_F12 + case 0x7C:return (256+14); // DOM_VK_F13 -> GLFW_KEY_F13 + case 0x7D:return (256+15); // DOM_VK_F14 -> GLFW_KEY_F14 + case 0x7E:return (256+16); // DOM_VK_F15 -> GLFW_KEY_F15 + case 0x7F:return (256+17); // DOM_VK_F16 -> GLFW_KEY_F16 + case 0x80:return (256+18); // DOM_VK_F17 -> GLFW_KEY_F17 + case 0x81:return (256+19); // DOM_VK_F18 -> GLFW_KEY_F18 + case 0x82:return (256+20); // DOM_VK_F19 -> GLFW_KEY_F19 + case 0x83:return (256+21); // DOM_VK_F20 -> GLFW_KEY_F20 + case 0x84:return (256+22); // DOM_VK_F21 -> GLFW_KEY_F21 + case 0x85:return (256+23); // DOM_VK_F22 -> GLFW_KEY_F22 + case 0x86:return (256+24); // DOM_VK_F23 -> GLFW_KEY_F23 + case 0x87:return (256+25); // DOM_VK_F24 -> GLFW_KEY_F24 + case 0x88:return (256+26); // 0x88 (not used?) -> GLFW_KEY_F25 + case 0x27:return (256+27); // DOM_VK_RIGHT -> GLFW_KEY_RIGHT + case 0x25:return (256+28); // DOM_VK_LEFT -> GLFW_KEY_LEFT + case 0x28:return (256+29); // DOM_VK_DOWN -> GLFW_KEY_DOWN + case 0x26:return (256+30); // DOM_VK_UP -> GLFW_KEY_UP + case 0x10:return (256+31); // DOM_VK_SHIFT -> GLFW_KEY_LSHIFT + // #define GLFW_KEY_RSHIFT (GLFW_KEY_SPECIAL+32) + case 0x11:return (256+33); // DOM_VK_CONTROL -> GLFW_KEY_LCTRL + // #define GLFW_KEY_RCTRL (GLFW_KEY_SPECIAL+34) + case 0x12:return (256+35); // DOM_VK_ALT -> GLFW_KEY_LALT + // #define GLFW_KEY_RALT (GLFW_KEY_SPECIAL+36) + case 0x09:return (256+37); // DOM_VK_TAB -> GLFW_KEY_TAB + case 0x0D:return (256+38); // DOM_VK_RETURN -> GLFW_KEY_ENTER + case 0x08:return (256+39); // DOM_VK_BACK -> GLFW_KEY_BACKSPACE + case 0x2D:return (256+40); // DOM_VK_INSERT -> GLFW_KEY_INSERT + case 0x2E:return (256+41); // DOM_VK_DELETE -> GLFW_KEY_DEL + case 0x21:return (256+42); // DOM_VK_PAGE_UP -> GLFW_KEY_PAGEUP + case 0x22:return (256+43); // DOM_VK_PAGE_DOWN -> GLFW_KEY_PAGEDOWN + case 0x24:return (256+44); // DOM_VK_HOME -> GLFW_KEY_HOME + case 0x23:return (256+45); // DOM_VK_END -> GLFW_KEY_END + case 0x60:return (256+46); // DOM_VK_NUMPAD0 -> GLFW_KEY_KP_0 + case 0x61:return (256+47); // DOM_VK_NUMPAD1 -> GLFW_KEY_KP_1 + case 0x62:return (256+48); // DOM_VK_NUMPAD2 -> GLFW_KEY_KP_2 + case 0x63:return (256+49); // DOM_VK_NUMPAD3 -> GLFW_KEY_KP_3 + case 0x64:return (256+50); // DOM_VK_NUMPAD4 -> GLFW_KEY_KP_4 + case 0x65:return (256+51); // DOM_VK_NUMPAD5 -> GLFW_KEY_KP_5 + case 0x66:return (256+52); // DOM_VK_NUMPAD6 -> GLFW_KEY_KP_6 + case 0x67:return (256+53); // DOM_VK_NUMPAD7 -> GLFW_KEY_KP_7 + case 0x68:return (256+54); // DOM_VK_NUMPAD8 -> GLFW_KEY_KP_8 + case 0x69:return (256+55); // DOM_VK_NUMPAD9 -> GLFW_KEY_KP_9 + case 0x6F:return (256+56); // DOM_VK_DIVIDE -> GLFW_KEY_KP_DIVIDE + case 0x6A:return (256+57); // DOM_VK_MULTIPLY -> GLFW_KEY_KP_MULTIPLY + case 0x6D:return (256+58); // DOM_VK_SUBTRACT -> GLFW_KEY_KP_SUBTRACT + case 0x6B:return (256+59); // DOM_VK_ADD -> GLFW_KEY_KP_ADD + case 0x6E:return (256+60); // DOM_VK_DECIMAL -> GLFW_KEY_KP_DECIMAL + // #define GLFW_KEY_KP_EQUAL (GLFW_KEY_SPECIAL+61) + // #define GLFW_KEY_KP_ENTER (GLFW_KEY_SPECIAL+62) + case 0x90:return (256+63); // DOM_VK_NUM_LOCK -> GLFW_KEY_KP_NUM_LOCK + case 0x14:return (256+64); // DOM_VK_CAPS_LOCK -> GLFW_KEY_CAPS_LOCK + case 0x91:return (256+65); // DOM_VK_SCROLL_LOCK -> GLFW_KEY_SCROLL_LOCK + case 0x13:return (256+66); // DOM_VK_PAUSE -> GLFW_KEY_PAUSE + case 0x5B:return (256+67); // DOM_VK_WIN -> GLFW_KEY_LSUPER + // #define GLFW_KEY_RSUPER (GLFW_KEY_SPECIAL+68) + case 0x5D:return (256+69); // DOM_VK_CONTEXT_MENU -> GLFW_KEY_MENU +#endif + +#if USE_GLFW == 3 case 0x1B:return 256; // DOM_VK_ESCAPE -> GLFW_KEY_ESCAPE case 0x0D:return 257; // DOM_VK_RETURN -> GLFW_KEY_ENTER case 0x09:return 258; // DOM_VK_TAB -> GLFW_KEY_TAB @@ -247,8 +323,8 @@ var LibraryGLFW = { // case 0x12:return 346; // DOM_VK_ALT -> GLFW_KEY_RIGHT_ALT (DOM_KEY_LOCATION_RIGHT) // case 0x5B:return 347; // DOM_VK_WIN -> GLFW_KEY_RIGHT_SUPER (DOM_KEY_LOCATION_RIGHT) case 0x5D:return 348; // DOM_VK_CONTEXT_MENU -> GLFW_KEY_MENU - // XXX: GLFW_KEY_WORLD_1, GLFW_KEY_WORLD_2 what are these? +#endif default:return -1; // GLFW_KEY_UNKNOWN }; }, diff --git a/src/settings.js b/src/settings.js index af3a3f2f5801c..7adf025041949 100644 --- a/src/settings.js +++ b/src/settings.js @@ -11,6 +11,10 @@ // mode. See apply_opt_level in tools/shared.py for how -O1,2,3 affect these // flags. // +// These flags should only have an effect when compiling to JS, so there +// should not be a need to have them when just compiling source to +// bitcode. However, there will also be no harm either, so it is ok to. +// // Tuning var QUANTUM_SIZE = 4; // This is the size of an individual field in a structure. 1 would diff --git a/system/bin/sdl-config b/system/bin/sdl-config index 51dff31ddcd88..db6ec2fc1e074 100755 --- a/system/bin/sdl-config +++ b/system/bin/sdl-config @@ -1,13 +1,14 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python +from __future__ import print_function import sys -print >> sys.stderr, 'emscripten sdl-config called with', sys.argv +print('emscripten sdl-config called with', ' '.join(sys.argv), file=sys.stderr) args = sys.argv[1:] if args[0] == '--cflags': - print '' + print('') elif '--version' in args: - print '1.3.0' + print('1.3.0') diff --git a/system/bin/sdl2-config b/system/bin/sdl2-config index f155153fd6ade..453fb2703ccc0 100755 --- a/system/bin/sdl2-config +++ b/system/bin/sdl2-config @@ -1,13 +1,14 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python +from __future__ import print_function import sys -print >> sys.stderr, 'emscripten sdl2-config called with', ' '.join(sys.argv) +print('emscripten sdl2-config called with', ' '.join(sys.argv), file=sys.stderr) args = sys.argv[1:] if '--cflags' in args or '--libs' in args: - print '-s USE_SDL=2' + print('-s USE_SDL=2') elif '--version' in args: - print '2.0.0' + print('2.0.0') diff --git a/tests/glfw_events.c b/tests/glfw_events.c new file mode 100644 index 0000000000000..4b8fea11b6caa --- /dev/null +++ b/tests/glfw_events.c @@ -0,0 +1,203 @@ +#ifdef USE_GLFW + #if USE_GLFW == 2 + #include + #else + #include + #endif + #include + #include + + #define MULTILINE(...) #__VA_ARGS__ + #define WIDTH 640 + #define HEIGHT 480 + + // Setup tests + typedef struct { + double x, y; + int button; + int action; + int modify; + } test_args_t; + + typedef struct { + char cmd[80]; + test_args_t args; + } test_t; + + // Javascript event.button 0 = left, 1 = middle, 2 = right + test_t g_tests[] = { + { "Module.injectMouseEvent(10.0, 10.0, 'mousedown', 0)", { 10.0, 10.0, GLFW_MOUSE_BUTTON_1, GLFW_PRESS, -1 } }, + { "Module.injectMouseEvent(10.0, 20.0, 'mouseup', 0)", { 10.0, 20.0, GLFW_MOUSE_BUTTON_1, GLFW_RELEASE, -1 } }, + { "Module.injectMouseEvent(10.0, 30.0, 'mousedown', 2)", { 10.0, 30.0, GLFW_MOUSE_BUTTON_2, GLFW_PRESS, -1 } }, + { "Module.injectMouseEvent(10.0, 40.0, 'mouseup', 2)", { 10.0, 40.0, GLFW_MOUSE_BUTTON_2, GLFW_RELEASE, -1 } }, + //{ "Module.injectMouseEvent(10.0, 50.0, 'mousewheel', 0)", { 10.0, 50.0, -1, -1, -1 } }, + //{ "Module.injectMouseEvent(10.0, 60.0, 'mousemove', 0)", { 10.0, 60.0, -1, -1, -1 } } + + { "Module.injectKeyEvent('keydown', 0x08)", { 0.0, 0.0, GLFW_KEY_BACKSPACE, GLFW_PRESS, -1 } }, + { "Module.injectKeyEvent('keyup', 0x08)", { 0.0, 0.0, GLFW_KEY_BACKSPACE, GLFW_RELEASE, -1 } }, + { "Module.injectKeyEvent('keydown', 0x09)", { 0.0, 0.0, GLFW_KEY_TAB, GLFW_PRESS, -1 } }, + { "Module.injectKeyEvent('keydown', 0x70)", { 0.0, 0.0, GLFW_KEY_F1, GLFW_PRESS, -1 } }, + + #if USE_GLFW == 2 + { "Module.injectKeyEvent('keydown', 0x1B)", { 0.0, 0.0, GLFW_KEY_ESC, GLFW_PRESS, -1 } }, + #else + { "Module.injectKeyEvent('keydown', 0x1B)", { 0.0, 0.0, GLFW_KEY_ESCAPE, GLFW_PRESS, -1 } }, + #endif + }; + + static unsigned int g_test_actual = 0; + static unsigned int g_test_count = sizeof(g_tests) / sizeof(test_t); + static unsigned int g_state = 0; + + #if USE_GLFW == 2 + static void on_mouse_button_vallback(int button, int action) + #else + static void on_mouse_button_vallback(GLFWwindow* window, int button, int action, int modify) + #endif + { + test_args_t args = g_tests[g_test_actual].args; + if (args.button == button && args.action == action) + { + g_state |= 1 << g_test_actual; + } + else + { + printf("Test %d: FAIL\n", g_test_actual); + } + } + + #if USE_GLFW == 2 + static void on_mouse_move(int x, int y) + #else + static void on_mouse_move(GLFWwindow* window, double x, double y) + #endif + { + test_args_t args = g_tests[g_test_actual].args; + if (args.x == x && args.y == y) + { + g_state |= 1 << g_test_actual; + } + else + { + printf("Test %d: FAIL\n", g_test_actual); + } + } + + #if USE_GLFW == 2 + static void on_key_callback(int key, int action) + #else + static void on_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) + #endif + { + test_args_t args = g_tests[g_test_actual].args; + if (args.button == key && args.action == action) + { + g_state |= 1 << g_test_actual; + } + else + { + printf("Test %d: FAIL\n", g_test_actual); + } + } + + #if USE_GLFW == 3 + static void on_mouse_wheel(GLFWwindow* window, double x, double y) + { + test_args_t args = g_tests[g_test_actual].args; + if (args.x == x && args.y == y) + { + g_state |= 1 << g_test_actual; + } + else + { + printf("Test %d: FAIL\n", g_test_actual); + } + } + + static void on_error(int error, const char *msg) + { + printf("%d: %s\n", error, msg); + } + #endif + + int main() + { + int result = 0; + unsigned int success = 0; + + emscripten_run_script(MULTILINE( + Module.injectMouseEvent = function(x, y, event_, button) { + var canvas = Module['canvas']; + var event = new MouseEvent(event_, { + 'view': window, + 'bubbles': true, + 'cancelable': true, + 'screenX': canvas.offsetLeft + x, + 'screenY': canvas.offsetTop + y, + 'clientX': canvas.offsetLeft + x, + 'clientY': canvas.offsetTop + y, + 'button': button + }); + canvas.dispatchEvent(event); + + //var event = document.createEvent("MouseEvents"); + //var canvas = Module['canvas']; + //event.initMouseEvent(event_, true, true, window, 0, canvas.offsetLeft + x, canvas.offsetTop + y, canvas.offsetLeft + x, canvas.offsetTop + y, 0, 0, 0, 0, button, null); + //canvas.dispatchEvent(event); + }; + + Module.injectKeyEvent = function(type, keyCode) { + var keyboardEvent = document.createEvent("KeyboardEvent"); + var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent"; + keyboardEvent[initMethod](type, true, true, window, false, false, false, false, keyCode, 0); + canvas.dispatchEvent(keyboardEvent); + }; + )); + + + glfwInit(); + + + #if USE_GLFW == 2 + glfwOpenWindow(WIDTH, HEIGHT, 5, 6, 5, 0, 0, 0, GLFW_WINDOW); // != GL_TRUE) + + glfwSetMousePosCallback(on_mouse_move); + glfwSetMouseButtonCallback(on_mouse_button_vallback); + glfwSetKeyCallback(on_key_callback); + //glfwSetCharCallback(...); + #else + glfwSetErrorCallback(on_error); + printf("%s\n", glfwGetVersionString()); + + GLFWwindow * _mainWindow = NULL; + glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); + _mainWindow = glfwCreateWindow(WIDTH, HEIGHT, "glfw3_events", NULL, NULL); + glfwMakeContextCurrent(_mainWindow); + + glfwSetMouseButtonCallback(_mainWindow, on_mouse_button_vallback); + glfwSetCursorPosCallback(_mainWindow, on_mouse_move); + glfwSetScrollCallback(_mainWindow, on_mouse_wheel); + glfwSetKeyCallback(_mainWindow, on_key_callback); + //glfwSetCharCallback(_mainWindow, ...); + #endif + + for (int i = 0; i < g_test_count; ++i) + { + g_test_actual = i; + emscripten_run_script(g_tests[g_test_actual].cmd); + } + + glfwTerminate(); + + success = (1 << (sizeof(g_tests) / sizeof(test_t))) - 1; // (2^count)-1 + + #ifdef REPORT_RESULT + result = g_state == success; + REPORT_RESULT(); + #else + printf("%d == %d = %d", g_state, success, g_state == success); + #endif + + return 0; + } +#endif \ No newline at end of file diff --git a/tests/test_browser.py b/tests/test_browser.py index bfcb0b313398d..6823c7d1f6fc4 100644 --- a/tests/test_browser.py +++ b/tests/test_browser.py @@ -2184,24 +2184,9 @@ def in_html(expected): def test_glfw3(self): self.btest(path_from_root('tests', 'glfw3.c'), args=['-s', 'LEGACY_GL_EMULATION=1', '-s', 'USE_GLFW=3'], expected='1') - def test_glfw3_events(self): - open(os.path.join(self.get_dir(), 'pre.js'), 'w').write(''' - function keydown(c) { - var event = document.createEvent("KeyboardEvent"); - event.initKeyEvent('keydown', true, true, window, - 0, 0, 0, 0, - c, c); - document.dispatchEvent(event); - } - function keyup(c) { - var event = document.createEvent("KeyboardEvent"); - event.initKeyEvent('keyup', true, true, window, - 0, 0, 0, 0, - c, c); - document.dispatchEvent(event); - } - ''') - self.btest(path_from_root('tests', 'glfw3_events.c'), args=['--pre-js', 'pre.js', '-s', 'LEGACY_GL_EMULATION=1', '-s', 'USE_GLFW=3'], expected='1') + def test_glfw_events(self): + self.btest(path_from_root('tests', 'glfw_events.c'), args=['-s', 'USE_GLFW=2', "-DUSE_GLFW=2"], expected='1') + self.btest(path_from_root('tests', 'glfw_events.c'), args=['-s', 'USE_GLFW=3', "-DUSE_GLFW=3"], expected='1') def test_asm_swapping(self): self.clear() @@ -2772,7 +2757,7 @@ def test_pthread_64bit_cxx11_atomics(self): def test_pthread_gcc_atomic_fetch_and_op(self): # We need to resort to using regexes to optimize out SharedArrayBuffer when pthreads are not supported, which is brittle! # Therefore perform very extensive testing of different codegen modes to catch any problems. - for opt in [[], ['-O1'], ['-O2'], ['-O3'], ['-Os'], ['-Oz']]: + for opt in [[], ['-O1'], ['-O2'], ['-O3'], ['-O3', '-s', 'AGGRESSIVE_VARIABLE_ELIMINATION=1'], ['-Os'], ['-Oz']]: for debug in [[], ['-g1'], ['-g2'], ['-g4']]: for f32 in [[], ['-s', 'PRECISE_F32=1']]: print opt, debug, f32 diff --git a/tools/client_mods.py b/tools/client_mods.py index edcc8eaeb681c..399de5e0a85bb 100644 --- a/tools/client_mods.py +++ b/tools/client_mods.py @@ -71,46 +71,48 @@ def get(settings, minified): var atomics_or = /var\s+([^=]+?)\s*=\s*global\.Atomics\.or;/.exec(code)[1]; var atomics_xor = /var\s+([^=]+?)\s*=\s*global\.Atomics\.xor;/.exec(code)[1]; - // "Atomics_load(HEAP32, index)" -> "HEAP32[index]|0" and same for other heap types. - code = code.replace(new RegExp('\\\\b' + atomics_load + '\\\\((' + heap8 + ')\w*,(.*?)\\\\\)', 'g'), "($1[$2]|0)"); - code = code.replace(new RegExp('\\\\b' + atomics_load + '\\\\((' + heap16 + ')\w*,(.*?)\\\\\)', 'g'), "($1[$2]|0)"); - code = code.replace(new RegExp('\\\\b' + atomics_load + '\\\\((' + heap32 + ')\w*,(.*?)\\\\\)', 'g'), "($1[$2]|0)"); - code = code.replace(new RegExp('\\\\b' + atomics_load + '\\\\((' + heapf32 + ')\w*,(.*?)\\\\\)', 'g'), math_fround + "$1[$2]"+cp); - code = code.replace(new RegExp('\\\\b' + atomics_load + '\\\\((' + heapf64 + ')\w*,(.*?)\\\\\)', 'g'), "(+$1[$2])"); - - // "Atomics_store(HEAP32, index, value)" -> "HEAP32[index] = value" and same for other heap types. - code = code.replace(new RegExp('\\\\b' + atomics_store + '\\\\((.*?),(.*?),(.*?)\\\\\)', 'g'), "($1[$2] = $3)"); - // The Atomics built-ins take as first parameter the heap object, however when replacing those with // polyfill versions, it is not possible to pass a heap object as the first parameter. Therefore // route each call to Atomics to a polyfill function for each type, e.g. "Atomics_add(HEAP32, index, val)" -> "Atomics_add_32(index, val)" - code = code.replace(new RegExp('\\\\b' + atomics_add + '\\\\('+heap8+',(.*?),(.*?)\\\\\)', 'g'), '((' + atomics_add + "_8($1,$2)|0)|0)"); - code = code.replace(new RegExp('\\\\b' + atomics_add + '\\\\('+heap16+',(.*?),(.*?)\\\\\)', 'g'), '((' + atomics_add + "_16($1,$2)|0)|0)"); - code = code.replace(new RegExp('\\\\b' + atomics_add + '\\\\('+heap32+',(.*?),(.*?)\\\\\)', 'g'), '((' + atomics_add + "_32($1,$2)|0)|0)"); - - code = code.replace(new RegExp('\\\\b' + atomics_sub + '\\\\('+heap8+',(.*?),(.*?)\\\\\)', 'g'), '((' + atomics_sub + "_8($1,$2)|0)|0)"); - code = code.replace(new RegExp('\\\\b' + atomics_sub + '\\\\('+heap16+',(.*?),(.*?)\\\\\)', 'g'), '((' + atomics_sub + "_16($1,$2)|0)|0)"); - code = code.replace(new RegExp('\\\\b' + atomics_sub + '\\\\('+heap32+',(.*?),(.*?)\\\\\)', 'g'), '((' + atomics_sub + "_32($1,$2)|0)|0)"); - - code = code.replace(new RegExp('\\\\b' + atomics_and + '\\\\('+heap8+',(.*?),(.*?)\\\\\)', 'g'), '((' + atomics_and + "_8($1,$2)|0)|0)"); - code = code.replace(new RegExp('\\\\b' + atomics_and + '\\\\('+heap16+',(.*?),(.*?)\\\\\)', 'g'), '((' + atomics_and + "_16($1,$2)|0)|0)"); - code = code.replace(new RegExp('\\\\b' + atomics_and + '\\\\('+heap32+',(.*?),(.*?)\\\\\)', 'g'), '((' + atomics_and + "_32($1,$2)|0)|0)"); - - code = code.replace(new RegExp('\\\\b' + atomics_or + '\\\\('+heap8+',(.*?),(.*?)\\\\\)', 'g'), '((' + atomics_or + "_8($1,$2)|0)|0)"); - code = code.replace(new RegExp('\\\\b' + atomics_or + '\\\\('+heap16+',(.*?),(.*?)\\\\\)', 'g'), '((' + atomics_or + "_16($1,$2)|0)|0)"); - code = code.replace(new RegExp('\\\\b' + atomics_or + '\\\\('+heap32+',(.*?),(.*?)\\\\\)', 'g'), '((' + atomics_or + "_32($1,$2)|0)|0)"); - - code = code.replace(new RegExp('\\\\b' + atomics_xor + '\\\\('+heap8+',(.*?),(.*?)\\\\\)', 'g'), '((' + atomics_xor + "_8($1,$2)|0)|0)"); - code = code.replace(new RegExp('\\\\b' + atomics_xor + '\\\\('+heap16+',(.*?),(.*?)\\\\\)', 'g'), '((' + atomics_xor + "_16($1,$2)|0)|0)"); - code = code.replace(new RegExp('\\\\b' + atomics_xor + '\\\\('+heap32+',(.*?),(.*?)\\\\\)', 'g'), '((' + atomics_xor + "_32($1,$2)|0)|0)"); - - code = code.replace(new RegExp('\\\\b' + atomics_exchange + '\\\\('+heap8+',(.*?),(.*?)\\\\\)', 'g'), '(' + atomics_exchange + "_8($1,$2)|0)"); - code = code.replace(new RegExp('\\\\b' + atomics_exchange + '\\\\('+heap16+',(.*?),(.*?)\\\\\)', 'g'), '(' + atomics_exchange + "_16($1,$2)|0)"); - code = code.replace(new RegExp('\\\\b' + atomics_exchange + '\\\\('+heap32+',(.*?),(.*?)\\\\\)', 'g'), '(' + atomics_exchange + "_32($1,$2)|0)"); - - code = code.replace(new RegExp('\\\\b' + atomics_compareExchange + '\\\\('+heap8+',(.*?),(.*?),(.*?)\\\\\)', 'g'), '(' + atomics_compareExchange + "_8($1,$2,$3)|0)"); - code = code.replace(new RegExp('\\\\b' + atomics_compareExchange + '\\\\('+heap16+',(.*?),(.*?),(.*?)\\\\\)', 'g'), '(' + atomics_compareExchange + "_16($1,$2,$3)|0)"); - code = code.replace(new RegExp('\\\\b' + atomics_compareExchange + '\\\\('+heap32+',(.*?),(.*?),(.*?)\\\\\)', 'g'), '(' + atomics_compareExchange + "_32($1,$2,$3)|0)"); + code = code.replace(new RegExp('\\\\b' + atomics_load + '\\\\('+heap8+',', 'g'), atomics_load + "_8("); + code = code.replace(new RegExp('\\\\b' + atomics_load + '\\\\('+heap16+',', 'g'), atomics_load + "_16("); + code = code.replace(new RegExp('\\\\b' + atomics_load + '\\\\('+heap32+',', 'g'), atomics_load + "_32("); + code = code.replace(new RegExp('\\\\b' + atomics_load + '\\\\('+heapf32+',', 'g'), atomics_load + "_f32("); + code = code.replace(new RegExp('\\\\b' + atomics_load + '\\\\('+heapf64+',', 'g'), atomics_load + "_f64("); + + code = code.replace(new RegExp('\\\\b' + atomics_store + '\\\\('+heap8+',', 'g'), atomics_store + "_8("); + code = code.replace(new RegExp('\\\\b' + atomics_store + '\\\\('+heap16+',', 'g'), atomics_store + "_16("); + code = code.replace(new RegExp('\\\\b' + atomics_store + '\\\\('+heap32+',', 'g'), atomics_store + "_32("); + code = code.replace(new RegExp('\\\\b' + atomics_store + '\\\\('+heapf32+',', 'g'), atomics_store + "_f32("); + code = code.replace(new RegExp('\\\\b' + atomics_store + '\\\\('+heapf64+',', 'g'), atomics_store + "_f64("); + + code = code.replace(new RegExp('\\\\b' + atomics_add + '\\\\('+heap8+',', 'g'), atomics_add + "_8("); + code = code.replace(new RegExp('\\\\b' + atomics_add + '\\\\('+heap16+',', 'g'), atomics_add + "_16("); + code = code.replace(new RegExp('\\\\b' + atomics_add + '\\\\('+heap32+',', 'g'), atomics_add + "_32("); + + code = code.replace(new RegExp('\\\\b' + atomics_sub + '\\\\('+heap8+',', 'g'), atomics_sub + "_8("); + code = code.replace(new RegExp('\\\\b' + atomics_sub + '\\\\('+heap16+',', 'g'), atomics_sub + "_16("); + code = code.replace(new RegExp('\\\\b' + atomics_sub + '\\\\('+heap32+',', 'g'), atomics_sub + "_32("); + + code = code.replace(new RegExp('\\\\b' + atomics_and + '\\\\('+heap8+',', 'g'), atomics_and + "_8("); + code = code.replace(new RegExp('\\\\b' + atomics_and + '\\\\('+heap16+',', 'g'), atomics_and + "_16("); + code = code.replace(new RegExp('\\\\b' + atomics_and + '\\\\('+heap32+',', 'g'), atomics_and + "_32("); + + code = code.replace(new RegExp('\\\\b' + atomics_or + '\\\\('+heap8+',', 'g'), atomics_or + "_8("); + code = code.replace(new RegExp('\\\\b' + atomics_or + '\\\\('+heap16+',', 'g'), atomics_or + "_16("); + code = code.replace(new RegExp('\\\\b' + atomics_or + '\\\\('+heap32+',', 'g'), atomics_or + "_32("); + + code = code.replace(new RegExp('\\\\b' + atomics_xor + '\\\\('+heap8+',', 'g'), atomics_xor + "_8("); + code = code.replace(new RegExp('\\\\b' + atomics_xor + '\\\\('+heap16+',', 'g'), atomics_xor + "_16("); + code = code.replace(new RegExp('\\\\b' + atomics_xor + '\\\\('+heap32+',', 'g'), atomics_xor + "_32("); + + code = code.replace(new RegExp('\\\\b' + atomics_exchange + '\\\\('+heap8+',', 'g'), atomics_exchange + "_8("); + code = code.replace(new RegExp('\\\\b' + atomics_exchange + '\\\\('+heap16+',', 'g'), atomics_exchange + "_16("); + code = code.replace(new RegExp('\\\\b' + atomics_exchange + '\\\\('+heap32+',', 'g'), atomics_exchange + "_32("); + + code = code.replace(new RegExp('\\\\b' + atomics_compareExchange + '\\\\('+heap8+',', 'g'), atomics_compareExchange + "_8("); + code = code.replace(new RegExp('\\\\b' + atomics_compareExchange + '\\\\('+heap16+',', 'g'), atomics_compareExchange + "_16("); + code = code.replace(new RegExp('\\\\b' + atomics_compareExchange + '\\\\('+heap32+',', 'g'), atomics_compareExchange + "_32("); // Remove the import statements of Atomics built-ins. code = code.replace(new RegExp("var " + atomics_load + "\\\\s*=\\\\s*global\\.Atomics\\.load;"), ""); @@ -125,6 +127,18 @@ def get(settings, minified): // Implement polyfill versions of Atomics intrinsics inside the asm.js scope. code = code.replace("// EMSCRIPTEN_START_FUNCS", "// EMSCRIPTEN_START_FUNCS\\n" + + "function " + atomics_load + "_8(i) { i=i|0; return "+heap8+"[i>>0]|0; }\\n" + + "function " + atomics_load + "_16(i) { i=i|0; return "+heap16+"[i<<1>>1]|0; }\\n" + + "function " + atomics_load + "_32(i) { i=i|0; return "+heap32+"[i<<2>>2]|0; }\\n" + + "function " + atomics_load + "_f32(i) { i=i|0; return "+math_fround+heapf32+"[i<<2>>2]"+cp+"; }\\n" + + "function " + atomics_load + "_f64(i) { i=i|0; return +"+heapf64+"[i<<3>>3]; }\\n" + + + "function " + atomics_store + "_8(i,v) { i=i|0; v=v|0; "+heap8+"[i>>0]=v; return v|0; }\\n" + + "function " + atomics_store + "_16(i,v) { i=i|0; v=v|0; "+heap16+"[i<<1>>1]=v; return v|0; }\\n" + + "function " + atomics_store + "_32(i,v) { i=i|0; v=v|0; "+heap32+"[i<<2>>2]=v; return v|0; }\\n" + + "function " + atomics_store + "_f32(i,v) { i=i|0; v="+math_fround+"v"+cp+"; "+heapf32+"[i<<2>>2]=v; return "+math_fround+"v"+cp+"; }\\n" + + "function " + atomics_store + "_f64(i,v) { i=i|0; v=+v;" +heapf64+"[i<<3>>3]=v; return +v; }\\n" + + "function " + atomics_add + "_8(i,v) { i=i|0; v=v|0; var w=0; w="+heap8+"[i>>0]|0; "+heap8+"[i>>0]=("+heap8+"[i>>0]|0)+(v|0); return w|0; }\\n" + "function " + atomics_add + "_16(i,v) { i=i|0; v=v|0; var w=0; w="+heap16+"[i<<1>>1]|0; "+heap16+"[i<<1>>1]=("+heap16+"[i<<1>>1]|0)+(v|0); return w|0; }\\n" + "function " + atomics_add + "_32(i,v) { i=i|0; v=v|0; var w=0; w="+heap32+"[i<<2>>2]|0; "+heap32+"[i<<2>>2]=("+heap32+"[i<<2>>2]|0)+(v|0); return w|0; }\\n" diff --git a/tools/line_endings.py b/tools/line_endings.py index e1c8797e39009..325ea32596c3f 100644 --- a/tools/line_endings.py +++ b/tools/line_endings.py @@ -13,8 +13,13 @@ def check_line_endings(filename, print_errors=True): if print_errors: print >> sys.stderr, "Unable to read file '" + filename + "', or file was empty!" return 1 - if "\r\r\n" in data: - if print_errors: print >> sys.stderr, "File '" + filename + "' contains BAD line endings of form \\r\\r\\n!" + bad_line_ending_index = data.find("\r\r\n") + if bad_line_ending_index != -1: + if print_errors: + print >> sys.stderr, "File '" + filename + "' contains BAD line endings of form \\r\\r\\n!" + bad_line = data[max(0,bad_line_ending_index-50):min(len(data), bad_line_ending_index+50)] + bad_line = bad_line.replace('\r', '\\r').replace('\n', '\\n') + print >> sys.stderr, "Content around the location: '" + bad_line + "'" return 1 # Bad line endings in file, return a non-zero process exit code. has_dos_line_endings = False diff --git a/tools/ports/sdl.py b/tools/ports/sdl.py index ab676094fec2d..3ceecd6e5f240 100644 --- a/tools/ports/sdl.py +++ b/tools/ports/sdl.py @@ -1,6 +1,6 @@ import os, shutil, logging -TAG = 'version_9' +TAG = 'version_10' def get_with_configure(ports, settings, shared): # not currently used; no real need for configure on emscripten users' machines! if settings.USE_SDL == 2: