diff --git a/src/lib/libhtml5.js b/src/lib/libhtml5.js index 0d110367b4fe9..6c28e9b5471f7 100644 --- a/src/lib/libhtml5.js +++ b/src/lib/libhtml5.js @@ -258,18 +258,15 @@ var LibraryHTML5 = { #if PTHREADS targetThread = JSEvents.getTargetThreadForEventCallback(targetThread); #endif - JSEvents.keyEvent ||= _malloc({{{ C_STRUCTS.EmscriptenKeyboardEvent.__size__ }}}); + var eventSize = {{{ C_STRUCTS.EmscriptenKeyboardEvent.__size__ }}}; + JSEvents.keyEvent ||= _malloc(eventSize); var keyEventHandlerFunc = (e) => { #if ASSERTIONS assert(e); #endif -#if PTHREADS - var keyEventData = targetThread ? _malloc({{{ C_STRUCTS.EmscriptenKeyboardEvent.__size__ }}}) : JSEvents.keyEvent; // This allocated block is passed as satellite data to the proxied function call, so the call frees up the data block when done. -#else var keyEventData = JSEvents.keyEvent; -#endif {{{ makeSetValue('keyEventData', C_STRUCTS.EmscriptenKeyboardEvent.timestamp, 'e.timeStamp', 'double') }}}; var idx = {{{ getHeapOffset('keyEventData', 'i32') }}}; @@ -289,7 +286,7 @@ var LibraryHTML5 = { stringToUTF8(e.locale || '', keyEventData + {{{ C_STRUCTS.EmscriptenKeyboardEvent.locale }}}, {{{ cDefs.EM_HTML5_SHORT_STRING_LEN_BYTES }}}); #if PTHREADS - if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, keyEventData, userData); + if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, keyEventData, eventSize, userData); else #endif if ({{{ makeDynCall('iipp', 'callbackfunc') }}}(eventTypeId, keyEventData, userData)) e.preventDefault(); @@ -480,7 +477,8 @@ var LibraryHTML5 = { #if PTHREADS targetThread = JSEvents.getTargetThreadForEventCallback(targetThread); #endif - JSEvents.mouseEvent ||= _malloc({{{ C_STRUCTS.EmscriptenMouseEvent.__size__ }}}); + var eventSize = {{{ C_STRUCTS.EmscriptenMouseEvent.__size__ }}}; + JSEvents.mouseEvent ||= _malloc(eventSize); target = findEventTarget(target); var mouseEventHandlerFunc = (e = event) => { @@ -489,9 +487,7 @@ var LibraryHTML5 = { #if PTHREADS if (targetThread) { - var mouseEventData = _malloc({{{ C_STRUCTS.EmscriptenMouseEvent.__size__ }}}); // This allocated block is passed as satellite data to the proxied function call, so the call frees up the data block when done. - fillMouseEventData(mouseEventData, e, target); - __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, mouseEventData, userData); + __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, JSEvents.mouseEvent, eventSize, userData); } else #endif if ({{{ makeDynCall('iipp', 'callbackfunc') }}}(eventTypeId, JSEvents.mouseEvent, userData)) e.preventDefault(); @@ -572,22 +568,19 @@ var LibraryHTML5 = { #if PTHREADS targetThread = JSEvents.getTargetThreadForEventCallback(targetThread); #endif - JSEvents.wheelEvent ||= _malloc({{{ C_STRUCTS.EmscriptenWheelEvent.__size__ }}}); + var eventSize = {{{ C_STRUCTS.EmscriptenWheelEvent.__size__ }}}; + JSEvents.wheelEvent ||= _malloc(eventSize) // The DOM Level 3 events spec event 'wheel' var wheelHandlerFunc = (e = event) => { -#if PTHREADS - var wheelEvent = targetThread ? _malloc({{{ C_STRUCTS.EmscriptenWheelEvent.__size__ }}}) : JSEvents.wheelEvent; // This allocated block is passed as satellite data to the proxied function call, so the call frees up the data block when done. -#else var wheelEvent = JSEvents.wheelEvent; -#endif fillMouseEventData(wheelEvent, e, target); {{{ makeSetValue('wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaX, 'e["deltaX"]', 'double') }}}; {{{ makeSetValue('wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaY, 'e["deltaY"]', 'double') }}}; {{{ makeSetValue('wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaZ, 'e["deltaZ"]', 'double') }}}; {{{ makeSetValue('wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaMode, 'e["deltaMode"]', 'i32') }}}; #if PTHREADS - if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, wheelEvent, userData); + if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, wheelEvent, eventSize, userData); else #endif if ({{{ makeDynCall('iipp', 'callbackfunc') }}}(eventTypeId, wheelEvent, userData)) e.preventDefault(); @@ -624,7 +617,8 @@ var LibraryHTML5 = { #if PTHREADS targetThread = JSEvents.getTargetThreadForEventCallback(targetThread); #endif - JSEvents.uiEvent ||= _malloc({{{ C_STRUCTS.EmscriptenUiEvent.__size__ }}}); + var eventSize = {{{ C_STRUCTS.EmscriptenUiEvent.__size__ }}}; + JSEvents.uiEvent ||= _malloc(eventSize); #if DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR target = findEventTarget(target); @@ -650,11 +644,7 @@ var LibraryHTML5 = { // During a page unload 'body' can be null, with "Cannot read property 'clientWidth' of null" being thrown return; } -#if PTHREADS - var uiEvent = targetThread ? _malloc({{{ C_STRUCTS.EmscriptenUiEvent.__size__ }}}) : JSEvents.uiEvent; -#else var uiEvent = JSEvents.uiEvent; -#endif {{{ makeSetValue('uiEvent', C_STRUCTS.EmscriptenUiEvent.detail, '0', 'i32') }}}; // always zero for resize and scroll {{{ makeSetValue('uiEvent', C_STRUCTS.EmscriptenUiEvent.documentBodyClientWidth, 'b.clientWidth', 'i32') }}}; {{{ makeSetValue('uiEvent', C_STRUCTS.EmscriptenUiEvent.documentBodyClientHeight, 'b.clientHeight', 'i32') }}}; @@ -665,7 +655,7 @@ var LibraryHTML5 = { {{{ makeSetValue('uiEvent', C_STRUCTS.EmscriptenUiEvent.scrollTop, 'pageXOffset | 0', 'i32') }}}; // scroll offsets are float {{{ makeSetValue('uiEvent', C_STRUCTS.EmscriptenUiEvent.scrollLeft, 'pageYOffset | 0', 'i32') }}}; #if PTHREADS - if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, uiEvent, userData); + if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, uiEvent, eventSize, userData); else #endif if ({{{ makeDynCall('iipp', 'callbackfunc') }}}(eventTypeId, uiEvent, userData)) e.preventDefault(); @@ -697,22 +687,19 @@ var LibraryHTML5 = { #if PTHREADS targetThread = JSEvents.getTargetThreadForEventCallback(targetThread); #endif - JSEvents.focusEvent ||= _malloc({{{ C_STRUCTS.EmscriptenFocusEvent.__size__ }}}); + var eventSize = {{{ C_STRUCTS.EmscriptenFocusEvent.__size__ }}}; + JSEvents.focusEvent ||= _malloc(eventSize); var focusEventHandlerFunc = (e = event) => { var nodeName = JSEvents.getNodeNameForTarget(e.target); var id = e.target.id ? e.target.id : ''; -#if PTHREADS - var focusEvent = targetThread ? _malloc({{{ C_STRUCTS.EmscriptenFocusEvent.__size__ }}}) : JSEvents.focusEvent; -#else var focusEvent = JSEvents.focusEvent; -#endif stringToUTF8(nodeName, focusEvent + {{{ C_STRUCTS.EmscriptenFocusEvent.nodeName }}}, {{{ cDefs.EM_HTML5_LONG_STRING_LEN_BYTES }}}); stringToUTF8(id, focusEvent + {{{ C_STRUCTS.EmscriptenFocusEvent.id }}}, {{{ cDefs.EM_HTML5_LONG_STRING_LEN_BYTES }}}); #if PTHREADS - if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, focusEvent, userData); + if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, focusEvent, eventSize, userData); else #endif if ({{{ makeDynCall('iipp', 'callbackfunc') }}}(eventTypeId, focusEvent, userData)) e.preventDefault(); @@ -761,16 +748,15 @@ var LibraryHTML5 = { #if PTHREADS targetThread = JSEvents.getTargetThreadForEventCallback(targetThread); #endif - JSEvents.deviceOrientationEvent ||= _malloc({{{ C_STRUCTS.EmscriptenDeviceOrientationEvent.__size__ }}}); + var eventSize = {{{ C_STRUCTS.EmscriptenDeviceOrientationEvent.__size__ }}}; + JSEvents.deviceOrientationEvent ||= _malloc(eventSize); var deviceOrientationEventHandlerFunc = (e = event) => { fillDeviceOrientationEventData(JSEvents.deviceOrientationEvent, e, target); // TODO: Thread-safety with respect to emscripten_get_deviceorientation_status() #if PTHREADS if (targetThread) { - var deviceOrientationEvent = _malloc({{{ C_STRUCTS.EmscriptenDeviceOrientationEvent.__size__ }}}); - fillDeviceOrientationEventData(deviceOrientationEvent, e, target); - __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, deviceOrientationEvent, userData); + __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, JSEvents.deviceOrientationEvent, eventSize, userData); } else #endif if ({{{ makeDynCall('iipp', 'callbackfunc') }}}(eventTypeId, JSEvents.deviceOrientationEvent, userData)) e.preventDefault(); @@ -832,16 +818,15 @@ var LibraryHTML5 = { #if PTHREADS targetThread = JSEvents.getTargetThreadForEventCallback(targetThread); #endif - JSEvents.deviceMotionEvent ||= _malloc({{{ C_STRUCTS.EmscriptenDeviceMotionEvent.__size__ }}}); + var eventSize = {{{ C_STRUCTS.EmscriptenDeviceMotionEvent.__size__ }}}; + JSEvents.deviceMotionEvent ||= _malloc(eventSize); var deviceMotionEventHandlerFunc = (e = event) => { fillDeviceMotionEventData(JSEvents.deviceMotionEvent, e, target); // TODO: Thread-safety with respect to emscripten_get_devicemotion_status() #if PTHREADS if (targetThread) { - var deviceMotionEvent = _malloc({{{ C_STRUCTS.EmscriptenDeviceMotionEvent.__size__ }}}); - fillDeviceMotionEventData(deviceMotionEvent, e, target); - __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, deviceMotionEvent, userData); + __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, JSEvents.deviceMotionEvent, eventSize, userData); } else #endif if ({{{ makeDynCall('iipp', 'callbackfunc') }}}(eventTypeId, JSEvents.deviceMotionEvent, userData)) e.preventDefault(); @@ -915,19 +900,15 @@ var LibraryHTML5 = { #if PTHREADS targetThread = JSEvents.getTargetThreadForEventCallback(targetThread); #endif - JSEvents.orientationChangeEvent ||= _malloc({{{ C_STRUCTS.EmscriptenOrientationChangeEvent.__size__ }}}); + var eventSize = {{{ C_STRUCTS.EmscriptenOrientationChangeEvent.__size__ }}}; + JSEvents.orientationChangeEvent ||= _malloc(eventSize); var orientationChangeEventHandlerFunc = (e = event) => { -#if PTHREADS - var orientationChangeEvent = targetThread ? _malloc({{{ C_STRUCTS.EmscriptenOrientationChangeEvent.__size__ }}}) : JSEvents.orientationChangeEvent; -#else var orientationChangeEvent = JSEvents.orientationChangeEvent; -#endif - fillOrientationChangeEventData(orientationChangeEvent); #if PTHREADS - if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, orientationChangeEvent, userData); + if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, orientationChangeEvent, eventSize, userData); else #endif if ({{{ makeDynCall('iipp', 'callbackfunc') }}}(eventTypeId, orientationChangeEvent, userData)) e.preventDefault(); @@ -1026,19 +1007,15 @@ var LibraryHTML5 = { #if PTHREADS targetThread = JSEvents.getTargetThreadForEventCallback(targetThread); #endif - JSEvents.fullscreenChangeEvent ||= _malloc({{{ C_STRUCTS.EmscriptenFullscreenChangeEvent.__size__ }}}); + var eventSize = {{{ C_STRUCTS.EmscriptenFullscreenChangeEvent.__size__ }}}; + JSEvents.fullscreenChangeEvent ||= _malloc(eventSize); var fullscreenChangeEventhandlerFunc = (e = event) => { -#if PTHREADS - var fullscreenChangeEvent = targetThread ? _malloc({{{ C_STRUCTS.EmscriptenFullscreenChangeEvent.__size__ }}}) : JSEvents.fullscreenChangeEvent; -#else var fullscreenChangeEvent = JSEvents.fullscreenChangeEvent; -#endif - fillFullscreenChangeEventData(fullscreenChangeEvent); #if PTHREADS - if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, fullscreenChangeEvent, userData); + if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, fullscreenChangeEvent, eventSize, userData); else #endif if ({{{ makeDynCall('iipp', 'callbackfunc') }}}(eventTypeId, fullscreenChangeEvent, userData)) e.preventDefault(); @@ -1528,18 +1505,15 @@ var LibraryHTML5 = { #if PTHREADS targetThread = JSEvents.getTargetThreadForEventCallback(targetThread); #endif - JSEvents.pointerlockChangeEvent ||= _malloc({{{ C_STRUCTS.EmscriptenPointerlockChangeEvent.__size__ }}}); + var eventSize = {{{ C_STRUCTS.EmscriptenPointerlockChangeEvent.__size__ }}}; + JSEvents.pointerlockChangeEvent ||= _malloc(eventSize); var pointerlockChangeEventHandlerFunc = (e = event) => { -#if PTHREADS - var pointerlockChangeEvent = targetThread ? _malloc({{{ C_STRUCTS.EmscriptenPointerlockChangeEvent.__size__ }}}) : JSEvents.pointerlockChangeEvent; -#else var pointerlockChangeEvent = JSEvents.pointerlockChangeEvent; -#endif fillPointerlockChangeEventData(pointerlockChangeEvent); #if PTHREADS - if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, pointerlockChangeEvent, userData); + if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, pointerlockChangeEvent, eventSize, userData); else #endif if ({{{ makeDynCall('iipp', 'callbackfunc') }}}(eventTypeId, pointerlockChangeEvent, userData)) e.preventDefault(); @@ -1725,19 +1699,15 @@ var LibraryHTML5 = { #if PTHREADS targetThread = JSEvents.getTargetThreadForEventCallback(targetThread); #endif - JSEvents.visibilityChangeEvent ||= _malloc({{{ C_STRUCTS.EmscriptenVisibilityChangeEvent.__size__ }}}); + var eventSize = {{{ C_STRUCTS.EmscriptenVisibilityChangeEvent.__size__ }}}; + JSEvents.visibilityChangeEvent ||= _malloc(eventSize); var visibilityChangeEventHandlerFunc = (e = event) => { -#if PTHREADS - var visibilityChangeEvent = targetThread ? _malloc({{{ C_STRUCTS.EmscriptenVisibilityChangeEvent.__size__ }}}) : JSEvents.visibilityChangeEvent; -#else var visibilityChangeEvent = JSEvents.visibilityChangeEvent; -#endif - fillVisibilityChangeEventData(visibilityChangeEvent); #if PTHREADS - if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, visibilityChangeEvent, userData); + if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, visibilityChangeEvent, eventSize, userData); else #endif if ({{{ makeDynCall('iipp', 'callbackfunc') }}}(eventTypeId, visibilityChangeEvent, userData)) e.preventDefault(); @@ -1780,7 +1750,8 @@ var LibraryHTML5 = { #if PTHREADS targetThread = JSEvents.getTargetThreadForEventCallback(targetThread); #endif - JSEvents.touchEvent ||= _malloc({{{ C_STRUCTS.EmscriptenTouchEvent.__size__ }}}); + var eventSize = {{{ C_STRUCTS.EmscriptenTouchEvent.__size__ }}}; + JSEvents.touchEvent ||= _malloc(eventSize); target = findEventTarget(target); @@ -1809,11 +1780,7 @@ var LibraryHTML5 = { touches[t.identifier].onTarget = 1; } -#if PTHREADS - var touchEvent = targetThread ? _malloc({{{ C_STRUCTS.EmscriptenTouchEvent.__size__ }}}) : JSEvents.touchEvent; -#else var touchEvent = JSEvents.touchEvent; -#endif {{{ makeSetValue('touchEvent', C_STRUCTS.EmscriptenTouchEvent.timestamp, 'e.timeStamp', 'double') }}}; HEAP8[touchEvent + {{{ C_STRUCTS.EmscriptenTouchEvent.ctrlKey }}}] = e.ctrlKey; HEAP8[touchEvent + {{{ C_STRUCTS.EmscriptenTouchEvent.shiftKey }}}] = e.shiftKey; @@ -1852,7 +1819,7 @@ var LibraryHTML5 = { {{{ makeSetValue('touchEvent', C_STRUCTS.EmscriptenTouchEvent.numTouches, 'numTouches', 'i32') }}}; #if PTHREADS - if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, touchEvent, userData); + if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, touchEvent, eventSize, userData); else #endif if ({{{ makeDynCall('iipp', 'callbackfunc') }}}(eventTypeId, touchEvent, userData)) e.preventDefault(); @@ -1927,18 +1894,15 @@ var LibraryHTML5 = { #if PTHREADS targetThread = JSEvents.getTargetThreadForEventCallback(targetThread); #endif - JSEvents.gamepadEvent ||= _malloc({{{ C_STRUCTS.EmscriptenGamepadEvent.__size__ }}}); + var eventSize = {{{ C_STRUCTS.EmscriptenGamepadEvent.__size__ }}}; + JSEvents.gamepadEvent ||= _malloc(eventSize); var gamepadEventHandlerFunc = (e = event) => { -#if PTHREADS - var gamepadEvent = targetThread ? _malloc({{{ C_STRUCTS.EmscriptenGamepadEvent.__size__ }}}) : JSEvents.gamepadEvent; -#else var gamepadEvent = JSEvents.gamepadEvent; -#endif fillGamepadEventData(gamepadEvent, e["gamepad"]); #if PTHREADS - if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, gamepadEvent, userData); + if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, gamepadEvent, eventSize, userData); else #endif if ({{{ makeDynCall('iipp', 'callbackfunc') }}}(eventTypeId, gamepadEvent, userData)) e.preventDefault(); @@ -2069,18 +2033,15 @@ var LibraryHTML5 = { #if PTHREADS targetThread = JSEvents.getTargetThreadForEventCallback(targetThread); #endif - JSEvents.batteryEvent ||= _malloc({{{ C_STRUCTS.EmscriptenBatteryEvent.__size__ }}}); + var eventSize = {{{ C_STRUCTS.EmscriptenBatteryEvent.__size__ }}}; + JSEvents.batteryEvent ||= _malloc(eventSize) var batteryEventHandlerFunc = (e = event) => { -#if PTHREADS - var batteryEvent = targetThread ? _malloc({{{ C_STRUCTS.EmscriptenBatteryEvent.__size__ }}}) : JSEvents.batteryEvent; -#else var batteryEvent = JSEvents.batteryEvent; -#endif fillBatteryEventData(batteryEvent, battery); #if PTHREADS - if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, batteryEvent, userData); + if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, batteryEvent, eventSize, userData); else #endif if ({{{ makeDynCall('iipp', 'callbackfunc') }}}(eventTypeId, batteryEvent, userData)) e.preventDefault(); diff --git a/system/lib/html5/callback.c b/system/lib/html5/callback.c index 23925e4ee5bc7..981a04f2013df 100644 --- a/system/lib/html5/callback.c +++ b/system/lib/html5/callback.c @@ -5,6 +5,7 @@ * found in the LICENSE file. */ #include +#include #include #include "emscripten_internal.h" @@ -14,8 +15,8 @@ typedef bool (*event_callback)(int event_type, void *event_data __attribute__((n typedef struct callback_args_t { event_callback callback; int event_type; - void *event_data; void *user_data; + uint8_t event_data[]; } callback_args_t; static void do_callback(void* arg) { @@ -28,13 +29,14 @@ void _emscripten_run_callback_on_thread(pthread_t t, event_callback f, int event_type, void* event_data, + size_t event_data_size, void* user_data) { em_proxying_queue* q = emscripten_proxy_get_system_queue(); - callback_args_t* arg = malloc(sizeof(callback_args_t)); + callback_args_t* arg = malloc(sizeof(callback_args_t) + event_data_size); arg->callback = f; arg->event_type = event_type; - arg->event_data = event_data; arg->user_data = user_data; + memcpy(arg->event_data, event_data, event_data_size); if (!emscripten_proxy_async(q, t, do_callback, arg)) { assert(false && "emscripten_proxy_async failed"); diff --git a/test/codesize/test_codesize_hello_dylink_all.json b/test/codesize/test_codesize_hello_dylink_all.json index 37009f94946f8..16afb2eccaf70 100644 --- a/test/codesize/test_codesize_hello_dylink_all.json +++ b/test/codesize/test_codesize_hello_dylink_all.json @@ -1,7 +1,7 @@ { "a.out.js": 245483, - "a.out.nodebug.wasm": 573907, - "total": 819390, + "a.out.nodebug.wasm": 573921, + "total": 819404, "sent": [ "IMG_Init", "IMG_Load", diff --git a/tools/emscripten.py b/tools/emscripten.py index 87ca13f4d1546..a94b2401dde96 100644 --- a/tools/emscripten.py +++ b/tools/emscripten.py @@ -1145,7 +1145,7 @@ def create_pointer_conversion_wrappers(metadata): 'emscripten_main_runtime_thread_id': 'p', '_emscripten_set_offscreencanvas_size_on_thread': '_pp__', 'fileno': '_p', - '_emscripten_run_callback_on_thread': '_pp_pp', + '_emscripten_run_callback_on_thread': '_pp_ppp', '_emscripten_find_dylib': 'ppppp', }