-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Use fetch
rather than XMLHttpRequest
for downloading Wasm files
#22015
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
710e300
bcdaaa8
d882d42
24fa0cd
8b9355b
d4a2fa0
a83c297
61132ca
6165987
fbe17c1
68023c8
459df06
72d6a2b
ea85f33
b4a9154
3974389
16559db
1b07be5
feab2d6
bbff4bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -600,3 +600,4 @@ a license to everyone to use it as detailed in LICENSE.) | |
* YAMAMOTO Takashi <[email protected]> | ||
* Artur Gatin <[email protected]> (copyright owned by Teladoc Health, Inc.) | ||
* Christian Lloyd <[email protected]> (copyright owned by Teladoc Health, Inc.) | ||
* Sean Morris <[email protected]> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -700,7 +700,9 @@ def setup(assetLocalization): | |
<center><canvas id='canvas' width='256' height='256'></canvas></center> | ||
<hr><div id='output'></div><hr> | ||
<script type='text/javascript'> | ||
window.onerror = (error) => { | ||
const handler = (event) => { | ||
event.stopImmediatePropagation(); | ||
const error = String(event instanceof ErrorEvent ? event.message : (event.reason || event)); | ||
window.disableErrorReporting = true; | ||
window.onerror = null; | ||
var result = error.includes("test.data") ? 1 : 0; | ||
|
@@ -709,6 +711,8 @@ def setup(assetLocalization): | |
xhr.send(); | ||
setTimeout(function() { window.close() }, 1000); | ||
} | ||
window.addEventListener('error', handler); | ||
window.addEventListener('unhandledrejection', handler); | ||
sbc100 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
var Module = { | ||
locateFile: function (path, prefix) {if (path.endsWith(".wasm")) {return prefix + path;} else {return "''' + assetLocalization + r'''" + path;}}, | ||
print: (function() { | ||
|
@@ -5545,6 +5549,39 @@ def test_webpack(self): | |
shutil.copyfile('webpack/src/hello.wasm', 'webpack/dist/hello.wasm') | ||
self.run_browser('webpack/dist/index.html', '/report_result?exit:0') | ||
|
||
def test_fetch_polyfill_shared_lib(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we even need to involve shared libraries here since the polyfill is needed even to load the base wasm file (I think). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lgtm either way though since you've already gone to the trouble to writing the test. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think its good to have this test either way, that stuff could be changed in the future as the code becomes more unified. We should make sure the code works in all cases. |
||
create_file('library.c', r''' | ||
#include <stdio.h> | ||
int library_func() { | ||
return 42; | ||
} | ||
''') | ||
create_file('main.c', r''' | ||
#include <dlfcn.h> | ||
#include <stdio.h> | ||
int main() { | ||
void *lib_handle = dlopen("/library.so", RTLD_NOW); | ||
typedef int (*voidfunc)(); | ||
voidfunc x = (voidfunc)dlsym(lib_handle, "library_func"); | ||
return x(); | ||
} | ||
''') | ||
|
||
self.run_process([EMCC, 'library.c', '-sSIDE_MODULE', '-O2', '-o', 'library.so']) | ||
|
||
def test(args, expect_fail): | ||
self.compile_btest('main.c', ['-fPIC', 'library.so', '-sMAIN_MODULE=2', '-sEXIT_RUNTIME', '-o', 'a.out.html'] + args) | ||
if expect_fail: | ||
js = read_file('a.out.js') | ||
create_file('a.out.js', 'fetch = undefined;\n' + js) | ||
return self.run_browser('a.out.html', '/report_result?abort:TypeError') | ||
else: | ||
return self.run_browser('a.out.html', '/report_result?exit:42') | ||
|
||
test([], expect_fail=True) | ||
test(['-sLEGACY_VM_SUPPORT'], expect_fail=False) | ||
test(['-sLEGACY_VM_SUPPORT', '-sNO_POLYFILL'], expect_fail=True) | ||
|
||
|
||
class emrun(RunnerCore): | ||
def test_emrun_info(self): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also update the above two uses of
XMLHttpRequest
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the two earlier calls are synchronous, it might take some more re-engineering to get those converted.