From abef0b76316ca88479160d8a5a9b1ffe7dd0f435 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Wed, 29 Mar 2023 10:08:19 -0700 Subject: [PATCH] Move runtime_strings.js code into library_strings.js --- ChangeLog.md | 13 + src/embind/embind.js | 3 +- src/jsifier.js | 7 +- src/library.js | 15 +- src/library_dylink.js | 1 + src/library_fetch.js | 3 + src/library_fs.js | 5 +- src/library_html5.js | 9 +- src/library_legacy.js | 3 +- src/library_strings.js | 246 ++++++++++++++++++ src/library_syscall.js | 3 + src/library_uuid.js | 1 + src/library_wasi.js | 2 +- src/library_wasmfs.js | 1 + src/library_webgl.js | 2 + src/library_websocket.js | 8 +- src/modules.js | 5 - src/preamble.js | 2 - src/preamble_minimal.js | 2 - src/runtime_strings.js | 240 ----------------- test/code_size/hello_webgl2_wasm2js.json | 8 +- test/code_size/hello_webgl_wasm2js.json | 8 +- test/code_size/hello_world_wasm.js | 10 +- test/code_size/hello_world_wasm2js.js | 12 +- test/code_size/hello_world_wasm2js.json | 4 +- test/code_size/random_printf_wasm.json | 4 +- test/code_size/random_printf_wasm2js.json | 4 +- test/core/test_em_js.cpp | 2 + .../metadce/test_metadce_cxx_ctors1.jssize | 2 +- .../metadce/test_metadce_cxx_ctors2.jssize | 2 +- .../metadce/test_metadce_cxx_except.jssize | 2 +- .../test_metadce_cxx_except_wasm.jssize | 2 +- .../metadce/test_metadce_cxx_noexcept.jssize | 2 +- .../metadce/test_metadce_hello_O0.jssize | 2 +- .../metadce/test_metadce_hello_dylink.jssize | 2 +- .../test_metadce_libcxxabi_message_O3.jssize | 2 +- ...dce_libcxxabi_message_O3_standalone.jssize | 2 +- test/other/metadce/test_metadce_mem_O3.jssize | 2 +- .../metadce/test_metadce_mem_O3_grow.jssize | 2 +- ...test_metadce_mem_O3_grow_standalone.jssize | 2 +- .../test_metadce_mem_O3_standalone.jssize | 2 +- .../test_metadce_mem_O3_standalone_lib.jssize | 2 +- ...test_metadce_mem_O3_standalone_narg.jssize | 2 +- ...metadce_mem_O3_standalone_narg_flto.jssize | 2 +- .../metadce/test_metadce_minimal_O0.jssize | 2 +- .../metadce/test_metadce_minimal_O1.jssize | 2 +- .../metadce/test_metadce_minimal_O2.jssize | 2 +- .../test_metadce_minimal_pthreads.jssize | 2 +- test/other/test_unoptimized_code_size.js.size | 2 +- ...t_unoptimized_code_size_no_asserts.js.size | 2 +- .../test_unoptimized_code_size_strict.js.size | 2 +- test/pthread/test_pthread_utf8_funcs.cpp | 2 + 52 files changed, 358 insertions(+), 313 deletions(-) delete mode 100644 src/runtime_strings.js diff --git a/ChangeLog.md b/ChangeLog.md index 779ce8f629491..a22e65ebdd71d 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -20,6 +20,19 @@ See docs/process.md for more on how version tagging works. 3.1.35 (in development) ----------------------- +- The following JavaScript runtime functions were converted to JavaScript + library functions: + - UTF8ArrayToString + - UTF8ToString + - stringToUTF8Array + - stringToUTF8 + - lengthBytesUTF8 + If you use any of these functions in your JS code you will now need to include + them explictly in one of the following ways: + - Add them to a `__deps` entry in your JS library file (with leading $) + - Add them to `DEFAULT_LIBRARY_FUNCS_TO_INCLUDE` (with leading $) + - Add them to `EXPORTED_FUNCTIONS` (without leading $) + - Set `-sLEGACY_RUNTIME` to include all of them at once. - `FS.loadFilesFromDB` and `FS.saveFilesToDB` were removed. We think it's unlikly there were any users of these functions since there is now a separate IDBFS filesystem for folks that want persistence. (#19049) diff --git a/src/embind/embind.js b/src/embind/embind.js index 95eabef2f3cfe..85e71fd87a79c 100644 --- a/src/embind/embind.js +++ b/src/embind/embind.js @@ -656,7 +656,8 @@ var LibraryEmbind = { _embind_register_std_string__sig: 'vpp', _embind_register_std_string__deps: [ '$readLatin1String', '$registerType', - '$simpleReadValueFromPointer', '$throwBindingError'], + '$simpleReadValueFromPointer', '$throwBindingError', + '$stringToUTF8', '$lengthBytesUTF8'], _embind_register_std_string: function(rawType, name) { name = readLatin1String(name); var stdStringIsUTF8 diff --git a/src/jsifier.js b/src/jsifier.js index 7516f764b20d7..fa95d9e236e67 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -197,13 +197,16 @@ function ${name}(${args}) { function addImplicitDeps(snippet, deps) { // There are some common dependencies that we inject automatically by // conservatively scanning the input functions for their usage. - // Specifically, these are dependencies that are automatically generated by - // the {{{ makeDynCall }}}, and {{{ runtimeKeepalivePush/Pop }}} macros. + // Specifically, these are dependencies that are very common and would be + // burdensome to add manually to all functions. + // The first four are deps that are automatically/conditionally added + // by the {{{ makeDynCall }}}, and {{{ runtimeKeepalivePush/Pop }}} macros. const autoDeps = [ 'getDynCaller', 'getWasmTableEntry', 'runtimeKeepalivePush', 'runtimeKeepalivePop', + 'UTF8ToString', ]; for (const dep of autoDeps) { if (snippet.includes(dep + '(')) { diff --git a/src/library.js b/src/library.js index 9044c3687fd57..96fff5fd75f29 100644 --- a/src/library.js +++ b/src/library.js @@ -2027,7 +2027,7 @@ mergeInto(LibraryManager.library, { return 0; }, - getnameinfo__deps: ['$Sockets', '$DNS', '$readSockaddr'], + getnameinfo__deps: ['$Sockets', '$DNS', '$readSockaddr', '$stringToUTF8'], getnameinfo: function (sa, salen, node, nodelen, serv, servlen, flags) { var info = readSockaddr(sa, salen); if (info.errno) { @@ -2305,6 +2305,7 @@ mergeInto(LibraryManager.library, { // Mark as `noleakcheck` otherwise lsan will report the last returned string // as a leak. emscripten_run_script_string__noleakcheck: true, + emscripten_run_script_string__deps: ['$lengthBytesUTF8', '$stringToUTF8', 'malloc'], emscripten_run_script_string: function(ptr) { {{{ makeEval("var s = eval(UTF8ToString(ptr));") }}} if (s == null) { @@ -2565,7 +2566,7 @@ mergeInto(LibraryManager.library, { return callstack; }, - emscripten_get_callstack__deps: ['$getCallstack'], + emscripten_get_callstack__deps: ['$getCallstack', '$lengthBytesUTF8', '$stringToUTF8'], emscripten_get_callstack: function(flags, str, maxbytes) { // Use explicit calls to from64 rather then using the __sig // magic here. This is because the __sig wrapper uses arrow function @@ -2647,6 +2648,7 @@ mergeInto(LibraryManager.library, { debugger; }, + emscripten_print_double__deps: ['$stringToUTF8', '$lengthBytesUTF8'], emscripten_print_double: function(x, to, max) { var str = x + ''; if (to) return stringToUTF8(str, to, max); @@ -2887,6 +2889,7 @@ mergeInto(LibraryManager.library, { return result ? result.column || 0 : 0; }, + emscripten_get_module_name__deps: ['$stringToUTF8'], emscripten_get_module_name: function(buf, length) { #if MINIMAL_RUNTIME return stringToUTF8('{{{ TARGET_BASENAME }}}.wasm', buf, length); @@ -3363,6 +3366,9 @@ mergeInto(LibraryManager.library, { // Use program_invocation_short_name and program_invocation_name in compiled // programs. This function is for implementing them. +#if !MINIMAL_RUNTIME + _emscripten_get_progname__deps: ['$stringToUTF8'], +#endif _emscripten_get_progname: function(str, len) { #if !MINIMAL_RUNTIME #if ASSERTIONS @@ -3723,5 +3729,10 @@ DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.push( '$ccall', '$cwrap', '$ExitStatus', + '$UTF8ArrayToString', + '$UTF8ToString', + '$stringToUTF8Array', + '$stringToUTF8', + '$lengthBytesUTF8', ); #endif diff --git a/src/library_dylink.js b/src/library_dylink.js index 0b102e91742af..c440de7479227 100644 --- a/src/library_dylink.js +++ b/src/library_dylink.js @@ -370,6 +370,7 @@ var LibraryDylink = { // returns the side module metadata as an object // { memorySize, memoryAlign, tableSize, tableAlign, neededDynlibs} + $getDylinkMetadata__deps: ['$UTF8ArrayToString'], $getDylinkMetadata__internal: true, $getDylinkMetadata: function(binary) { var offset = 0; diff --git a/src/library_fetch.js b/src/library_fetch.js index 88497f99bae70..f2d470ff03f34 100644 --- a/src/library_fetch.js +++ b/src/library_fetch.js @@ -13,7 +13,9 @@ var LibraryFetch = { $Fetch__postset: 'Fetch.staticInit();', #endif $Fetch: Fetch, + _emscripten_fetch_get_response_headers_length__deps: ['$lengthBytesUTF8'], _emscripten_fetch_get_response_headers_length: fetchGetResponseHeadersLength, + _emscripten_fetch_get_response_headers__deps: ['$lengthBytesUTF8', '$stringToUTF8'], _emscripten_fetch_get_response_headers: fetchGetResponseHeaders, _emscripten_fetch_free: fetchFree, @@ -30,6 +32,7 @@ var LibraryFetch = { '$fetchXHR', '$callUserCallback', '$writeI53ToI64', + '$stringToUTF8', #if FETCH_SUPPORT_INDEXEDDB '$fetchCacheData', '$fetchLoadCachedData', diff --git a/src/library_fs.js b/src/library_fs.js index b47020340b7c4..5c7864e3f48f8 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -5,7 +5,10 @@ */ mergeInto(LibraryManager.library, { - $FS__deps: ['$randomFill', '$PATH', '$PATH_FS', '$TTY', '$MEMFS', '$asyncLoad', '$intArrayFromString', + $FS__deps: ['$randomFill', '$PATH', '$PATH_FS', '$TTY', '$MEMFS', '$asyncLoad', + '$intArrayFromString', + '$stringToUTF8Array', + '$lengthBytesUTF8', #if LibraryManager.has('library_idbfs.js') '$IDBFS', #endif diff --git a/src/library_html5.js b/src/library_html5.js index 4994e6919cc07..7ab09794a5595 100644 --- a/src/library_html5.js +++ b/src/library_html5.js @@ -235,7 +235,7 @@ var LibraryHTML5 = { }, }, - $registerKeyEventCallback__deps: ['$JSEvents', '$findEventTarget'], + $registerKeyEventCallback__deps: ['$JSEvents', '$findEventTarget', '$stringToUTF8'], $registerKeyEventCallback: function(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) { #if PTHREADS targetThread = JSEvents.getTargetThreadForEventCallback(targetThread); @@ -768,7 +768,7 @@ var LibraryHTML5 = { return {{{ cDefs.EMSCRIPTEN_RESULT_SUCCESS }}}; }, - $registerFocusEventCallback__deps: ['$JSEvents', '$findEventTarget'], + $registerFocusEventCallback__deps: ['$JSEvents', '$findEventTarget', '$stringToUTF8'], $registerFocusEventCallback: function(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) { #if PTHREADS targetThread = JSEvents.getTargetThreadForEventCallback(targetThread); @@ -1073,7 +1073,7 @@ var LibraryHTML5 = { return {{{ cDefs.EMSCRIPTEN_RESULT_SUCCESS }}}; }, - $fillFullscreenChangeEventData__deps: ['$JSEvents'], + $fillFullscreenChangeEventData__deps: ['$JSEvents', '$stringToUTF8'], $fillFullscreenChangeEventData: function(eventStruct) { var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement; var isFullscreen = !!fullscreenElement; @@ -1662,7 +1662,7 @@ var LibraryHTML5 = { return {{{ cDefs.EMSCRIPTEN_RESULT_SUCCESS }}}; }, - $fillPointerlockChangeEventData__deps: ['$JSEvents'], + $fillPointerlockChangeEventData__deps: ['$JSEvents', '$stringToUTF8'], $fillPointerlockChangeEventData: function(eventStruct) { var pointerLockElement = document.pointerLockElement || document.mozPointerLockElement || document.webkitPointerLockElement || document.msPointerLockElement; var isPointerlocked = !!pointerLockElement; @@ -2105,6 +2105,7 @@ var LibraryHTML5 = { return {{{ cDefs.EMSCRIPTEN_RESULT_SUCCESS }}}; }, + $fillGamepadEventData__deps: ['$stringToUTF8'], $fillGamepadEventData: function(eventStruct, e) { {{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenGamepadEvent.timestamp, 'e.timestamp', 'double') }}}; for (var i = 0; i < e.axes.length; ++i) { diff --git a/src/library_legacy.js b/src/library_legacy.js index dbbcf433431d8..a396573f86e11 100644 --- a/src/library_legacy.js +++ b/src/library_legacy.js @@ -44,12 +44,13 @@ mergeInto(LibraryManager.library, { // in a maximum length that can be used to be secure from out of bounds // writes. $writeStringToMemory__docs: '/** @deprecated @param {boolean=} dontAddNull */', + $writeStringToMemory__deps: ['$lengthBytesUTF8', '$stringToUTF8'], $writeStringToMemory: function(string, buffer, dontAddNull) { warnOnce('writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!'); var /** @type {number} */ lastChar, /** @type {number} */ end; if (dontAddNull) { - // stringToUTF8Array always appends null. If we don't want to do that, remember the + // stringToUTF8 always appends null. If we don't want to do that, remember the // character that existed at the location where the null will be placed, and restore // that after the write (below). end = buffer + lengthBytesUTF8(string); diff --git a/src/library_strings.js b/src/library_strings.js index f72925a2f9ed1..eeefc039d823e 100644 --- a/src/library_strings.js +++ b/src/library_strings.js @@ -7,7 +7,251 @@ #include "arrayUtils.js" mergeInto(LibraryManager.library, { +#if TEXTDECODER == 2 + $UTF8Decoder: "new TextDecoder('utf8')", +#elif TEXTDECODER == 1 + $UTF8Decoder: "typeof TextDecoder != 'undefined' ? new TextDecoder('utf8') : undefined", +#endif + + $UTF8ArrayToString__docs: ` + /** + * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given + * array that contains uint8 values, returns a copy of that string as a + * Javascript String object. + * heapOrArray is either a regular array, or a JavaScript typed array view. + * @param {number} idx + * @param {number=} maxBytesToRead + * @return {string} + */`, +#if TEXTDECODER + $UTF8ArrayToString__deps: ['$UTF8Decoder'], +#endif + $UTF8ArrayToString: function(heapOrArray, idx, maxBytesToRead) { +#if CAN_ADDRESS_2GB + idx >>>= 0; +#endif + var endIdx = idx + maxBytesToRead; +#if TEXTDECODER + var endPtr = idx; + // TextDecoder needs to know the byte length in advance, it doesn't stop on + // null terminator by itself. Also, use the length info to avoid running tiny + // strings through TextDecoder, since .subarray() allocates garbage. + // (As a tiny code save trick, compare endPtr against endIdx using a negation, + // so that undefined means Infinity) + while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr; +#endif // TEXTDECODER + +#if TEXTDECODER == 2 + return UTF8Decoder.decode(heapOrArray.buffer ? {{{ getUnsharedTextDecoderView('heapOrArray', 'idx', 'endPtr') }}} : new Uint8Array(heapOrArray.slice(idx, endPtr))); +#else // TEXTDECODER == 2 +#if TEXTDECODER + if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) { + return UTF8Decoder.decode({{{ getUnsharedTextDecoderView('heapOrArray', 'idx', 'endPtr') }}}); + } +#endif // TEXTDECODER + var str = ''; +#if TEXTDECODER + // If building with TextDecoder, we have already computed the string length + // above, so test loop end condition against that + while (idx < endPtr) { +#else + while (!(idx >= endIdx)) { +#endif + // For UTF8 byte structure, see: + // http://en.wikipedia.org/wiki/UTF-8#Description + // https://www.ietf.org/rfc/rfc2279.txt + // https://tools.ietf.org/html/rfc3629 + var u0 = heapOrArray[idx++]; +#if !TEXTDECODER + // If not building with TextDecoder enabled, we don't know the string + // length, so scan for \0 byte. + // If building with TextDecoder, we know exactly at what byte index the + // string ends, so checking for nulls here would be redundant. + if (!u0) return str; +#endif + if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; } + var u1 = heapOrArray[idx++] & 63; + if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; } + var u2 = heapOrArray[idx++] & 63; + if ((u0 & 0xF0) == 0xE0) { + u0 = ((u0 & 15) << 12) | (u1 << 6) | u2; + } else { +#if ASSERTIONS + if ((u0 & 0xF8) != 0xF0) warnOnce('Invalid UTF-8 leading byte ' + ptrToString(u0) + ' encountered when deserializing a UTF-8 string in wasm memory to a JS string!'); +#endif + u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63); + } + + if (u0 < 0x10000) { + str += String.fromCharCode(u0); + } else { + var ch = u0 - 0x10000; + str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); + } + } + return str; +#endif // TEXTDECODER == 2 + }, + + $UTF8ToString__docs: ` + /** + * 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. + * + * @param {number} ptr + * @param {number=} maxBytesToRead - An optional length that specifies the + * maximum number of bytes to read. You can omit this parameter to scan the + * string until the first \0 byte. If maxBytesToRead is passed, and the string + * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the + * string will cut short at that byte index (i.e. maxBytesToRead will not + * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing + * frequent uses of UTF8ToString() with and without maxBytesToRead may throw + * JS JIT optimizations off, so it is worth to consider consistently using one + * @return {string} + */`, +#if TEXTDECODER == 2 + $UTF8ToString__deps: ['$UTF8Decoder'], +#else + $UTF8ToString__deps: ['$UTF8ArrayToString'], +#endif + $UTF8ToString: function(ptr, maxBytesToRead) { +#if ASSERTIONS + assert(typeof ptr == 'number'); +#endif +#if CAN_ADDRESS_2GB + ptr >>>= 0; +#endif +#if TEXTDECODER == 2 + if (!ptr) return ''; + var maxPtr = ptr + maxBytesToRead; + for (var end = ptr; !(end >= maxPtr) && HEAPU8[end];) ++end; + return UTF8Decoder.decode({{{ getUnsharedTextDecoderView('HEAPU8', 'ptr', 'end') }}}); +#else + return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ''; +#endif + }, + + /** + * Copies the given Javascript String object 'str' to the given byte array at + * address 'outIdx', encoded in UTF8 form and null-terminated. The copy will + * require at most str.length*4+1 bytes of space in the HEAP. Use the function + * lengthBytesUTF8 to compute the exact number of bytes (excluding null + * terminator) that this function will write. + * + * @param {string} str - The Javascript string to copy. + * @param {ArrayBufferView|Array} heap - The array to copy to. Each + * index in this array is assumed + * to be one 8-byte element. + * @param {number} outIdx - The starting offset in the array to begin the copying. + * @param {number} maxBytesToWrite - The maximum number of bytes this function + * can write to the array. This count should + * include the null terminator, i.e. if + * maxBytesToWrite=1, only the null terminator + * will be written and nothing else. + * maxBytesToWrite=0 does not write any bytes + * to the output, not even the null + * terminator. + * @return {number} The number of bytes written, EXCLUDING the null terminator. + */ + $stringToUTF8Array: function(str, heap, outIdx, maxBytesToWrite) { +#if CAN_ADDRESS_2GB + outIdx >>>= 0; +#endif + // Parameter maxBytesToWrite is not optional. Negative values, 0, null, + // undefined and false each don't write out any bytes. + if (!(maxBytesToWrite > 0)) + return 0; + + var startIdx = outIdx; + var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator. + for (var i = 0; i < str.length; ++i) { + // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code + // unit, not a Unicode code point of the character! So decode + // UTF16->UTF32->UTF8. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description + // and https://www.ietf.org/rfc/rfc2279.txt + // and https://tools.ietf.org/html/rfc3629 + var u = str.charCodeAt(i); // possibly a lead surrogate + if (u >= 0xD800 && u <= 0xDFFF) { + var u1 = str.charCodeAt(++i); + u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF); + } + if (u <= 0x7F) { + if (outIdx >= endIdx) break; + heap[outIdx++] = u; + } else if (u <= 0x7FF) { + if (outIdx + 1 >= endIdx) break; + heap[outIdx++] = 0xC0 | (u >> 6); + heap[outIdx++] = 0x80 | (u & 63); + } else if (u <= 0xFFFF) { + if (outIdx + 2 >= endIdx) break; + heap[outIdx++] = 0xE0 | (u >> 12); + heap[outIdx++] = 0x80 | ((u >> 6) & 63); + heap[outIdx++] = 0x80 | (u & 63); + } else { + if (outIdx + 3 >= endIdx) break; +#if ASSERTIONS + if (u > 0x10FFFF) warnOnce('Invalid Unicode code point ' + ptrToString(u) + ' encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).'); +#endif + heap[outIdx++] = 0xF0 | (u >> 18); + heap[outIdx++] = 0x80 | ((u >> 12) & 63); + heap[outIdx++] = 0x80 | ((u >> 6) & 63); + heap[outIdx++] = 0x80 | (u & 63); + } + } + // Null-terminate the pointer to the buffer. + heap[outIdx] = 0; + return outIdx - startIdx; + }, + + /** + * Copies the given Javascript String object 'str' to the emscripten HEAP at + * address 'outPtr', null-terminated and encoded in UTF8 form. The copy will + * require at most str.length*4+1 bytes of space in the HEAP. + * Use the function lengthBytesUTF8 to compute the exact number of bytes + * (excluding null terminator) that this function will write. + * + * @return {number} The number of bytes written, EXCLUDING the null terminator. + */ + $stringToUTF8__deps: ['$stringToUTF8Array'], + $stringToUTF8: function(str, outPtr, maxBytesToWrite) { +#if ASSERTIONS + assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); +#endif + return stringToUTF8Array(str, {{{ heapAndOffset('HEAPU8', 'outPtr') }}}, maxBytesToWrite); + }, + + /** + * Returns the number of bytes the given Javascript string takes if encoded as a + * UTF8 byte array, EXCLUDING the null terminator byte. + * + * @param {string} str - JavaScript string to operator on + * @return {number} Length, in bytes, of the UTF8 encoded string. + */ + $lengthBytesUTF8: function(str) { + var len = 0; + for (var i = 0; i < str.length; ++i) { + // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code + // unit, not a Unicode code point of the character! So decode + // UTF16->UTF32->UTF8. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + var c = str.charCodeAt(i); // possibly a lead surrogate + if (c <= 0x7F) { + len++; + } else if (c <= 0x7FF) { + len += 2; + } else if (c >= 0xD800 && c <= 0xDFFF) { + len += 4; ++i; + } else { + len += 3; + } + } + return len; + }, + $intArrayFromString__docs: '/** @type {function(string, boolean=, number=)} */', + $intArrayFromString__deps: ['$lengthBytesUTF8', '$stringToUTF8Array'], $intArrayFromString: intArrayFromString, $intArrayToString: intArrayToString, @@ -232,6 +476,7 @@ mergeInto(LibraryManager.library, { // Allocate heap space for a JS string, and write it there. // It is the responsibility of the caller to free() that memory. + $stringToNewUTF8__deps: ['$lengthBytesUTF8', '$stringToUTF8'], $stringToNewUTF8: function(str) { var size = lengthBytesUTF8(str) + 1; var ret = {{{ makeMalloc('stringToNewUTF8', 'size') }}}; @@ -240,6 +485,7 @@ mergeInto(LibraryManager.library, { }, // Allocate stack space for a JS string, and write it there. + $stringToUTF8OnStack__deps: ['$lengthBytesUTF8', '$stringToUTF8'], $stringToUTF8OnStack: function(str) { var size = lengthBytesUTF8(str) + 1; var ret = stackAlloc(size); diff --git a/src/library_syscall.js b/src/library_syscall.js index bc08ecb93aa97..45fb3ca65dead 100644 --- a/src/library_syscall.js +++ b/src/library_syscall.js @@ -598,6 +598,7 @@ var SyscallsLibrary = { } return nonzero; }, + __syscall_getcwd__deps: ['$lengthBytesUTF8', '$stringToUTF8'], __syscall_getcwd: function(buf, size) { if (size === 0) return -{{{ cDefs.EINVAL }}}; var cwd = FS.cwd(); @@ -635,6 +636,7 @@ var SyscallsLibrary = { FS.fchown(fd, owner, group); return 0; }, + __syscall_getdents64__deps: ['$stringToUTF8'], __syscall_getdents64: function(fd, dirp, count) { var stream = SYSCALLS.getStreamFromFD(fd) if (!stream.getdents) { @@ -869,6 +871,7 @@ var SyscallsLibrary = { FS.symlink(target, linkpath); return 0; }, + __syscall_readlinkat__deps: ['$lengthBytesUTF8', '$stringToUTF8'], __syscall_readlinkat: function(dirfd, path, buf, bufsize) { path = SYSCALLS.getStr(path); path = SYSCALLS.calculateAt(dirfd, path); diff --git a/src/library_uuid.js b/src/library_uuid.js index f0f0e72219436..0e212e095d1af 100644 --- a/src/library_uuid.js +++ b/src/library_uuid.js @@ -111,6 +111,7 @@ mergeInto(LibraryManager.library, { // Convert a 'compact' form UUID to a string, if the upper parameter is supplied make the string upper case. uuid_unparse__docs: '/** @param {number|boolean=} upper */', + uuid_unparse__deps: ['$stringToUTF8'], uuid_unparse: function(uu, out, upper) { // void uuid_unparse(const uuid_t uu, char *out); var i = 0; diff --git a/src/library_wasi.js b/src/library_wasi.js index c9cca336316d5..1dbb9dbf692c3 100644 --- a/src/library_wasi.js +++ b/src/library_wasi.js @@ -226,7 +226,7 @@ var WasiLibrary = { $printCharBuffers: [null, [], []], // 1 => stdout, 2 => stderr $printCharBuffers__internal: true, $printChar__internal: true, - $printChar__deps: ['$printCharBuffers'], + $printChar__deps: ['$printCharBuffers', '$UTF8ArrayToString'], $printChar: function(stream, curr) { var buffer = printCharBuffers[stream]; #if ASSERTIONS diff --git a/src/library_wasmfs.js b/src/library_wasmfs.js index 2b6136a78a41e..ce489ab50db16 100644 --- a/src/library_wasmfs.js +++ b/src/library_wasmfs.js @@ -276,6 +276,7 @@ mergeInto(LibraryManager.library, { stringToUTF8(s, childNameBuffer, len); }, _wasmfs_get_preloaded_path_name__sig: 'vip', + _wasmfs_get_preloaded_path_name__deps: ['$lengthBytesUTF8', '$stringToUTF8'], _wasmfs_get_preloaded_path_name: function(index, fileNameBuffer) { var s = wasmFSPreloadedFiles[index].pathName; var len = lengthBytesUTF8(s) + 1; diff --git a/src/library_webgl.js b/src/library_webgl.js index c2e2066a2a17a..7455cf0317a0a 100644 --- a/src/library_webgl.js +++ b/src/library_webgl.js @@ -2916,6 +2916,7 @@ var LibraryGL = { return GLctx.getAttribLocation(GL.programs[program], UTF8ToString(name)); }, + $__glGetActiveAttribOrUniform__deps: ['$stringToUTF8'], $__glGetActiveAttribOrUniform: function(funcName, program, index, bufSize, length, size, type, name) { #if GL_ASSERTIONS GL.validateGLObjectID(GL.programs, program, funcName, 'program'); @@ -3167,6 +3168,7 @@ var LibraryGL = { #endif }, + glGetShaderInfoLog__deps: ['$stringToUTF8'], glGetShaderInfoLog: function(shader, maxLength, length, infoLog) { #if GL_ASSERTIONS GL.validateGLObjectID(GL.shaders, shader, 'glGetShaderInfoLog', 'shader'); diff --git a/src/library_websocket.js b/src/library_websocket.js index e6e7ad6ee50ea..06153eaf0a556 100644 --- a/src/library_websocket.js +++ b/src/library_websocket.js @@ -40,7 +40,7 @@ var LibraryWebSocket = { return {{{ cDefs.EMSCRIPTEN_RESULT_SUCCESS }}}; }, - emscripten_websocket_get_extensions__deps: ['$WS'], + emscripten_websocket_get_extensions__deps: ['$WS', '$stringToUTF8'], emscripten_websocket_get_extensions__proxy: 'sync', emscripten_websocket_get_extensions: function(socketId, extensions, extensionsLength) { var socket = WS.sockets[socketId]; @@ -70,7 +70,7 @@ var LibraryWebSocket = { return {{{ cDefs.EMSCRIPTEN_RESULT_SUCCESS }}}; }, - emscripten_websocket_get_protocol__deps: ['$WS'], + emscripten_websocket_get_protocol__deps: ['$WS', '$stringToUTF8'], emscripten_websocket_get_protocol__proxy: 'sync', emscripten_websocket_get_protocol: function(socketId, protocol, protocolLength) { var socket = WS.sockets[socketId]; @@ -100,7 +100,7 @@ var LibraryWebSocket = { return {{{ cDefs.EMSCRIPTEN_RESULT_SUCCESS }}}; }, - emscripten_websocket_get_url__deps: ['$WS'], + emscripten_websocket_get_url__deps: ['$WS', '$stringToUTF8'], emscripten_websocket_get_url__proxy: 'sync', emscripten_websocket_get_url: function(socketId, url, urlLength) { var socket = WS.sockets[socketId]; @@ -186,7 +186,7 @@ var LibraryWebSocket = { return {{{ cDefs.EMSCRIPTEN_RESULT_SUCCESS }}}; }, - emscripten_websocket_set_onclose_callback_on_thread__deps: ['$WS'], + emscripten_websocket_set_onclose_callback_on_thread__deps: ['$WS', '$stringToUTF8'], emscripten_websocket_set_onclose_callback_on_thread__proxy: 'sync', emscripten_websocket_set_onclose_callback_on_thread: function(socketId, userData, callbackFunc, thread) { if (!WS.socketEvent) WS.socketEvent = _malloc(1024); // TODO: sizeof(EmscriptenWebSocketCloseEvent), which is the largest event struct diff --git a/src/modules.js b/src/modules.js index 811ab7ddd8c57..613a836b0975a 100644 --- a/src/modules.js +++ b/src/modules.js @@ -355,11 +355,6 @@ function exportRuntime() { // All possible runtime elements that can be exported let runtimeElements = [ 'run', - 'UTF8ArrayToString', - 'UTF8ToString', - 'stringToUTF8Array', - 'stringToUTF8', - 'lengthBytesUTF8', 'addOnPreRun', 'addOnInit', 'addOnPreMain', diff --git a/src/preamble.js b/src/preamble.js index 5d1c9f5b610ef..1c3a74ac5744e 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -102,8 +102,6 @@ function _free() { #endif // free #endif // ASSERTIONS -#include "runtime_strings.js" - // Memory management var HEAP, diff --git a/src/preamble_minimal.js b/src/preamble_minimal.js index dc6ea52ad9e6b..dd67803067d5e 100644 --- a/src/preamble_minimal.js +++ b/src/preamble_minimal.js @@ -60,8 +60,6 @@ if (Module['doWasm2JS']) { Module['wasm'] = base64Decode('<<< WASM_BINARY_DATA >>>'); #endif -#include "runtime_strings.js" - var HEAP8, HEAP16, HEAP32, HEAPU8, HEAPU16, HEAPU32, HEAPF32, HEAPF64, #if WASM_BIGINT HEAP64, HEAPU64, diff --git a/src/runtime_strings.js b/src/runtime_strings.js deleted file mode 100644 index c412e5e310d7d..0000000000000 --- a/src/runtime_strings.js +++ /dev/null @@ -1,240 +0,0 @@ -/** - * @license - * Copyright 2019 The Emscripten Authors - * SPDX-License-Identifier: MIT - */ - -// runtime_strings.js: String related runtime functions that are part of both -// MINIMAL_RUNTIME and regular runtime. - -#if TEXTDECODER == 2 -var UTF8Decoder = new TextDecoder('utf8'); -#elif TEXTDECODER == 1 -var UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf8') : undefined; -#endif - -/** - * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given - * array that contains uint8 values, returns a copy of that string as a - * Javascript String object. - * heapOrArray is either a regular array, or a JavaScript typed array view. - * @param {number} idx - * @param {number=} maxBytesToRead - * @return {string} - */ -function UTF8ArrayToString(heapOrArray, idx, maxBytesToRead) { -#if CAN_ADDRESS_2GB - idx >>>= 0; -#endif - var endIdx = idx + maxBytesToRead; -#if TEXTDECODER - var endPtr = idx; - // TextDecoder needs to know the byte length in advance, it doesn't stop on - // null terminator by itself. Also, use the length info to avoid running tiny - // strings through TextDecoder, since .subarray() allocates garbage. - // (As a tiny code save trick, compare endPtr against endIdx using a negation, - // so that undefined means Infinity) - while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr; -#endif // TEXTDECODER - -#if TEXTDECODER == 2 - return UTF8Decoder.decode(heapOrArray.buffer ? {{{ getUnsharedTextDecoderView('heapOrArray', 'idx', 'endPtr') }}} : new Uint8Array(heapOrArray.slice(idx, endPtr))); -#else // TEXTDECODER == 2 -#if TEXTDECODER - if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) { - return UTF8Decoder.decode({{{ getUnsharedTextDecoderView('heapOrArray', 'idx', 'endPtr') }}}); - } -#endif // TEXTDECODER - var str = ''; -#if TEXTDECODER - // If building with TextDecoder, we have already computed the string length - // above, so test loop end condition against that - while (idx < endPtr) { -#else - while (!(idx >= endIdx)) { -#endif - // For UTF8 byte structure, see: - // http://en.wikipedia.org/wiki/UTF-8#Description - // https://www.ietf.org/rfc/rfc2279.txt - // https://tools.ietf.org/html/rfc3629 - var u0 = heapOrArray[idx++]; -#if !TEXTDECODER - // If not building with TextDecoder enabled, we don't know the string - // length, so scan for \0 byte. - // If building with TextDecoder, we know exactly at what byte index the - // string ends, so checking for nulls here would be redundant. - if (!u0) return str; -#endif - if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; } - var u1 = heapOrArray[idx++] & 63; - if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; } - var u2 = heapOrArray[idx++] & 63; - if ((u0 & 0xF0) == 0xE0) { - u0 = ((u0 & 15) << 12) | (u1 << 6) | u2; - } else { -#if ASSERTIONS - if ((u0 & 0xF8) != 0xF0) warnOnce('Invalid UTF-8 leading byte ' + ptrToString(u0) + ' encountered when deserializing a UTF-8 string in wasm memory to a JS string!'); -#endif - u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63); - } - - if (u0 < 0x10000) { - str += String.fromCharCode(u0); - } else { - var ch = u0 - 0x10000; - str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); - } - } - return str; -#endif // TEXTDECODER == 2 -} - -/** - * 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. - * - * @param {number} ptr - * @param {number=} maxBytesToRead - An optional length that specifies the - * maximum number of bytes to read. You can omit this parameter to scan the - * string until the first \0 byte. If maxBytesToRead is passed, and the string - * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the - * string will cut short at that byte index (i.e. maxBytesToRead will not - * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing - * frequent uses of UTF8ToString() with and without maxBytesToRead may throw - * JS JIT optimizations off, so it is worth to consider consistently using one - * @return {string} - */ -function UTF8ToString(ptr, maxBytesToRead) { -#if ASSERTIONS - assert(typeof ptr == 'number'); -#endif -#if CAN_ADDRESS_2GB - ptr >>>= 0; -#endif -#if TEXTDECODER == 2 - if (!ptr) return ''; - var maxPtr = ptr + maxBytesToRead; - for (var end = ptr; !(end >= maxPtr) && HEAPU8[end];) ++end; - return UTF8Decoder.decode({{{ getUnsharedTextDecoderView('HEAPU8', 'ptr', 'end') }}}); -#else - return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ''; -#endif -} - -/** - * Copies the given Javascript String object 'str' to the given byte array at - * address 'outIdx', encoded in UTF8 form and null-terminated. The copy will - * require at most str.length*4+1 bytes of space in the HEAP. Use the function - * lengthBytesUTF8 to compute the exact number of bytes (excluding null - * terminator) that this function will write. - * - * @param {string} str - The Javascript string to copy. - * @param {ArrayBufferView|Array} heap - The array to copy to. Each - * index in this array is assumed - * to be one 8-byte element. - * @param {number} outIdx - The starting offset in the array to begin the copying. - * @param {number} maxBytesToWrite - The maximum number of bytes this function - * can write to the array. This count should - * include the null terminator, i.e. if - * maxBytesToWrite=1, only the null terminator - * will be written and nothing else. - * maxBytesToWrite=0 does not write any bytes - * to the output, not even the null - * terminator. - * @return {number} The number of bytes written, EXCLUDING the null terminator. - */ -function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) { -#if CAN_ADDRESS_2GB - outIdx >>>= 0; -#endif - // Parameter maxBytesToWrite is not optional. Negative values, 0, null, - // undefined and false each don't write out any bytes. - if (!(maxBytesToWrite > 0)) - return 0; - - var startIdx = outIdx; - var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator. - for (var i = 0; i < str.length; ++i) { - // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code - // unit, not a Unicode code point of the character! So decode - // UTF16->UTF32->UTF8. - // See http://unicode.org/faq/utf_bom.html#utf16-3 - // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description - // and https://www.ietf.org/rfc/rfc2279.txt - // and https://tools.ietf.org/html/rfc3629 - var u = str.charCodeAt(i); // possibly a lead surrogate - if (u >= 0xD800 && u <= 0xDFFF) { - var u1 = str.charCodeAt(++i); - u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF); - } - if (u <= 0x7F) { - if (outIdx >= endIdx) break; - heap[outIdx++] = u; - } else if (u <= 0x7FF) { - if (outIdx + 1 >= endIdx) break; - heap[outIdx++] = 0xC0 | (u >> 6); - heap[outIdx++] = 0x80 | (u & 63); - } else if (u <= 0xFFFF) { - if (outIdx + 2 >= endIdx) break; - heap[outIdx++] = 0xE0 | (u >> 12); - heap[outIdx++] = 0x80 | ((u >> 6) & 63); - heap[outIdx++] = 0x80 | (u & 63); - } else { - if (outIdx + 3 >= endIdx) break; -#if ASSERTIONS - if (u > 0x10FFFF) warnOnce('Invalid Unicode code point ' + ptrToString(u) + ' encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).'); -#endif - heap[outIdx++] = 0xF0 | (u >> 18); - heap[outIdx++] = 0x80 | ((u >> 12) & 63); - heap[outIdx++] = 0x80 | ((u >> 6) & 63); - heap[outIdx++] = 0x80 | (u & 63); - } - } - // Null-terminate the pointer to the buffer. - heap[outIdx] = 0; - return outIdx - startIdx; -} - -/** - * Copies the given Javascript String object 'str' to the emscripten HEAP at - * address 'outPtr', null-terminated and encoded in UTF8 form. The copy will - * require at most str.length*4+1 bytes of space in the HEAP. - * Use the function lengthBytesUTF8 to compute the exact number of bytes - * (excluding null terminator) that this function will write. - * - * @return {number} The number of bytes written, EXCLUDING the null terminator. - */ -function stringToUTF8(str, outPtr, maxBytesToWrite) { -#if ASSERTIONS - assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); -#endif - return stringToUTF8Array(str, {{{ heapAndOffset('HEAPU8', 'outPtr') }}}, maxBytesToWrite); -} - -/** - * Returns the number of bytes the given Javascript string takes if encoded as a - * UTF8 byte array, EXCLUDING the null terminator byte. - * - * @param {string} str - JavaScript string to operator on - * @return {number} Length, in bytes, of the UTF8 encoded string. - */ -function lengthBytesUTF8(str) { - var len = 0; - for (var i = 0; i < str.length; ++i) { - // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code - // unit, not a Unicode code point of the character! So decode - // UTF16->UTF32->UTF8. - // See http://unicode.org/faq/utf_bom.html#utf16-3 - var c = str.charCodeAt(i); // possibly a lead surrogate - if (c <= 0x7F) { - len++; - } else if (c <= 0x7FF) { - len += 2; - } else if (c >= 0xD800 && c <= 0xDFFF) { - len += 4; ++i; - } else { - len += 3; - } - } - return len; -} diff --git a/test/code_size/hello_webgl2_wasm2js.json b/test/code_size/hello_webgl2_wasm2js.json index b57f45586eb05..82590513233fa 100644 --- a/test/code_size/hello_webgl2_wasm2js.json +++ b/test/code_size/hello_webgl2_wasm2js.json @@ -1,10 +1,10 @@ { "a.html": 567, "a.html.gz": 379, - "a.js": 18210, - "a.js.gz": 8068, + "a.js": 18201, + "a.js.gz": 8063, "a.mem": 3171, "a.mem.gz": 2714, - "total": 21948, - "total_gz": 11161 + "total": 21939, + "total_gz": 11156 } diff --git a/test/code_size/hello_webgl_wasm2js.json b/test/code_size/hello_webgl_wasm2js.json index 4f88747f65ba3..0bce64c31085a 100644 --- a/test/code_size/hello_webgl_wasm2js.json +++ b/test/code_size/hello_webgl_wasm2js.json @@ -1,10 +1,10 @@ { "a.html": 567, "a.html.gz": 379, - "a.js": 17681, - "a.js.gz": 7887, + "a.js": 17673, + "a.js.gz": 7885, "a.mem": 3171, "a.mem.gz": 2714, - "total": 21419, - "total_gz": 10980 + "total": 21411, + "total_gz": 10978 } diff --git a/test/code_size/hello_world_wasm.js b/test/code_size/hello_world_wasm.js index 1621dc2eecb62..39c7f8ea8fdd0 100644 --- a/test/code_size/hello_world_wasm.js +++ b/test/code_size/hello_world_wasm.js @@ -1,12 +1,12 @@ -var d = Module, e = new TextDecoder("utf8"), f, g, h; +var d = Module, e, f, g = new TextDecoder("utf8"), h; WebAssembly.instantiate(d.wasm, { a: { a: function(a) { var c = console, k = c.log; if (a) { - for (var l = a + void 0, b = a; !(b >= l) && f[b]; ) ++b; - a = e.decode(f.subarray(a, b)); + for (var l = a + void 0, b = a; !(b >= l) && e[b]; ) ++b; + a = g.decode(e.subarray(a, b)); } else a = ""; k.call(c, a); } @@ -14,8 +14,8 @@ WebAssembly.instantiate(d.wasm, { }).then((function(a) { a = a.instance.exports; h = a.d; - g = a.b; - f = new Uint8Array(g.buffer); + f = a.b; + e = new Uint8Array(f.buffer); a.c(); h(); })); \ No newline at end of file diff --git a/test/code_size/hello_world_wasm2js.js b/test/code_size/hello_world_wasm2js.js index a0f42eb284ab8..abf10cbbb704e 100644 --- a/test/code_size/hello_world_wasm2js.js +++ b/test/code_size/hello_world_wasm2js.js @@ -1,9 +1,9 @@ -var b = Module, d = new TextDecoder("utf8"), k = new function(a) { +var b = Module, g = new function(a) { this.buffer = new ArrayBuffer(65536 * a.initial); }({ initial: 256, maximum: 256 -}), l = k.buffer, g = new Uint8Array(l), m; +}), k = g.buffer, d = new Uint8Array(k), l = new TextDecoder("utf8"), m; function c(a) { this.exports = function(h) { @@ -43,17 +43,17 @@ function c(a) { a: function(a) { var h = console, n = h.log; if (a) { - for (var f = a + void 0, e = a; !(e >= f) && g[e]; ) ++e; - a = d.decode(g.subarray(a, e)); + for (var f = a + void 0, e = a; !(e >= f) && d[e]; ) ++e; + a = l.decode(d.subarray(a, e)); } else a = ""; n.call(h, a); }, - memory: k + memory: g } }).then((function(a) { a = a.instance.exports; m = a.c; - g.set(new Uint8Array(b.mem), 1024); + d.set(new Uint8Array(b.mem), 1024); a.b(); m(); })); \ No newline at end of file diff --git a/test/code_size/hello_world_wasm2js.json b/test/code_size/hello_world_wasm2js.json index 1c5bd3408e704..a3f3cbd9c3e90 100644 --- a/test/code_size/hello_world_wasm2js.json +++ b/test/code_size/hello_world_wasm2js.json @@ -2,9 +2,9 @@ "a.html": 671, "a.html.gz": 430, "a.js": 710, - "a.js.gz": 435, + "a.js.gz": 433, "a.mem": 6, "a.mem.gz": 32, "total": 1387, - "total_gz": 897 + "total_gz": 895 } diff --git a/test/code_size/random_printf_wasm.json b/test/code_size/random_printf_wasm.json index a01587ec0fdd8..61d36dd843d9f 100644 --- a/test/code_size/random_printf_wasm.json +++ b/test/code_size/random_printf_wasm.json @@ -1,6 +1,6 @@ { "a.html": 12778, - "a.html.gz": 6977, + "a.html.gz": 6975, "total": 12778, - "total_gz": 6977 + "total_gz": 6975 } diff --git a/test/code_size/random_printf_wasm2js.json b/test/code_size/random_printf_wasm2js.json index 940cac873a931..583d6d5870767 100644 --- a/test/code_size/random_printf_wasm2js.json +++ b/test/code_size/random_printf_wasm2js.json @@ -1,6 +1,6 @@ { "a.html": 17390, - "a.html.gz": 7551, + "a.html.gz": 7550, "total": 17390, - "total_gz": 7551 + "total_gz": 7550 } diff --git a/test/core/test_em_js.cpp b/test/core/test_em_js.cpp index ece7bc96c8ad3..1d50e6e55f97e 100644 --- a/test/core/test_em_js.cpp +++ b/test/core/test_em_js.cpp @@ -63,6 +63,8 @@ EM_JS(int, user_comma, (void), { return x[y][1]; }); +EM_JS_DEPS(deps, "$stringToUTF8,$lengthBytesUTF8"); + EM_JS(char*, return_utf8_str, (void), { var jsString = 'こんにちは'; var lengthBytes = lengthBytesUTF8(jsString)+1; diff --git a/test/other/metadce/test_metadce_cxx_ctors1.jssize b/test/other/metadce/test_metadce_cxx_ctors1.jssize index 11aaae0dc022f..e0d406ae03b87 100644 --- a/test/other/metadce/test_metadce_cxx_ctors1.jssize +++ b/test/other/metadce/test_metadce_cxx_ctors1.jssize @@ -1 +1 @@ -26183 +26178 diff --git a/test/other/metadce/test_metadce_cxx_ctors2.jssize b/test/other/metadce/test_metadce_cxx_ctors2.jssize index c87d967550f6a..56f822ab463b2 100644 --- a/test/other/metadce/test_metadce_cxx_ctors2.jssize +++ b/test/other/metadce/test_metadce_cxx_ctors2.jssize @@ -1 +1 @@ -26147 +26142 diff --git a/test/other/metadce/test_metadce_cxx_except.jssize b/test/other/metadce/test_metadce_cxx_except.jssize index f11164ae1afba..b96e97707e21e 100644 --- a/test/other/metadce/test_metadce_cxx_except.jssize +++ b/test/other/metadce/test_metadce_cxx_except.jssize @@ -1 +1 @@ -30720 +30715 diff --git a/test/other/metadce/test_metadce_cxx_except_wasm.jssize b/test/other/metadce/test_metadce_cxx_except_wasm.jssize index 79ad1614ad48f..d62e0edd7d545 100644 --- a/test/other/metadce/test_metadce_cxx_except_wasm.jssize +++ b/test/other/metadce/test_metadce_cxx_except_wasm.jssize @@ -1 +1 @@ -25862 +25857 diff --git a/test/other/metadce/test_metadce_cxx_noexcept.jssize b/test/other/metadce/test_metadce_cxx_noexcept.jssize index 11aaae0dc022f..e0d406ae03b87 100644 --- a/test/other/metadce/test_metadce_cxx_noexcept.jssize +++ b/test/other/metadce/test_metadce_cxx_noexcept.jssize @@ -1 +1 @@ -26183 +26178 diff --git a/test/other/metadce/test_metadce_hello_O0.jssize b/test/other/metadce/test_metadce_hello_O0.jssize index 198c1f4e0790b..62b8d754e9866 100644 --- a/test/other/metadce/test_metadce_hello_O0.jssize +++ b/test/other/metadce/test_metadce_hello_O0.jssize @@ -1 +1 @@ -23990 +24002 diff --git a/test/other/metadce/test_metadce_hello_dylink.jssize b/test/other/metadce/test_metadce_hello_dylink.jssize index 2ef6bbb56d062..e8f92ab1737aa 100644 --- a/test/other/metadce/test_metadce_hello_dylink.jssize +++ b/test/other/metadce/test_metadce_hello_dylink.jssize @@ -1 +1 @@ -27922 +27921 diff --git a/test/other/metadce/test_metadce_libcxxabi_message_O3.jssize b/test/other/metadce/test_metadce_libcxxabi_message_O3.jssize index e96a113a815ce..95494025b416c 100644 --- a/test/other/metadce/test_metadce_libcxxabi_message_O3.jssize +++ b/test/other/metadce/test_metadce_libcxxabi_message_O3.jssize @@ -1 +1 @@ -5170 +5166 diff --git a/test/other/metadce/test_metadce_libcxxabi_message_O3_standalone.jssize b/test/other/metadce/test_metadce_libcxxabi_message_O3_standalone.jssize index b399a63028457..2874bd57eeefd 100644 --- a/test/other/metadce/test_metadce_libcxxabi_message_O3_standalone.jssize +++ b/test/other/metadce/test_metadce_libcxxabi_message_O3_standalone.jssize @@ -1 +1 @@ -5238 +5234 diff --git a/test/other/metadce/test_metadce_mem_O3.jssize b/test/other/metadce/test_metadce_mem_O3.jssize index 1f10f1976c57e..a49b0bdb8b0d5 100644 --- a/test/other/metadce/test_metadce_mem_O3.jssize +++ b/test/other/metadce/test_metadce_mem_O3.jssize @@ -1 +1 @@ -6092 +6088 diff --git a/test/other/metadce/test_metadce_mem_O3_grow.jssize b/test/other/metadce/test_metadce_mem_O3_grow.jssize index 7b44e6c407b80..0a85a000114a0 100644 --- a/test/other/metadce/test_metadce_mem_O3_grow.jssize +++ b/test/other/metadce/test_metadce_mem_O3_grow.jssize @@ -1 +1 @@ -6429 +6425 diff --git a/test/other/metadce/test_metadce_mem_O3_grow_standalone.jssize b/test/other/metadce/test_metadce_mem_O3_grow_standalone.jssize index c9a4db7eba921..a734b82fb60ea 100644 --- a/test/other/metadce/test_metadce_mem_O3_grow_standalone.jssize +++ b/test/other/metadce/test_metadce_mem_O3_grow_standalone.jssize @@ -1 +1 @@ -5818 +5815 diff --git a/test/other/metadce/test_metadce_mem_O3_standalone.jssize b/test/other/metadce/test_metadce_mem_O3_standalone.jssize index bac191e478119..c689f62048150 100644 --- a/test/other/metadce/test_metadce_mem_O3_standalone.jssize +++ b/test/other/metadce/test_metadce_mem_O3_standalone.jssize @@ -1 +1 @@ -5741 +5737 diff --git a/test/other/metadce/test_metadce_mem_O3_standalone_lib.jssize b/test/other/metadce/test_metadce_mem_O3_standalone_lib.jssize index d57d96f601aca..7ac3c34e4749d 100644 --- a/test/other/metadce/test_metadce_mem_O3_standalone_lib.jssize +++ b/test/other/metadce/test_metadce_mem_O3_standalone_lib.jssize @@ -1 +1 @@ -5256 +5252 diff --git a/test/other/metadce/test_metadce_mem_O3_standalone_narg.jssize b/test/other/metadce/test_metadce_mem_O3_standalone_narg.jssize index b399a63028457..2874bd57eeefd 100644 --- a/test/other/metadce/test_metadce_mem_O3_standalone_narg.jssize +++ b/test/other/metadce/test_metadce_mem_O3_standalone_narg.jssize @@ -1 +1 @@ -5238 +5234 diff --git a/test/other/metadce/test_metadce_mem_O3_standalone_narg_flto.jssize b/test/other/metadce/test_metadce_mem_O3_standalone_narg_flto.jssize index b399a63028457..2874bd57eeefd 100644 --- a/test/other/metadce/test_metadce_mem_O3_standalone_narg_flto.jssize +++ b/test/other/metadce/test_metadce_mem_O3_standalone_narg_flto.jssize @@ -1 +1 @@ -5238 +5234 diff --git a/test/other/metadce/test_metadce_minimal_O0.jssize b/test/other/metadce/test_metadce_minimal_O0.jssize index fc4c8011f0552..ad846c4f1412f 100644 --- a/test/other/metadce/test_metadce_minimal_O0.jssize +++ b/test/other/metadce/test_metadce_minimal_O0.jssize @@ -1 +1 @@ -20298 +20248 diff --git a/test/other/metadce/test_metadce_minimal_O1.jssize b/test/other/metadce/test_metadce_minimal_O1.jssize index 5e91da113af69..d4c9c722de609 100644 --- a/test/other/metadce/test_metadce_minimal_O1.jssize +++ b/test/other/metadce/test_metadce_minimal_O1.jssize @@ -1 +1 @@ -4935 +4869 diff --git a/test/other/metadce/test_metadce_minimal_O2.jssize b/test/other/metadce/test_metadce_minimal_O2.jssize index e67b201f450e6..bb778e4e859fc 100644 --- a/test/other/metadce/test_metadce_minimal_O2.jssize +++ b/test/other/metadce/test_metadce_minimal_O2.jssize @@ -1 +1 @@ -3798 +3737 diff --git a/test/other/metadce/test_metadce_minimal_pthreads.jssize b/test/other/metadce/test_metadce_minimal_pthreads.jssize index 32f63fcc9dfdf..691c02c06b388 100644 --- a/test/other/metadce/test_metadce_minimal_pthreads.jssize +++ b/test/other/metadce/test_metadce_minimal_pthreads.jssize @@ -1 +1 @@ -15557 +15562 diff --git a/test/other/test_unoptimized_code_size.js.size b/test/other/test_unoptimized_code_size.js.size index c406ed12e1d78..5eaf22fbbe33c 100644 --- a/test/other/test_unoptimized_code_size.js.size +++ b/test/other/test_unoptimized_code_size.js.size @@ -1 +1 @@ -64444 +59608 diff --git a/test/other/test_unoptimized_code_size_no_asserts.js.size b/test/other/test_unoptimized_code_size_no_asserts.js.size index 5c9209553b59f..a1a4ad036cfb3 100644 --- a/test/other/test_unoptimized_code_size_no_asserts.js.size +++ b/test/other/test_unoptimized_code_size_no_asserts.js.size @@ -1 +1 @@ -37791 +33322 diff --git a/test/other/test_unoptimized_code_size_strict.js.size b/test/other/test_unoptimized_code_size_strict.js.size index 62df8c0b97d49..30bb88e98b13c 100644 --- a/test/other/test_unoptimized_code_size_strict.js.size +++ b/test/other/test_unoptimized_code_size_strict.js.size @@ -1 +1 @@ -63386 +58550 diff --git a/test/pthread/test_pthread_utf8_funcs.cpp b/test/pthread/test_pthread_utf8_funcs.cpp index ba596f37201c1..490a86e88abb3 100644 --- a/test/pthread/test_pthread_utf8_funcs.cpp +++ b/test/pthread/test_pthread_utf8_funcs.cpp @@ -13,6 +13,8 @@ char stringBuffer[1024]; #define TEST_STRING "something long so that it hits the TextDecoder path" +EM_JS_DEPS(deps, "$stringToUTF8"); + static void *thread1_start(void *arg) { EM_ASM({ var mystr = UTF8ToString($0);