From 8d30ebdf136c3626a94193b47a04ccc263549cf9 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Tue, 14 Jun 2022 17:01:09 -0700 Subject: [PATCH] Update emscripten patches again (#2684) This drops the Rust patch and "Throw away errors in minify wasm_js" which I suspect was fixed by an emscripten update (I'm not sure how long ago). It replaces the two remaining emscripten patches with new versions that match the versions I am upstreaming. --- Makefile.envs | 1 + ...Add-BigInt64Array-shim-for-Safari-14.patch | 158 +++++++++++++++++ ...-Throw-away-errors-in-minify_wasm_js.patch | 36 ---- ...Add-BigInt64Array-shim-for-Safari-14.patch | 162 ------------------ emsdk/patches/0002-Fix-dup-again.patch | 88 ++++++++++ emsdk/patches/0003-Fix-dup-again.patch | 75 -------- 6 files changed, 247 insertions(+), 273 deletions(-) create mode 100644 emsdk/patches/0001-Add-BigInt64Array-shim-for-Safari-14.patch delete mode 100644 emsdk/patches/0001-Throw-away-errors-in-minify_wasm_js.patch delete mode 100644 emsdk/patches/0002-Add-BigInt64Array-shim-for-Safari-14.patch create mode 100644 emsdk/patches/0002-Fix-dup-again.patch delete mode 100644 emsdk/patches/0003-Fix-dup-again.patch diff --git a/Makefile.envs b/Makefile.envs index f0f998765..994fab565 100644 --- a/Makefile.envs +++ b/Makefile.envs @@ -106,6 +106,7 @@ export MAIN_MODULE_LDFLAGS= $(LDFLAGS_BASE) \ -s FORCE_FILESYSTEM=1 \ -s TOTAL_MEMORY=20971520 \ -s ALLOW_MEMORY_GROWTH=1 \ + -s POLYFILL \ \ -lpython$(PYMAJOR).$(PYMINOR) \ -lffi \ diff --git a/emsdk/patches/0001-Add-BigInt64Array-shim-for-Safari-14.patch b/emsdk/patches/0001-Add-BigInt64Array-shim-for-Safari-14.patch new file mode 100644 index 000000000..d1f6b6bd2 --- /dev/null +++ b/emsdk/patches/0001-Add-BigInt64Array-shim-for-Safari-14.patch @@ -0,0 +1,158 @@ +From b8c1b850cf029cbfd23a41f2695fe7e924d07348 Mon Sep 17 00:00:00 2001 +From: Hood Chatham +Date: Sun, 29 May 2022 18:17:29 -0700 +Subject: [PATCH 1/2] Add BigInt64Array shim for Safari 14 + +https://github.com/emscripten-core/emscripten/pull/17103 +--- + ChangeLog.md | 21 +++++++++ + src/polyfill/bigint64array.js | 88 +++++++++++++++++++++++++++++++++++ + src/shell.js | 5 ++ + 3 files changed, 114 insertions(+) + create mode 100644 src/polyfill/bigint64array.js + +diff --git a/ChangeLog.md b/ChangeLog.md +index fecdfa383..cb65c0d29 100644 +--- a/ChangeLog.md ++++ b/ChangeLog.md +@@ -20,6 +20,27 @@ See docs/process.md for more on how version tagging works. + + 3.1.13 + ------ ++3.2.0 ++----- ++- Emscripten now knows what minimum browser versions the `WASM_BIGINT` feature ++ requires and will automatically set the defaults accordingly. (#17163) ++- Weak undefined symbols fixed in dynamic linking. (#17164) ++- Internally, the name of `main` function now gets mangled (by clang) in the ++ same way as with other wasm targets. This means that within the wasm module ++ the name of the main function can now be `__main_argc_argv`, but, since we ++ still export this to JS as `_main`, this should not be a user-visible change. ++- Use of pkg-config from cmake not longer causes the C++ include path to be ++ broken. (#17137) ++- `emscripten_runtime_keeplive_push()` and `emscripten_runtime_keeplive_push()` ++ are now exposed to native code and can be used to keep the runtime alive ++ without immediately unwinding the event loop (as ++ `emscripten_exit_with_live_runtime()` does). (#17160) ++- Added a shim for `BigInt64Array` so `-sWASM_BIGINT` can be used in Safari ++ v14. (#17103) ++ ++3.1.13 - 06/02/2022 ++------------------- ++- xlocale.h compatibility header was restored after being removed in 3.1.12. + + 3.1.12 - 05/25/2022 + ------------------- +diff --git a/src/polyfill/bigint64array.js b/src/polyfill/bigint64array.js +new file mode 100644 +index 000000000..3b21fe914 +--- /dev/null ++++ b/src/polyfill/bigint64array.js +@@ -0,0 +1,88 @@ ++if (typeof globalThis.BigInt64Array === "undefined") { ++ // BigInt64Array polyfill for Safari versions between v14.0 and v15.0. ++ // All browsers other than Safari added BigInt and BigInt64Array at the same ++ // time, but Safari introduced BigInt in v14.0 and introduced BigInt64Array in ++ // v15.0 ++ ++ function partsToBigIntSigned(lower, upper) { ++ return BigInt(lower) | (BigInt(upper + 2 * (upper & 0x80000000)) << 32n); ++ } ++ ++ function partsToBigIntUnsigned(lower, upper) { ++ return BigInt(lower) | (BigInt(upper) << 32n); ++ } ++ ++ function bigIntToParts(value) { ++ var lower = Number(BigInt(value) & BigInt(0xffffffff)) | 0; ++ var upper = (Number(BigInt(value) >> 32n) | 0); ++ return [lower, upper]; ++ } ++ ++ function createBigIntArrayShim(partsToBigInt) { ++ function createBigInt64Array(array) { ++ if (!ArrayBuffer.isView(array)){ ++ array = new Uint32Array(array); ++ } ++ var proxy = new Proxy({ ++ slice: function(min, max) { ++ var new_buf = array.slice(min * 2, max *2); ++ return createBigInt64Array(new_buf); ++ }, ++ subarray: function(min, max) { ++ var new_buf = array.subarray(min * 2, max *2); ++ return createBigInt64Array(new_buf); ++ }, ++ [Symbol.iterator]: function*() { ++ for (var i = 0; i < (array.length)/2; i++) { ++ yield partsToBigInt(array[2*i], array[2*i+1]); ++ } ++ }, ++ buffer : array.buffer, ++ byteLength : array.byteLength, ++ offset : array.byteOffset / 2, ++ copyWithin: function(target, start, end) { ++ array.copyWithin(target*2, start * 2, end*2); ++ return proxy; ++ }, ++ set: function(source, targetOffset) { ++ if (2*(source.length + targetOffset) > array.length) { ++ // This is the Chrome error message ++ // Firefox: "invalid or out-of-range index" ++ throw new RangeError("offset is out of bounds"); ++ } ++ for (var i = 0; i < array.length; i++) { ++ var value = source[i]; ++ var pair = bigIntToParts(BigInt(value)); ++ array.set(pair, 2*(targetOffset + i)); ++ } ++ } ++ }, { ++ get: function(target, idx, receiver) { ++ if (typeof idx !== "string" || !/^\d+$/.test(idx)) { ++ return Reflect.get(target, idx, receiver); ++ } ++ var lower = array[idx * 2]; ++ var upper = array[idx * 2 + 1]; ++ return partsToBigInt(lower, upper); ++ }, ++ set: function(target, idx, value, receiver) { ++ if (typeof idx !== "string" || !/^\d+$/.test(idx)) { ++ return Reflect.set(target, idx, value, receiver); ++ } ++ if (typeof value !== "bigint") { ++ // Chrome error message, Firefox has no "a" in front if "BigInt". ++ throw new TypeError(`Cannot convert ${value} to a BigInt`); ++ } ++ var pair = bigIntToParts(value); ++ array.set(pair, 2*idx); ++ return true; ++ } ++ }); ++ return proxy; ++ } ++ return createBigInt64Array; ++ } ++ ++ globalThis.BigUint64Array = createBigIntArrayShim(partsToBigIntUnsigned); ++ globalThis.BigInt64Array = createBigIntArrayShim(partsToBigIntSigned); ++} +diff --git a/src/shell.js b/src/shell.js +index 22fac7f69..5a89717fe 100644 +--- a/src/shell.js ++++ b/src/shell.js +@@ -51,6 +51,11 @@ var Module = typeof {{{ EXPORT_NAME }}} != 'undefined' ? {{{ EXPORT_NAME }}} : { + #if MIN_CHROME_VERSION < 45 || MIN_EDGE_VERSION < 12 || MIN_FIREFOX_VERSION < 34 || MIN_IE_VERSION != TARGET_NOT_SUPPORTED || MIN_SAFARI_VERSION < 90000 + #include "polyfill/objassign.js" + #endif ++ ++// See https://caniuse.com/mdn-javascript_builtins_bigint64array ++#if WASM_BIGINT && MIN_SAFARI_VERSION < 150000 ++#include "polyfill/bigint64array.js" ++#endif + #endif // POLYFILL + + #if MODULARIZE +-- +2.25.1 + diff --git a/emsdk/patches/0001-Throw-away-errors-in-minify_wasm_js.patch b/emsdk/patches/0001-Throw-away-errors-in-minify_wasm_js.patch deleted file mode 100644 index 9336d23c9..000000000 --- a/emsdk/patches/0001-Throw-away-errors-in-minify_wasm_js.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 314d9d1c6405cc197a2022d3176a225c9d70b9e9 Mon Sep 17 00:00:00 2001 -From: Hood -Date: Thu, 24 Jun 2021 04:08:02 -0700 -Subject: [PATCH 1/4] Throw away errors in minify_wasm_js - ---- - emcc.py | 13 ++++++++----- - 1 file changed, 8 insertions(+), 5 deletions(-) - -diff --git a/emcc.py b/emcc.py -index d67aa5414..b97321cde 100755 ---- a/emcc.py -+++ b/emcc.py -@@ -3409,11 +3409,14 @@ def phase_binaryen(target, options, wasm_target): - # Closure can print out readable error messages (Closure will then - # minify whitespace afterwards) - save_intermediate_with_wasm('preclean', wasm_target) -- final_js = building.minify_wasm_js(js_file=final_js, -- wasm_file=wasm_target, -- expensive_optimizations=will_metadce(), -- minify_whitespace=minify_whitespace() and not options.use_closure_compiler, -- debug_info=intermediate_debug_info) -+ try: -+ final_js = building.minify_wasm_js(js_file=final_js, -+ wasm_file=wasm_target, -+ expensive_optimizations=will_metadce(), -+ minify_whitespace=minify_whitespace() and not options.use_closure_compiler, -+ debug_info=intermediate_debug_info) -+ except: -+ pass - save_intermediate_with_wasm('postclean', wasm_target) - - if settings.ASYNCIFY_LAZY_LOAD_CODE: --- -2.25.1 - diff --git a/emsdk/patches/0002-Add-BigInt64Array-shim-for-Safari-14.patch b/emsdk/patches/0002-Add-BigInt64Array-shim-for-Safari-14.patch deleted file mode 100644 index 8388d06dd..000000000 --- a/emsdk/patches/0002-Add-BigInt64Array-shim-for-Safari-14.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 458c78230e6dd45d724b04904f15628c570ae904 Mon Sep 17 00:00:00 2001 -From: Hood Chatham -Date: Wed, 8 Jun 2022 19:08:18 -0700 -Subject: [PATCH 2/4] Add BigInt64Array shim for Safari 14 - ---- - src/polyfill/bigint64array.js | 94 +++++++++++++++++++++++++++++++++++ - src/preamble.js | 2 +- - src/settings.js | 4 ++ - src/shell.js | 7 ++- - 4 files changed, 105 insertions(+), 2 deletions(-) - create mode 100644 src/polyfill/bigint64array.js - -diff --git a/src/polyfill/bigint64array.js b/src/polyfill/bigint64array.js -new file mode 100644 -index 000000000..448a2d2a4 ---- /dev/null -+++ b/src/polyfill/bigint64array.js -@@ -0,0 +1,94 @@ -+// BigInt ==> globalThis so we can use globalThis. -+var BigInt64Array; -+var BigUint64Array; -+if (typeof globalThis.BigInt64Array !== "undefined") { -+ BigInt64Array = globalThis.BigInt64Array; -+ BigUint64Array = globalThis.BigUint64Array; -+} else { -+ // BigInt64Array polyfill for Safari versions between v14.0 and v15.0. -+ // All browsers other than Safari added BigInt and BigInt64Array at the same -+ // time, but Safari introduced BigInt in v14.0 and introduced BigInt64Array in -+ // v15.0 -+ -+ function partsToBigIntSigned(lower, upper) { -+ return BigInt(lower) | (BigInt(upper + 2 * (upper & 0x80000000)) << BigInt(32)); -+ } -+ -+ function partsToBigIntUnsigned(lower, upper) { -+ return BigInt(lower) | (BigInt(upper) << BigInt(32)); -+ } -+ -+ function bigIntToParts(value) { -+ var lower = Number(BigInt(value) & BigInt(0xffffffff)) | 0; -+ var upper = (Number(BigInt(value) >> BigInt(32)) | 0); -+ return [lower, upper]; -+ } -+ -+ function createBigIntArrayShim(partsToBigInt) { -+ function createBigInt64Array(array) { -+ if(!ArrayBuffer.isView(array)){ -+ array = new Uint32Array(array); -+ } -+ let proxy = new Proxy({ -+ slice: function(min, max) { -+ var new_buf = array.slice(min * 2, max *2); -+ return createBigInt64Array(new_buf); -+ }, -+ subarray: function(min, max) { -+ var new_buf = array.subarray(min * 2, max *2); -+ return createBigInt64Array(new_buf); -+ }, -+ [Symbol.iterator]: function*() { -+ for (var i = 0; i < (array.length)/2; i++) { -+ yield partsToBigInt(array[2*i], array[2*i+1]); -+ } -+ }, -+ buffer : array.buffer, -+ byteLength : array.byteLength, -+ offset : array.byteOffset / 2, -+ copyWithin: function(target, start, end) { -+ array.copyWithin(target*2, start * 2, end*2); -+ return proxy; -+ }, -+ set: function(source, targetOffset) { -+ if (2*(source.length + targetOffset) > array.length) { -+ // This is the Chrome error message -+ // Firefox: "invalid or out-of-range index" -+ throw new RangeError("offset is out of bounds"); -+ } -+ for (var i = 0; i < array.length; i++) { -+ var value = source[i]; -+ var pair = bigIntToParts(BigInt(value)); -+ array.set(pair, 2*(targetOffset + i)); -+ } -+ } -+ }, { -+ get: function(target, idx, receiver) { -+ if (typeof idx !== "string" || !/^\d+$/.test(idx)) { -+ return Reflect.get(target, idx, receiver); -+ } -+ var lower = array[idx * 2]; -+ var upper = array[idx * 2 + 1]; -+ return partsToBigInt(lower, upper); -+ }, -+ set: function(target, idx, value, receiver) { -+ if (typeof idx !== "string" || !/^\d+$/.test(idx)) { -+ return Reflect.set(target, idx, value, receiver); -+ } -+ if (typeof value !== "bigint") { -+ // Chrome error message, Firefox has no "a" in front if "BigInt". -+ throw new TypeError(`Cannot convert ${value} to a BigInt`); -+ } -+ var pair = bigIntToParts(value); -+ array.set(pair, 2*idx); -+ return true; -+ } -+ }); -+ return proxy; -+ } -+ return createBigInt64Array; -+ } -+ -+ var BigUint64Array = createBigIntArrayShim(partsToBigIntUnsigned); -+ var BigInt64Array = createBigIntArrayShim(partsToBigIntSigned); -+} -diff --git a/src/preamble.js b/src/preamble.js -index ce24d8456..618ccd2ac 100644 ---- a/src/preamble.js -+++ b/src/preamble.js -@@ -297,7 +297,7 @@ function updateGlobalBufferAndViews(buf) { - #if WASM_BIGINT - Module['HEAP64'] = HEAP64 = new BigInt64Array(buf); - Module['HEAPU64'] = HEAPU64 = new BigUint64Array(buf); --#endif -+#endif // WASM_BIGINT - } - - var TOTAL_STACK = {{{ TOTAL_STACK }}}; -diff --git a/src/settings.js b/src/settings.js -index 1a8b7f1fe..be5964519 100644 ---- a/src/settings.js -+++ b/src/settings.js -@@ -1341,6 +1341,10 @@ var DYNCALLS = false; - // WebAssembly integration with JavaScript BigInt. When enabled we don't need - // to legalize i64s into pairs of i32s, as the wasm VM will use a BigInt where - // an i64 is used. -+// If WASM_BIGINT is present, the default minimum browser versions increase to -+// Safari v15.0, Firefox v68, and Edge v79. It is possible to use WASM_BIGINT -+// with Safari >= v14.0, in that case Emscripten will polyfill BigInt64Array. -+// Use `-sMIN_SAFARI_VERSION=140000` to request this. - // [link] - var WASM_BIGINT = false; - -diff --git a/src/shell.js b/src/shell.js -index 22fac7f69..9d7558340 100644 ---- a/src/shell.js -+++ b/src/shell.js -@@ -51,7 +51,12 @@ var Module = typeof {{{ EXPORT_NAME }}} != 'undefined' ? {{{ EXPORT_NAME }}} : { - #if MIN_CHROME_VERSION < 45 || MIN_EDGE_VERSION < 12 || MIN_FIREFOX_VERSION < 34 || MIN_IE_VERSION != TARGET_NOT_SUPPORTED || MIN_SAFARI_VERSION < 90000 - #include "polyfill/objassign.js" - #endif --#endif // POLYFILL -+#endif -+ -+// See https://caniuse.com/mdn-javascript_builtins_bigint64array -+#if WASM_BIGINT && MIN_SAFARI_VERSION < 150000 -+#include "polyfill/bigint64array.js" -+#endif // MIN_SAFARI_VERSION < 15000// POLYFILL - - #if MODULARIZE - // Set up the promise that indicates the Module is initialized --- -2.25.1 - diff --git a/emsdk/patches/0002-Fix-dup-again.patch b/emsdk/patches/0002-Fix-dup-again.patch new file mode 100644 index 000000000..b5db386cf --- /dev/null +++ b/emsdk/patches/0002-Fix-dup-again.patch @@ -0,0 +1,88 @@ +From e6d94de69535b7dfa1941655217e1410199ef059 Mon Sep 17 00:00:00 2001 +From: Hood Chatham +Date: Wed, 8 Jun 2022 22:06:54 -0700 +Subject: [PATCH 2/2] Fix dup again + +https://github.com/emscripten-core/emscripten/pull/17184 +--- + src/library_fs.js | 16 +++++++++++++--- + tests/unistd/dup.c | 10 ++++++++++ + 2 files changed, 23 insertions(+), 3 deletions(-) + +diff --git a/src/library_fs.js b/src/library_fs.js +index 88f3bd98c..1e768763b 100644 +--- a/src/library_fs.js ++++ b/src/library_fs.js +@@ -403,29 +403,39 @@ FS.staticInit();` + + FS.FSStream = /** @constructor */ function() { + this.shared = { }; + }; +- FS.FSStream.prototype = { ++ FS.FSStream.prototype = {}; ++ Object.defineProperties(FS.FSStream.prototype, { + object: { ++ /** @this {FS.FSStream} */ + get: function() { return this.node; }, ++ /** @this {FS.FSStream} */ + set: function(val) { this.node = val; } + }, + isRead: { ++ /** @this {FS.FSStream} */ + get: function() { return (this.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_WRONLY') }}}; } + }, + isWrite: { ++ /** @this {FS.FSStream} */ + get: function() { return (this.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_RDONLY') }}}; } + }, + isAppend: { ++ /** @this {FS.FSStream} */ + get: function() { return (this.flags & {{{ cDefine('O_APPEND') }}}); } + }, + flags: { ++ /** @this {FS.FSStream} */ + get: function() { return this.shared.flags; }, ++ /** @this {FS.FSStream} */ + set: function(val) { this.shared.flags = val; }, + }, + position : { +- get function() { return this.shared.position; }, ++ /** @this {FS.FSStream} */ ++ get: function() { return this.shared.position; }, ++ /** @this {FS.FSStream} */ + set: function(val) { this.shared.position = val; }, + }, +- }; ++ }); + } + // clone it, so we can return an instance of FSStream + stream = Object.assign(new FS.FSStream(), stream); +diff --git a/tests/unistd/dup.c b/tests/unistd/dup.c +index c238678d3..814df5a25 100644 +--- a/tests/unistd/dup.c ++++ b/tests/unistd/dup.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + + int main() { +@@ -59,5 +60,14 @@ int main() { + read(g, buf, 5); + // should print "buf: abc\n" + printf("buf: %s\n", buf); ++ ++ ++ int fd1 = open("./blah.txt", O_RDWR | O_CREAT | O_EXCL, 0600); ++ int fd2 = dup(fd1); ++ int n = write(fd1, "abcabc\n", 7); ++ assert(n == 7); ++ assert(lseek(fd1, 0, SEEK_CUR) == 7); ++ assert(lseek(fd2, 0, SEEK_CUR) == 7); ++ + return 0; + } +-- +2.25.1 + diff --git a/emsdk/patches/0003-Fix-dup-again.patch b/emsdk/patches/0003-Fix-dup-again.patch deleted file mode 100644 index 6486f80c6..000000000 --- a/emsdk/patches/0003-Fix-dup-again.patch +++ /dev/null @@ -1,75 +0,0 @@ -From cedb7b1a5a341103707da7fbea435a7f4ed719f1 Mon Sep 17 00:00:00 2001 -From: Hood Chatham -Date: Wed, 8 Jun 2022 22:06:54 -0700 -Subject: [PATCH 3/4] Fix dup again - ---- - src/library_fs.js | 40 ++++++++++++++++++++++++++-------------- - 1 file changed, 26 insertions(+), 14 deletions(-) - -diff --git a/src/library_fs.js b/src/library_fs.js -index 88f3bd98c..693a1988a 100644 ---- a/src/library_fs.js -+++ b/src/library_fs.js -@@ -400,32 +400,44 @@ FS.staticInit();` + - // SOCKFS is completed. - createStream: (stream, fd_start, fd_end) => { - if (!FS.FSStream) { -- FS.FSStream = /** @constructor */ function() { -- this.shared = { }; -+ FS.FSStream = function FSStream() { -+ this.shared = {flags : 0, position : 0}; - }; -- FS.FSStream.prototype = { -+ FS.FSStream.prototype = Object.create(Object.prototype); -+ FS.FSStream.prototype.constructor = FS.FSStream; -+ Object.defineProperties(FS.FSStream.prototype, { - object: { -- get: function() { return this.node; }, -- set: function(val) { this.node = val; } -+ get: function () { -+ return this.node; -+ }, -+ set: function (val) { -+ this.node = val; -+ }, -+ enumerable : true, - }, - isRead: { -- get: function() { return (this.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_WRONLY') }}}; } -+ get: function() { return (this.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_WRONLY') }}}; }, -+ enumerable : true, - }, - isWrite: { -- get: function() { return (this.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_RDONLY') }}}; } -+ get: function() { return (this.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_RDONLY') }}}; }, -+ enumerable : true, - }, - isAppend: { -- get: function() { return (this.flags & {{{ cDefine('O_APPEND') }}}); } -+ get: function() { return (this.flags & {{{ cDefine('O_APPEND') }}}); }, -+ enumerable : true, - }, - flags: { -- get: function() { return this.shared.flags; }, -- set: function(val) { this.shared.flags = val; }, -+ get: function () { return this.shared.flags; }, -+ set: function (val) { this.shared.flags = val; }, -+ enumerable : true, - }, -- position : { -- get function() { return this.shared.position; }, -- set: function(val) { this.shared.position = val; }, -+ position: { -+ get: function() { return this.shared.position; }, -+ set: function (val) { this.shared.position = val; }, -+ enumerable : true, - }, -- }; -+ }); - } - // clone it, so we can return an instance of FSStream - stream = Object.assign(new FS.FSStream(), stream); --- -2.25.1 -