diff --git a/ChangeLog.md b/ChangeLog.md index 532b5d718f4fa..2724d26435f5a 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -17,6 +17,9 @@ See docs/process.md for how version tagging works. Current Trunk ------------- +- Stop including `malloc` and `free` by default. If you need access to them from + JS, you must export them manually using + `-s EXPORTED_FUNCTIONS=['_malloc', ..]`. - Stop running Binaryen optimizations in `-O1`. This makes `-O1` builds a little larger but they compile a lot faster, which makes more sense in a "compromise" build (in between `-O0` and higher optimization levels suitable for release diff --git a/emcc.py b/emcc.py index 19c555ff20a4f..64b2dd5b5e6f8 100755 --- a/emcc.py +++ b/emcc.py @@ -1405,12 +1405,6 @@ def check(input_file): if shared.Settings.EMBIND: forced_stdlibs.append('libembind') - if not shared.Settings.MINIMAL_RUNTIME and not shared.Settings.STANDALONE_WASM: - # The normal JS runtime depends on malloc and free so always keep them alive. - # MINIMAL_RUNTIME avoids this dependency as does STANDALONE_WASM mode (since it has no - # JS runtime at all). - shared.Settings.EXPORTED_FUNCTIONS += ['_malloc', '_free'] - shared.Settings.EXPORTED_FUNCTIONS += ['_stackSave', '_stackRestore', '_stackAlloc'] # We need to preserve the __data_end symbol so that wasm-emscripten-finalize can determine # where static data ends (and correspondingly where the stack begins). @@ -1539,7 +1533,7 @@ def check(input_file): if shared.Settings.USE_PTHREADS: # memalign is used to ensure allocated thread stacks are aligned. - shared.Settings.EXPORTED_FUNCTIONS += ['_memalign', '_malloc'] + shared.Settings.EXPORTED_FUNCTIONS += ['_memalign'] # dynCall is used to call pthread entry points in worker.js (as # metadce does not consider worker.js, which is external, we must @@ -1761,6 +1755,26 @@ def include_and_export(name): if sanitize and '-g4' in args: shared.Settings.LOAD_SOURCE_MAP = 1 + # various settings require malloc/free support from JS + if shared.Settings.RELOCATABLE or \ + shared.Settings.BUILD_AS_WORKER or \ + shared.Settings.USE_WEBGPU or \ + shared.Settings.USE_PTHREADS or \ + shared.Settings.OFFSCREENCANVAS_SUPPORT or \ + shared.Settings.LEGACY_GL_EMULATION or \ + shared.Settings.DISABLE_EXCEPTION_CATCHING != 1 or \ + shared.Settings.ASYNCIFY or \ + shared.Settings.ASMFS or \ + shared.Settings.DEMANGLE_SUPPORT or \ + shared.Settings.FORCE_FILESYSTEM or \ + shared.Settings.STB_IMAGE or \ + shared.Settings.EMBIND or \ + shared.Settings.FETCH or \ + shared.Settings.PROXY_POSIX_SOCKETS or \ + options.memory_profiler or \ + sanitize: + shared.Settings.EXPORTED_FUNCTIONS += ['_malloc', '_free'] + options.binaryen_passes += backend_binaryen_passes() if shared.Settings.WASM2JS and use_source_map(options): diff --git a/emscripten.py b/emscripten.py index 0e9667f33fb37..b3d69b489e6ed 100644 --- a/emscripten.py +++ b/emscripten.py @@ -249,10 +249,6 @@ def report_missing_symbols(all_implemented, pre): for requested in missing: if ('function ' + asstr(requested)) in pre: continue - # special-case malloc, EXPORTED by default for internal use, but we bake in a - # trivial allocator and warn at runtime if used in ASSERTIONS - if missing == '_malloc': - continue diagnostics.warning('undefined', 'undefined exported function: "%s"', requested) # Special hanlding for the `_main` symbol diff --git a/src/deps_info.json b/src/deps_info.json index 5d107f60bae7c..287e4b5f1ee7d 100644 --- a/src/deps_info.json +++ b/src/deps_info.json @@ -4,40 +4,50 @@ "getenv": ["malloc", "free"], "SDL_getenv": ["malloc", "free"], "dlerror": ["malloc", "free"], - "readdir": ["malloc"], - "ttyname": ["malloc"], - "calloc": ["malloc"], + "dladdr": ["malloc", "free"], + "readdir": ["malloc", "free"], + "ttyname": ["malloc", "free"], + "calloc": ["malloc", "free"], "realloc": ["malloc", "free"], - "getlogin": ["malloc"], - "tmpnam": ["malloc"], - "mmap": ["memalign", "memset"], - "realpath": ["malloc"], - "strerror": ["malloc"], - "__ctype_b_loc": ["malloc"], - "__ctype_tolower_loc": ["malloc"], - "__ctype_toupper_loc": ["malloc"], - "newlocale": ["malloc"], + "getlogin": ["malloc", "free"], + "tmpnam": ["malloc", "free"], + "mmap": ["memalign", "memset", "malloc", "free"], + "munmap": ["memalign", "memset", "malloc", "free"], + "realpath": ["malloc", "free"], + "strerror": ["malloc", "free"], + "__ctype_b_loc": ["malloc", "free"], + "__ctype_tolower_loc": ["malloc", "free"], + "__ctype_toupper_loc": ["malloc", "free"], + "newlocale": ["malloc", "free"], "freelocale": ["free"], - "nl_langinfo": ["malloc"], - "inet_ntoa": ["malloc"], + "nl_langinfo": ["malloc", "free"], + "inet_ntoa": ["malloc", "free"], "gethostbyname": ["malloc", "free", "htons", "ntohs", "memcpy"], "gethostbyname_r": ["malloc", "free", "htons", "ntohs", "memcpy"], - "getaddrinfo": ["malloc", "htonl", "htons", "ntohs"], + "getaddrinfo": ["malloc", "free", "htonl", "htons", "ntohs"], "getnameinfo": ["htons", "ntohs"], "getpeername": ["htons", "ntohs"], "_inet_ntop6_raw": ["ntohs"], "_read_sockaddr": ["ntohs"], "freeaddrinfo": ["free"], - "gai_strerror": ["malloc"], - "setprotoent": ["malloc"], + "gai_strerror": ["malloc", "free"], + "setprotoent": ["malloc", "free"], "emscripten_run_script_string": ["malloc", "free"], "emscripten_log": ["strlen"], "uuid_clear": ["memset"], "uuid_compare": ["memcmp", "memcpy", "memset"], "uuid_copy": ["memcpy"], "SDL_Init": ["malloc", "free", "memset", "memcpy"], + "SDL_PushEvent": ["malloc", "free"], + "SDL_OpenAudio": ["malloc", "free"], + "SDL_LockSurface": ["malloc", "free"], "SDL_GL_GetProcAddress": ["emscripten_GetProcAddress"], + "SDL_CreateRGBSurface": ["malloc", "free"], + "SDL_malloc": ["malloc", "free"], + "SDL_free": ["free"], + "emscripten_SDL_SetEventHandler": ["malloc", "free"], "Mix_LoadWAV_RW": ["fileno"], + "eglQueryString": ["malloc", "free"], "eglGetProcAddress": ["emscripten_GetProcAddress"], "glfwGetProcAddress": ["emscripten_GetProcAddress"], "emscripten_GetProcAddress": ["strstr"], @@ -46,6 +56,9 @@ "emscripten_GetAlcProcAddress": ["strcmp"], "emscripten_GetAlProcAddress": ["strcmp"], "emscripten_get_preloaded_image_data_from_FILE": ["fileno"], + "alGetString": ["malloc", "free"], + "alcGetString": ["malloc", "free"], + "emscripten_alcGetStringiSOFT": ["malloc", "free"], "__gxx_personality_v0": ["_ZSt18uncaught_exceptionv", "__cxa_find_matching_catch"], "__cxa_find_matching_catch": ["__cxa_is_pointer_type", "__cxa_can_catch"], "__cxa_find_matching_catch_0": ["__cxa_is_pointer_type", "__cxa_can_catch"], @@ -60,12 +73,14 @@ "__cxa_find_matching_catch_9": ["__cxa_is_pointer_type", "__cxa_can_catch"], "__cxa_begin_catch": ["_ZSt18uncaught_exceptionv", "setThrew"], "__cxa_end_catch": ["free"], - "__cxa_allocate_exception": ["malloc", "setThrew"], + "__cxa_allocate_exception": ["malloc", "free", "setThrew"], "__cxa_free_exception": ["free"], "__cxa_throw": ["setThrew"], "formatString": ["strlen"], + "glfwInit": ["malloc", "free"], "glfwSleep": ["sleep"], "glBegin": ["malloc", "free"], + "glewInit": ["malloc", "free"], "bind": ["htonl", "htons", "ntohs"], "connect": ["htonl", "htons", "ntohs"], "socket": ["htonl", "htons", "ntohs"], @@ -73,23 +88,28 @@ "sleep": ["usleep"], "recv": ["htons", "ntohs"], "send": ["htons", "ntohs"], - "ctime": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc"], - "ctime_r": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc"], - "localtime": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc"], - "localtime_r": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc"], - "mktime": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc"], - "timegm": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc"], - "tzset": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc"], + "ctime": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc", "free"], + "ctime_r": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc", "free"], + "gmtime": ["malloc", "free"], + "gmtime_r": ["malloc", "free"], + "localtime": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc", "free"], + "localtime_r": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc", "free"], + "mktime": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc", "free"], + "timegm": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc", "free"], + "tzset": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc", "free"], "times": ["memset"], + "emscripten_pc_get_function": ["malloc", "free"], + "emscripten_pc_get_file": ["malloc", "free"], "emscripten_set_canvas_element_size_calling_thread": ["_emscripten_call_on_thread"], - "emscripten_set_offscreencanvas_size_on_target_thread": ["_emscripten_call_on_thread"], - "emscripten_websocket_new": ["malloc"], - "emscripten_wget_data": ["malloc"], + "emscripten_set_offscreencanvas_size_on_target_thread": ["_emscripten_call_on_thread", "malloc", "free"], + "emscripten_set_offscreencanvas_size_on_target_thread_js": ["malloc", "free"], + "emscripten_websocket_new": ["malloc", "free"], + "emscripten_wget_data": ["malloc", "free"], "emscripten_webgl_destroy_context": ["emscripten_webgl_make_context_current", "emscripten_webgl_get_current_context"], "emscripten_idb_async_load": ["malloc", "free"], "emscripten_idb_load": ["malloc", "free"], "wgpuDeviceCreateBuffer": ["malloc", "free"], - "stringToNewUTF8": ["malloc"], + "stringToNewUTF8": ["malloc", "free"], "_embind_register_std_string": ["malloc", "free"], "_embind_register_std_wstring": ["malloc", "free"], "pthread_create": ["malloc", "free", "emscripten_main_thread_process_queued_calls"], @@ -103,5 +123,64 @@ "setjmp": ["setThrew", "realloc", "testSetjmp", "saveSetjmp"], "longjmp": ["setThrew", "realloc", "testSetjmp", "saveSetjmp"], "siglongjmp": ["setThrew", "realloc", "testSetjmp", "saveSetjmp"], - "emscripten_longjmp_jmpbuf": ["setThrew", "realloc", "testSetjmp", "saveSetjmp"] + "emscripten_longjmp_jmpbuf": ["setThrew", "realloc", "testSetjmp", "saveSetjmp"], + "emscripten_websocket_new": ["malloc", "free"], + "emscripten_websocket_set_onmessage_callback_on_thread": ["malloc", "free"], + "emscripten_websocket_set_onclose_callback_on_thread": ["malloc", "free"], + "emscripten_websocket_set_onerror_callback_on_thread": ["malloc", "free"], + "emscripten_websocket_set_onopen_callback_on_thread": ["malloc", "free"], + "emscripten_init_websocket_to_posix_socket_bridge": ["malloc", "free"], + "emscripten_set_keypress_callback_on_thread": ["malloc", "free"], + "emscripten_set_keyup_callback_on_thread": ["malloc", "free"], + "emscripten_set_keydown_callback_on_thread": ["malloc", "free"], + "emscripten_set_click_callback_on_thread": ["malloc", "free"], + "emscripten_set_mousedown_callback_on_thread": ["malloc", "free"], + "emscripten_set_mouseup_callback_on_thread": ["malloc", "free"], + "emscripten_set_dblclick_callback_on_thread": ["malloc", "free"], + "emscripten_set_mousemove_callback_on_thread": ["malloc", "free"], + "emscripten_set_mousemove_callback_on_thread": ["malloc", "free"], + "emscripten_set_mouseenter_callback_on_thread": ["malloc", "free"], + "emscripten_set_mouseleave_callback_on_thread": ["malloc", "free"], + "emscripten_set_mouseover_callback_on_thread": ["malloc", "free"], + "emscripten_set_mouseout_callback_on_thread": ["malloc", "free"], + "emscripten_set_wheel_callback_on_thread": ["malloc", "free"], + "emscripten_set_resize_callback_on_thread": ["malloc", "free"], + "emscripten_set_scroll_callback_on_thread": ["malloc", "free"], + "emscripten_set_blur_callback_on_thread": ["malloc", "free"], + "emscripten_set_focus_callback_on_thread": ["malloc", "free"], + "emscripten_set_focusin_callback_on_thread": ["malloc", "free"], + "emscripten_set_focusout_callback_on_thread": ["malloc", "free"], + "emscripten_set_deviceorientation_callback_on_thread": ["malloc", "free"], + "emscripten_set_orientationchange_callback_on_thread": ["malloc", "free"], + "emscripten_set_fullscreenchange_callback_on_thread": ["malloc", "free"], + "emscripten_set_pointerlockchange_callback_on_thread": ["malloc", "free"], + "emscripten_set_pointerlockerror_callback_on_thread": ["malloc", "free"], + "emscripten_set_visibilitychange_callback_on_thread": ["malloc", "free"], + "emscripten_set_touchstart_callback_on_thread": ["malloc", "free"], + "emscripten_set_touchend_callback_on_thread": ["malloc", "free"], + "emscripten_set_touchmove_callback_on_thread": ["malloc", "free"], + "emscripten_set_touchcancel_callback_on_thread": ["malloc", "free"], + "emscripten_set_gamepadconnected_callback_on_thread": ["malloc", "free"], + "emscripten_set_gamepaddisconnected_callback_on_thread": ["malloc", "free"], + "emscripten_set_beforeunload_callback_on_thread": ["malloc", "free"], + "emscripten_set_batterychargingchange_callback_on_thread": ["malloc", "free"], + "emscripten_set_batterylevelchange_callback_on_thread": ["malloc", "free"], + "emscripten_set_devicemotion_callback_on_thread": ["malloc", "free"], + "emscripten_run_preload_plugins_data": ["malloc", "free"], + "emscripten_async_wget_data": ["malloc", "free"], + "emscripten_async_wget2_data": ["malloc", "free"], + "emscripten_get_window_title": ["malloc", "free"], + "emscripten_get_compiler_setting": ["malloc", "free"], + "emscripten_create_worker": ["malloc", "free"], + "emscripten_get_preloaded_image_data": ["malloc", "free"], + "emscripten_webgl_get_supported_extensions": ["malloc", "free"], + "emscripten_webgl_get_program_info_log_utf8": ["malloc", "free"], + "emscripten_webgl_get_shader_info_log_utf8": ["malloc", "free"], + "emscripten_webgl_get_shader_source_utf8": ["malloc", "free"], + "emscripten_webgl_get_parameter_utf8": ["malloc", "free"], + "emscripten_webgl_create_context": ["malloc", "free"], + "glMapBufferRange": ["malloc", "free"], + "glGetString": ["malloc", "free"], + "glGetStringi": ["malloc", "free"], + "syslog": ["malloc", "free"] } diff --git a/src/library_fs.js b/src/library_fs.js index 7b78bf96b7b20..528bbb3a2c1d9 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -2026,7 +2026,7 @@ FS.staticInit();` + // page-aligned size, and clears the padding. mmapAlloc: function(size) { var alignedSize = alignMemory(size, {{{ POSIX_PAGE_SIZE }}}); - var ptr = _malloc(alignedSize); + var ptr = {{{ makeMalloc('mmapAlloc', 'alignedSize') }}}; while (size < alignedSize) HEAP8[ptr + size++] = 0; return ptr; } diff --git a/src/library_sdl.js b/src/library_sdl.js index d312e5394c73b..f67c6ee0730ab 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1846,10 +1846,14 @@ var LibrarySDL = { SDL_SetError: function() {}, SDL_malloc__sig: 'ii', - SDL_malloc: 'malloc', + SDL_malloc: function(size) { + return _malloc(size); + }, SDL_free__sig: 'vi', - SDL_free: 'free', + SDL_free: function(ptr) { + _free(ptr); + }, SDL_CreateRGBSurface__proxy: 'sync', SDL_CreateRGBSurface__sig: 'iiiiiiiii', @@ -2653,7 +2657,7 @@ var LibrarySDL = { SDL.audio.paused = pauseOn; }, - SDL_CloseAudio__deps: ['SDL_PauseAudio', 'free'], + SDL_CloseAudio__deps: ['SDL_PauseAudio'], SDL_CloseAudio__proxy: 'sync', SDL_CloseAudio__sig: 'v', SDL_CloseAudio: function() { diff --git a/src/parseTools.js b/src/parseTools.js index f7bf61d6ac23f..406e301318353 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1707,3 +1707,18 @@ function addReadyPromiseAssertions(promise) { `; }).join('\n'); } + +function makeMalloc(source, param) { + if ('_malloc' in IMPLEMENTED_FUNCTIONS) { + return '_malloc(' + param + ')'; + } + // It should be impossible to call some functions without malloc being + // included, unless we have a deps_info.json bug. To let closure not error + // on `_malloc` not being present, they don't call malloc and instead abort + // with an error at runtime. + // TODO: A more comprehensive deps system could catch this at compile time. + if (!ASSERTIONS) { + return "abort();"; + } + return `abort('malloc was not included, but is needed in ${source}. Adding "_malloc" to EXPORTED_FUNCTIONS should fix that. This may be a bug in the compiler, please file an issue.');` +} diff --git a/src/preamble.js b/src/preamble.js index 559f466258827..8fa84dd7d44a2 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -187,6 +187,22 @@ function cwrap(ident, returnType, argTypes, opts) { } } +#if ASSERTIONS +// We used to include malloc/free by default in the past. Show a helpful error in +// builds with assertions. +#if !('_malloc' in IMPLEMENTED_FUNCTIONS) +function _malloc() { + abort("malloc() called but not included in the build - add '_malloc' to EXPORTED_FUNCTIONS"); +} +#endif // malloc +#if !('_free' in IMPLEMENTED_FUNCTIONS) +function _free() { + // Show a helpful error since we used to include free by default in the past. + abort("free() called but not included in the build - add '_free' to EXPORTED_FUNCTIONS"); +} +#endif // free +#endif // ASSERTIONS + var ALLOC_NORMAL = 0; // Tries to use _malloc() var ALLOC_STACK = 1; // Lives for the duration of the current function call var ALLOC_NONE = 2; // Do not allocate @@ -221,7 +237,7 @@ function allocate(slab, types, allocator, ptr) { if (allocator == ALLOC_NONE) { ret = ptr; } else { - ret = [_malloc, + ret = [{{{ ('_malloc' in IMPLEMENTED_FUNCTIONS) ? '_malloc' : 'null' }}}, #if DECLARE_ASM_MODULE_EXPORTS stackAlloc, #else diff --git a/src/runtime_strings_extra.js b/src/runtime_strings_extra.js index 4e29c5b40043d..dd2e86d75c464 100644 --- a/src/runtime_strings_extra.js +++ b/src/runtime_strings_extra.js @@ -209,7 +209,7 @@ function lengthBytesUTF32(str) { // It is the responsibility of the caller to free() that memory. function allocateUTF8(str) { var size = lengthBytesUTF8(str) + 1; - var ret = _malloc(size); + var ret = {{{ makeMalloc('allocateUTF8', 'size') }}}; if (ret) stringToUTF8Array(str, HEAP8, ret, size); return ret; } diff --git a/tests/code_size/hello_webgl2_wasm.json b/tests/code_size/hello_webgl2_wasm.json index fe03b4496af53..087157885afbb 100644 --- a/tests/code_size/hello_webgl2_wasm.json +++ b/tests/code_size/hello_webgl2_wasm.json @@ -4,7 +4,7 @@ "a.js": 5035, "a.js.gz": 2395, "a.wasm": 10910, - "a.wasm.gz": 6930, + "a.wasm.gz": 6928, "total": 16508, - "total_gz": 9702 + "total_gz": 9700 } diff --git a/tests/code_size/hello_webgl_wasm.json b/tests/code_size/hello_webgl_wasm.json index 5976a06cd0dc1..aa005f3ab04a0 100644 --- a/tests/code_size/hello_webgl_wasm.json +++ b/tests/code_size/hello_webgl_wasm.json @@ -4,7 +4,7 @@ "a.js": 4519, "a.js.gz": 2219, "a.wasm": 10910, - "a.wasm.gz": 6930, + "a.wasm.gz": 6928, "total": 15992, - "total_gz": 9526 + "total_gz": 9524 } diff --git a/tests/code_size/hello_webgl_wasm2js.json b/tests/code_size/hello_webgl_wasm2js.json index 8a79269c7b842..a07ba6a9eaec5 100644 --- a/tests/code_size/hello_webgl_wasm2js.json +++ b/tests/code_size/hello_webgl_wasm2js.json @@ -2,9 +2,9 @@ "a.html": 588, "a.html.gz": 386, "a.js": 21617, - "a.js.gz": 8296, + "a.js.gz": 8297, "a.mem": 3168, "a.mem.gz": 2711, "total": 25373, - "total_gz": 11393 + "total_gz": 11394 } diff --git a/tests/code_size/random_printf_wasm.json b/tests/code_size/random_printf_wasm.json index 20823d8529a54..6d4f375f3f8f5 100644 --- a/tests/code_size/random_printf_wasm.json +++ b/tests/code_size/random_printf_wasm.json @@ -1,6 +1,6 @@ { "a.html": 13702, "a.html.gz": 7337, - "total": 13706, + "total": 13702, "total_gz": 7337 } diff --git a/tests/code_size/random_printf_wasm2js.json b/tests/code_size/random_printf_wasm2js.json index 4c44bfc5d0468..71afae2edba90 100644 --- a/tests/code_size/random_printf_wasm2js.json +++ b/tests/code_size/random_printf_wasm2js.json @@ -1,6 +1,6 @@ { "a.html": 19370, "a.html.gz": 8062, - "total": 19378, + "total": 19370, "total_gz": 8062 } diff --git a/tests/other/metadce/hello_libcxx_O2.exports b/tests/other/metadce/hello_libcxx_O2.exports index 8a8bcc4e0e2cf..d72d2f36753ac 100644 --- a/tests/other/metadce/hello_libcxx_O2.exports +++ b/tests/other/metadce/hello_libcxx_O2.exports @@ -7,9 +7,7 @@ dynCall_iiiiij dynCall_iiiiijj dynCall_jiji dynCall_viijii -free main -malloc stackAlloc stackRestore stackSave diff --git a/tests/other/metadce/hello_world.exports b/tests/other/metadce/hello_world.exports index 22878a4a6e84d..37277d1a6c9cd 100644 --- a/tests/other/metadce/hello_world.exports +++ b/tests/other/metadce/hello_world.exports @@ -4,9 +4,7 @@ __growWasmMemory __wasm_call_ctors dynCall_jiji fflush -free main -malloc stackAlloc stackRestore stackSave diff --git a/tests/other/metadce/hello_world.funcs b/tests/other/metadce/hello_world.funcs index 39378bd6badb8..9dbe27b3f37a1 100644 --- a/tests/other/metadce/hello_world.funcs +++ b/tests/other/metadce/hello_world.funcs @@ -21,8 +21,6 @@ $__unlockfile $__vfprintf_internal $__wasi_syscall_ret $__wasm_call_ctors -$dlfree -$dlmalloc $dynCall_jiji $fflush $fmt_fp @@ -44,7 +42,6 @@ $pop_arg_long_double $printf $printf_core $pthread_self -$sbrk $stackAlloc $stackRestore $stackSave diff --git a/tests/other/metadce/hello_world.imports b/tests/other/metadce/hello_world.imports index c915795b67695..5b3c1cb9b90e1 100644 --- a/tests/other/metadce/hello_world.imports +++ b/tests/other/metadce/hello_world.imports @@ -1,6 +1,5 @@ __indirect_function_table emscripten_memcpy_big -emscripten_resize_heap fd_write memory setTempRet0 diff --git a/tests/other/metadce/hello_world.sent b/tests/other/metadce/hello_world.sent index c915795b67695..5b3c1cb9b90e1 100644 --- a/tests/other/metadce/hello_world.sent +++ b/tests/other/metadce/hello_world.sent @@ -1,6 +1,5 @@ __indirect_function_table emscripten_memcpy_big -emscripten_resize_heap fd_write memory setTempRet0 diff --git a/tests/other/metadce/hello_world_O1.exports b/tests/other/metadce/hello_world_O1.exports index 9e43d3335f546..4c73b545677e5 100644 --- a/tests/other/metadce/hello_world_O1.exports +++ b/tests/other/metadce/hello_world_O1.exports @@ -3,9 +3,7 @@ __errno_location __growWasmMemory __wasm_call_ctors dynCall_jiji -free main -malloc stackAlloc stackRestore stackSave diff --git a/tests/other/metadce/hello_world_O1.funcs b/tests/other/metadce/hello_world_O1.funcs index 2a013ebe1f2be..d7cbe3fd3a46f 100644 --- a/tests/other/metadce/hello_world_O1.funcs +++ b/tests/other/metadce/hello_world_O1.funcs @@ -11,8 +11,6 @@ $__towrite $__unlockfile $__wasi_syscall_ret $__wasm_call_ctors -$dlfree -$dlmalloc $dynCall_jiji $fputs $fwrite @@ -20,7 +18,6 @@ $legalstub$dynCall_jiji $main $memcpy $puts -$sbrk $stackAlloc $stackRestore $stackSave diff --git a/tests/other/metadce/hello_world_O1.imports b/tests/other/metadce/hello_world_O1.imports index c915795b67695..5b3c1cb9b90e1 100644 --- a/tests/other/metadce/hello_world_O1.imports +++ b/tests/other/metadce/hello_world_O1.imports @@ -1,6 +1,5 @@ __indirect_function_table emscripten_memcpy_big -emscripten_resize_heap fd_write memory setTempRet0 diff --git a/tests/other/metadce/hello_world_O1.sent b/tests/other/metadce/hello_world_O1.sent index c915795b67695..5b3c1cb9b90e1 100644 --- a/tests/other/metadce/hello_world_O1.sent +++ b/tests/other/metadce/hello_world_O1.sent @@ -1,6 +1,5 @@ __indirect_function_table emscripten_memcpy_big -emscripten_resize_heap fd_write memory setTempRet0 diff --git a/tests/other/metadce/hello_world_O2.exports b/tests/other/metadce/hello_world_O2.exports index 9e43d3335f546..4c73b545677e5 100644 --- a/tests/other/metadce/hello_world_O2.exports +++ b/tests/other/metadce/hello_world_O2.exports @@ -3,9 +3,7 @@ __errno_location __growWasmMemory __wasm_call_ctors dynCall_jiji -free main -malloc stackAlloc stackRestore stackSave diff --git a/tests/other/metadce/hello_world_O2.funcs b/tests/other/metadce/hello_world_O2.funcs index 7c63c15bfaef8..376dbb78ebecb 100644 --- a/tests/other/metadce/hello_world_O2.funcs +++ b/tests/other/metadce/hello_world_O2.funcs @@ -8,14 +8,11 @@ $__stdio_write $__towrite $__wasi_syscall_ret $__wasm_call_ctors -$dlfree -$dlmalloc $fwrite $legalstub$dynCall_jiji $main $memcpy $puts -$sbrk $stackAlloc $stackRestore $stackSave diff --git a/tests/other/metadce/hello_world_O2.imports b/tests/other/metadce/hello_world_O2.imports index c915795b67695..5b3c1cb9b90e1 100644 --- a/tests/other/metadce/hello_world_O2.imports +++ b/tests/other/metadce/hello_world_O2.imports @@ -1,6 +1,5 @@ __indirect_function_table emscripten_memcpy_big -emscripten_resize_heap fd_write memory setTempRet0 diff --git a/tests/other/metadce/hello_world_O2.sent b/tests/other/metadce/hello_world_O2.sent index c915795b67695..5b3c1cb9b90e1 100644 --- a/tests/other/metadce/hello_world_O2.sent +++ b/tests/other/metadce/hello_world_O2.sent @@ -1,6 +1,5 @@ __indirect_function_table emscripten_memcpy_big -emscripten_resize_heap fd_write memory setTempRet0 diff --git a/tests/other/metadce/minimal.exports b/tests/other/metadce/minimal.exports index bdf6e35eb01ba..5c652c3248342 100644 --- a/tests/other/metadce/minimal.exports +++ b/tests/other/metadce/minimal.exports @@ -4,9 +4,7 @@ __growWasmMemory __wasm_call_ctors add fflush -free global_val -malloc stackAlloc stackRestore stackSave diff --git a/tests/other/metadce/minimal.funcs b/tests/other/metadce/minimal.funcs index 899eb986a422c..3c769b7929dba 100644 --- a/tests/other/metadce/minimal.funcs +++ b/tests/other/metadce/minimal.funcs @@ -9,10 +9,7 @@ $__unlock $__unlockfile $__wasm_call_ctors $add -$dlfree -$dlmalloc $fflush -$sbrk $stackAlloc $stackRestore $stackSave diff --git a/tests/other/metadce/minimal.imports b/tests/other/metadce/minimal.imports index c5eccccf1608b..65a6a2f0060ad 100644 --- a/tests/other/metadce/minimal.imports +++ b/tests/other/metadce/minimal.imports @@ -1,3 +1,2 @@ __indirect_function_table -emscripten_resize_heap memory diff --git a/tests/other/metadce/minimal.sent b/tests/other/metadce/minimal.sent index c5eccccf1608b..65a6a2f0060ad 100644 --- a/tests/other/metadce/minimal.sent +++ b/tests/other/metadce/minimal.sent @@ -1,3 +1,2 @@ __indirect_function_table -emscripten_resize_heap memory diff --git a/tests/other/metadce/minimal_O1.exports b/tests/other/metadce/minimal_O1.exports index ab7f06c9ef915..e97876450cd5e 100644 --- a/tests/other/metadce/minimal_O1.exports +++ b/tests/other/metadce/minimal_O1.exports @@ -3,9 +3,7 @@ __errno_location __growWasmMemory __wasm_call_ctors add -free global_val -malloc stackAlloc stackRestore stackSave diff --git a/tests/other/metadce/minimal_O1.funcs b/tests/other/metadce/minimal_O1.funcs index 08eeaa3e673d0..3fbfc34f72a02 100644 --- a/tests/other/metadce/minimal_O1.funcs +++ b/tests/other/metadce/minimal_O1.funcs @@ -2,9 +2,6 @@ $__errno_location $__growWasmMemory $__wasm_call_ctors $add -$dlfree -$dlmalloc -$sbrk $stackAlloc $stackRestore $stackSave diff --git a/tests/other/metadce/minimal_O1.imports b/tests/other/metadce/minimal_O1.imports index c5eccccf1608b..65a6a2f0060ad 100644 --- a/tests/other/metadce/minimal_O1.imports +++ b/tests/other/metadce/minimal_O1.imports @@ -1,3 +1,2 @@ __indirect_function_table -emscripten_resize_heap memory diff --git a/tests/other/metadce/minimal_O1.sent b/tests/other/metadce/minimal_O1.sent index c5eccccf1608b..65a6a2f0060ad 100644 --- a/tests/other/metadce/minimal_O1.sent +++ b/tests/other/metadce/minimal_O1.sent @@ -1,3 +1,2 @@ __indirect_function_table -emscripten_resize_heap memory diff --git a/tests/other/metadce/minimal_O2.exports b/tests/other/metadce/minimal_O2.exports index ab7f06c9ef915..e97876450cd5e 100644 --- a/tests/other/metadce/minimal_O2.exports +++ b/tests/other/metadce/minimal_O2.exports @@ -3,9 +3,7 @@ __errno_location __growWasmMemory __wasm_call_ctors add -free global_val -malloc stackAlloc stackRestore stackSave diff --git a/tests/other/metadce/minimal_O2.funcs b/tests/other/metadce/minimal_O2.funcs index 08eeaa3e673d0..3fbfc34f72a02 100644 --- a/tests/other/metadce/minimal_O2.funcs +++ b/tests/other/metadce/minimal_O2.funcs @@ -2,9 +2,6 @@ $__errno_location $__growWasmMemory $__wasm_call_ctors $add -$dlfree -$dlmalloc -$sbrk $stackAlloc $stackRestore $stackSave diff --git a/tests/other/metadce/minimal_O2.imports b/tests/other/metadce/minimal_O2.imports index fb9ffcb5c570c..2142c3ad3ce3e 100644 --- a/tests/other/metadce/minimal_O2.imports +++ b/tests/other/metadce/minimal_O2.imports @@ -1,2 +1 @@ -emscripten_resize_heap memory diff --git a/tests/other/metadce/minimal_O2.sent b/tests/other/metadce/minimal_O2.sent index c5eccccf1608b..65a6a2f0060ad 100644 --- a/tests/other/metadce/minimal_O2.sent +++ b/tests/other/metadce/minimal_O2.sent @@ -1,3 +1,2 @@ __indirect_function_table -emscripten_resize_heap memory diff --git a/tests/test_browser.py b/tests/test_browser.py index 72e74a2cfb8c4..39dda6c8807e6 100644 --- a/tests/test_browser.py +++ b/tests/test_browser.py @@ -3874,7 +3874,7 @@ def test_pthread_call_async(self): def test_pthread_call_sync_on_main_thread(self): self.btest(path_from_root('tests', 'pthread', 'call_sync_on_main_thread.c'), expected='1', args=['-O3', '-s', 'USE_PTHREADS=1', '-s', 'PROXY_TO_PTHREAD=1', '-DPROXY_TO_PTHREAD=1', '--js-library', path_from_root('tests', 'pthread', 'call_sync_on_main_thread.js')]) self.btest(path_from_root('tests', 'pthread', 'call_sync_on_main_thread.c'), expected='1', args=['-O3', '-s', 'USE_PTHREADS=1', '-DPROXY_TO_PTHREAD=0', '--js-library', path_from_root('tests', 'pthread', 'call_sync_on_main_thread.js')]) - self.btest(path_from_root('tests', 'pthread', 'call_sync_on_main_thread.c'), expected='1', args=['-Oz', '-DPROXY_TO_PTHREAD=0', '--js-library', path_from_root('tests', 'pthread', 'call_sync_on_main_thread.js')]) + self.btest(path_from_root('tests', 'pthread', 'call_sync_on_main_thread.c'), expected='1', args=['-Oz', '-DPROXY_TO_PTHREAD=0', '--js-library', path_from_root('tests', 'pthread', 'call_sync_on_main_thread.js'), '-s', 'EXPORTED_FUNCTIONS=[_main,_malloc]']) # Test that it is possible to asynchronously call a JavaScript function on the main thread. @requires_threads diff --git a/tests/test_core.py b/tests/test_core.py index a1fc1f7d200c5..bdaf5aa2e5ea5 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -6974,7 +6974,7 @@ def test_webidl(self, mode, allow_memory_growth): # Export things on "TheModule". This matches the typical use pattern of the bound library # being used as Box2D.* or Ammo.*, and we cannot rely on "Module" being always present (closure may remove it). - self.emcc_args += ['-s', 'EXPORTED_FUNCTIONS=["_malloc"]', '--post-js', 'glue.js'] + self.emcc_args += ['-s', 'EXPORTED_FUNCTIONS=["_malloc","_free"]', '--post-js', 'glue.js'] if allow_memory_growth: self.emcc_args += ['-s', 'ALLOW_MEMORY_GROWTH', '-Wno-almost-asm'] diff --git a/tests/test_other.py b/tests/test_other.py index f970cb4d90afc..f845950b0ee22 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -2398,7 +2398,7 @@ def test_module_exports_with_closure(self): self.run_process([EMCC, path_from_root('tests', 'Module-exports', 'test.c'), '-o', 'test.js', '-O2', '--closure', '0', '--pre-js', path_from_root('tests', 'Module-exports', 'setup.js'), - '-s', 'EXPORTED_FUNCTIONS=["_bufferTest"]', + '-s', 'EXPORTED_FUNCTIONS=["_bufferTest","_malloc","_free"]', '-s', 'EXTRA_EXPORTED_RUNTIME_METHODS=["ccall", "cwrap"]', '-s', 'WASM_ASYNC_COMPILATION=0']) @@ -2423,7 +2423,7 @@ def test_module_exports_with_closure(self): self.run_process([EMCC, path_from_root('tests', 'Module-exports', 'test.c'), '-o', 'test.js', '-O2', '--closure', '1', '--pre-js', path_from_root('tests', 'Module-exports', 'setup.js'), - '-s', 'EXPORTED_FUNCTIONS=["_bufferTest"]', + '-s', 'EXPORTED_FUNCTIONS=["_bufferTest","_malloc","_free"]', '-s', 'EXTRA_EXPORTED_RUNTIME_METHODS=["ccall", "cwrap"]', '-s', 'WASM_ASYNC_COMPILATION=0']) @@ -4783,24 +4783,6 @@ def test_js_main(self): self.assertContained('compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]', self.run_js('a.out.js', assert_returncode=NON_ZERO)) - def test_js_malloc(self): - create_test_file('src.cpp', r''' -#include -#include - -int main() { - EM_ASM({ - for (var i = 0; i < 1000; i++) { - var ptr = Module._malloc(1024 * 1024); // only done in JS, but still must not leak - Module._free(ptr); - } - }); - printf("ok.\n"); -} - ''') - self.run_process([EMCC, 'src.cpp']) - self.assertContained('ok.', self.run_js('a.out.js', args=['C'])) - def test_locale_wrong(self): create_test_file('src.cpp', r''' #include @@ -6738,7 +6720,7 @@ def test_binaryen_names(self): print(args, expect_names) try_delete('a.out.js') # we use dlmalloc here, as emmalloc has a bunch of asserts that contain the text "malloc" in them, which makes counting harder - self.run_process([EMCC, path_from_root('tests', 'hello_world.cpp')] + args + ['-s', 'MALLOC="dlmalloc"']) + self.run_process([EMCC, path_from_root('tests', 'hello_world.cpp')] + args + ['-s', 'MALLOC="dlmalloc"', '-s', 'EXPORTED_FUNCTIONS=[_main,_malloc]']) code = open('a.out.wasm', 'rb').read() if expect_names: # name section adds the name of malloc (there is also another one for the export) @@ -6989,9 +6971,9 @@ def strip_numeric_suffixes(funcname): self.assertFileContents(filename, data) @parameterized({ - 'O0': ([], [], ['waka'], 9766), # noqa - 'O1': (['-O1'], [], ['waka'], 9093), # noqa - 'O2': (['-O2'], [], ['waka'], 7871), # noqa + 'O0': ([], [], ['waka'], 977), # noqa + 'O1': (['-O1'], [], ['waka'], 467), # noqa + 'O2': (['-O2'], [], ['waka'], 384), # noqa # in -O3, -Os and -Oz we metadce, and they shrink it down to the minimal output we want 'O3': (['-O3'], [], [], 85), # noqa 'Os': (['-Os'], [], [], 85), # noqa @@ -7016,9 +6998,9 @@ def test_metadce_cxx(self, *args): self.run_metadce_test('hello_libcxx.cpp', *args, check_funcs=False) @parameterized({ - 'O0': ([], [], ['waka'], 22849), # noqa - 'O1': (['-O1'], [], ['waka'], 12578), # noqa - 'O2': (['-O2'], [], ['waka'], 10256), # noqa + 'O0': ([], [], ['waka'], 13768), # noqa + 'O1': (['-O1'], [], ['waka'], 3954), # noqa + 'O2': (['-O2'], [], ['waka'], 2511), # noqa 'O3': (['-O3'], [], [], 1999), # noqa; in -O3, -Os and -Oz we metadce 'Os': (['-Os'], [], [], 2010), # noqa 'Oz': (['-Oz'], [], [], 2004), # noqa @@ -9680,5 +9662,48 @@ def test_standalone_export_main(self): # We should consider making this a warning since the `_main` export is redundant. self.run_process([EMCC, '-sEXPORTED_FUNCTIONS=[_main]', '-sSTANDALONE_WASM', '-c', path_from_root('tests', 'core', 'test_hello_world.c')]) + def test_missing_malloc_export(self): + # we used to include malloc by default. show a clear error in builds with + # ASSERTIONS to help with any confusion when the user calls malloc/free + # directly + create_test_file('unincluded_malloc.c', r''' + #include + int main() { + EM_ASM({ + try { + _malloc(1); + } catch(e) { + console.log('exception:', e); + } + try { + _free(); + } catch(e) { + console.log('exception:', e); + } + }); + } + ''') + self.do_runf('unincluded_malloc.c', ( + "malloc() called but not included in the build - add '_malloc' to EXPORTED_FUNCTIONS", + "free() called but not included in the build - add '_free' to EXPORTED_FUNCTIONS")) + + def test_missing_malloc_export_indirect(self): + # we used to include malloc by default. show a clear error in builds with + # ASSERTIONS to help with any confusion when the user calls a JS API that + # requires malloc + create_test_file('unincluded_malloc.c', r''' + #include + int main() { + EM_ASM({ + try { + allocateUTF8("foo"); + } catch(e) { + console.log('exception:', e); + } + }); + } + ''') + self.do_runf('unincluded_malloc.c', 'malloc was not included, but is needed in allocateUTF8. Adding "_malloc" to EXPORTED_FUNCTIONS should fix that. This may be a bug in the compiler, please file an issue.') + def test_getrusage(self): self.do_runf(path_from_root('tests', 'other', 'test_getrusage.c'))