From 32fbce89fd1bd1b92b3a32fec532315ccd379bd7 Mon Sep 17 00:00:00 2001 From: Sean Morris <640101+seanmorris@users.noreply.github.com> Date: Wed, 29 May 2024 21:23:22 -0400 Subject: [PATCH 01/43] Separating file packager fetch. --- src/polyfill/fetch.js | 80 +++++++++++++++++++++++++ src/shell.js | 5 ++ test/common.py | 2 +- test/test_browser.py | 132 ++++++++++++++++++++++++++++++++++++++++- tools/file_packager.py | 127 +++++++++++++++++++++------------------ 5 files changed, 286 insertions(+), 60 deletions(-) create mode 100644 src/polyfill/fetch.js diff --git a/src/polyfill/fetch.js b/src/polyfill/fetch.js new file mode 100644 index 0000000000000..979335699a84e --- /dev/null +++ b/src/polyfill/fetch.js @@ -0,0 +1,80 @@ +// Fetch polyfill from https://github.com/developit/unfetch +// License: +//============================================================================== +// Copyright (c) 2017 Jason Miller +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +//============================================================================== + +#if !POLYFILL +#error "this file should never be included unless POLYFILL is set" +#endif + +if (typeof globalThis.fetch == 'undefined') { + globalThis.fetch = function (url, options) { + options = options || {}; + return new Promise((resolve, reject) => { + const request = new XMLHttpRequest(); + const keys = []; + const headers = {}; + + request.responseType = 'arraybuffer'; + + const response = () => ({ + ok: ((request.status / 100) | 0) == 2, // 200-299 + statusText: request.statusText, + status: request.status, + url: request.responseURL, + text: () => Promise.resolve(request.responseText), + json: () => Promise.resolve(request.responseText).then(JSON.parse), + blob: () => Promise.resolve(new Blob([request.response])), + arrayBuffer: () => Promise.resolve(request.response), + clone: response, + headers: { + keys: () => keys, + entries: () => keys.map((n) => [n, request.getResponseHeader(n)]), + get: (n) => request.getResponseHeader(n), + has: (n) => request.getResponseHeader(n) != null, + }, + }); + + request.open(options.method || "get", url, true); + + request.onload = () => { + request + .getAllResponseHeaders() + .toLowerCase() + .replace(/^(.+?):/gm, (m, key) => { + headers[key] || keys.push((headers[key] = key)); + }); + resolve(response()); + }; + + request.onerror = reject; + + request.withCredentials = options.credentials == "include"; + + for (const i in options.headers) { + request.setRequestHeader(i, options.headers[i]); + } + + request.send(options.body || null); + }); + } +} diff --git a/src/shell.js b/src/shell.js index add93992b4960..e0e99753c067c 100644 --- a/src/shell.js +++ b/src/shell.js @@ -61,6 +61,11 @@ var Module = typeof {{{ EXPORT_NAME }}} != 'undefined' ? {{{ EXPORT_NAME }}} : { // See https://caniuse.com/mdn-javascript_builtins_bigint64array #include "polyfill/bigint64array.js" #endif + +#if MIN_CHROME_VERSION < 40 || MIN_FIREFOX_VERSION < 39 || MIN_SAFARI_VERSION < 103000 +// See https://caniuse.com/fetch +#include "polyfill/fetch.js" +#endif #endif // POLYFILL #if MODULARIZE diff --git a/test/common.py b/test/common.py index c19be77f01e00..a342524e42d30 100644 --- a/test/common.py +++ b/test/common.py @@ -2270,7 +2270,7 @@ def compile_btest(self, filename, args, reporting=Reporting.FULL): if reporting == Reporting.FULL: # If C reporting (i.e. the REPORT_RESULT macro) is required we # also include report_result.c and force-include report_result.h - self.run_process([EMCC, '-c', '-I' + TEST_ROOT, + self.run_process([EMCC, '-c', '-fPIC', '-I' + TEST_ROOT, '-DEMTEST_PORT_NUMBER=%d' % self.port, test_file('report_result.c')] + self.get_emcc_args(compile_only=True)) args += ['report_result.o', '-include', test_file('report_result.h')] diff --git a/test/test_browser.py b/test/test_browser.py index 957883dbe17cb..2164e15e821c9 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -699,7 +699,8 @@ def setup(assetLocalization):