Skip to content
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

Copy the wasm exports object if we intend to modify it #8950

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
70 changes: 6 additions & 64 deletions .circleci/config.yml
Expand Up @@ -47,7 +47,7 @@ test-firefox: &test-firefox
- run:
name: download firefox
command: |
FF_VERSION=65.0.2
FF_VERSION=68.0
wget https://download-installer.cdn.mozilla.net/pub/firefox/releases/$FF_VERSION/linux-x86_64/en-US/firefox-$FF_VERSION.tar.bz2
tar xf firefox-$FF_VERSION.tar.bz2
# wget -O nightly.tar.bz2 "https://download.mozilla.org/?product=firefox-nightly-latest-ssl&os=linux64&lang=en-US"
Expand Down Expand Up @@ -152,21 +152,22 @@ test-chrome: &test-chrome
name: install package dependencies
command: |
apt-get update -q
# install chromium-browser in order to ensure we have most of the
# install chromium-browser temporarily in order to ensure we have most of the
# dependecies for chrome.
EXTRA_CHROME_DEPS="lsb-release fonts-liberation libappindicator3-1"
apt-get install -q -y unzip xvfb chromium-browser openjdk-8-jre-headless $EXTRA_CHROME_DEPS
apt-get remove -q -y chromium-browser
- run:
name: download chrome
command: |
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
dpkg -i google-chrome-stable_current_amd64.deb
wget https://dl.google.com/linux/direct/google-chrome-unstable_current_amd64.deb
dpkg -i google-chrome-unstable_current_amd64.deb
- run:
name: run tests
command: |
# --no-sandbox becasue we are running as root and chrome requires
# this flag for now: https://crbug.com/638180
CHROME_FLAGS_BASE="--no-first-run -start-maximized --no-sandbox --use-gl=swiftshader"
CHROME_FLAGS_BASE="--no-first-run -start-maximized --no-sandbox --use-gl=swiftshader --javascript-harmony --enable-experimental-web-platform-features"
CHROME_FLAGS_WASM="--enable-features=WebAssembly --enable-features=SharedArrayBuffer --disable-features=WebAssemblyTrapHandler --js-flags=\"--experimental-wasm-threads --harmony-sharedarraybuffer --no-wasm-disable-structured-cloning\""
export EMTEST_BROWSER="xvfb-run -a -e /dev/stdout /usr/bin/google-chrome-stable $CHROME_FLAGS_BASE $CHROME_FLAGS_WASM"
export EMTEST_LACKS_GRAPHICS_HARDWARE=1
Expand Down Expand Up @@ -400,73 +401,14 @@ workflows:

build-test:
jobs:
- flake8
- build-docs
- build
- test-other:
requires:
- build
- test-browser-firefox:
requires:
- build
- test-browser-chrome:
requires:
- build
- test-ab:
requires:
- build
- test-c:
requires:
- build
- test-d:
requires:
- build
- test-e:
requires:
- build
- test-f:
requires:
- build
- test-ghi:
requires:
- build
- test-jklmno:
requires:
- build
- test-p:
requires:
- build
- test-qrst:
requires:
- build
- test-uvwxyz:
requires:
- build
- test-wasm0:
requires:
- build
- test-wasm1:
requires:
- build
- test-wasm2:
requires:
- build
- test-wasm3:
requires:
- build
- test-sanity:
requires:
- build
- build-upstream
- test-upstream-wasm0:
requires:
- build-upstream
- test-upstream-wasm2:
requires:
- build-upstream
- test-upstream-other:
requires:
- build-upstream
- test-upstream-browser-chrome:
requires:
- build-upstream
Expand Down
5 changes: 0 additions & 5 deletions emscripten.py
Expand Up @@ -1707,11 +1707,6 @@ def create_receiving(function_table_data, function_tables_defs, exported_impleme

shared.Settings.MODULE_EXPORTS = module_exports = exported_implemented_functions + function_tables(function_table_data)

# Currently USE PTHREADS + EXPORT ES6 doesn't work with the previously generated assertions.
# ES6 modules disallow re-assigning read-only properties.
if shared.Settings.USE_PTHREADS and shared.Settings.EXPORT_ES6 and shared.Settings.ASSERTIONS and receiving:
receiving = "assert(!ENVIRONMENT_IS_PTHREAD, 'Error: USE_PTHREADS and EXPORT_ES6 requires ASSERTIONS=0');\n" + receiving

if not shared.Settings.SWAPPABLE_ASM_MODULE:
if shared.Settings.DECLARE_ASM_MODULE_EXPORTS:
imported_exports = [s for s in module_exports if s not in initializers]
Expand Down
9 changes: 9 additions & 0 deletions src/preamble.js
@@ -1,3 +1,4 @@
if (typeof log === 'function') log('premalbe');
// === Preamble library stuff ===

// Documentation for the public APIs defined in this file must be updated in:
Expand Down Expand Up @@ -975,6 +976,14 @@ function createWasm(env) {
// performing other necessary setup
function receiveInstance(instance, module) {
var exports = instance.exports;
// We want to modify the exports in some cases, however, in ES6 environments that
// may be illegal as the wasm exports are an ES6 export object, which is read-only.
// To work around that, we simply make a copy of them.
#if EXPORT_ES6 && (ASSERTIONS || BYSYNCIFY)
var originalExports = exports;
kripken marked this conversation as resolved.
Show resolved Hide resolved
exports = {};
for (var x in originalExports) exports[x] = originalExports[x];
#endif
#if BYSYNCIFY
exports = Bysyncify.instrumentWasmExports(exports);
#endif
Expand Down
42 changes: 42 additions & 0 deletions tests/test_browser.py
Expand Up @@ -4716,3 +4716,45 @@ def test_minimal_runtime_loader_shell(self):
for modularize in [[], ['-s', 'MODULARIZE=1']]:
print(str(args + wasm + modularize))
self.btest('minimal_hello.c', '0', args=args + wasm + modularize)

def _test_es6(self, args):
args = args + ['-s', 'EXPORT_ES6', '-s', 'MODULARIZE', '-s', 'MODULARIZE_INSTANCE', '-s', 'ASSERTIONS', '-o', 'test.mjs']
print(args)
create_test_file('src.c', self.with_report_result(open(path_from_root('tests', 'browser_test_hello_world.c')).read()))
self.compile_btest(['src.c'] + args)
create_test_file('test.html', '''
<script>
var logs = 0;
function log(e) {
var xhr = new XMLHttpRequest();
xhr.open('GET', encodeURI('http://localhost:8888?stdout=' + e + ' : ' + new Error().stack + ' : ' + logs++));
xhr.send();
}
log('startup');
window.onerror = function(e) {
log(e);
};
</script>
<script type="module" src="test.mjs"></script>
<script>
log('after');
</script>
''')
self.run_browser('test.html', None, '/report_result?0')

def test_es6_O0(self):
self._test_es6([])

def test_es6_O3(self):
self._test_es6(['-O3'])

def test_es6_async(self):
self._test_es6(self.get_async_args())

@requires_threads
def test_es6_threads(self):
# TODO: use PROXY_TO_PTHREAD and/or '-s', 'PTHREAD_POOL_SIZE=1' once https://bugs.chromium.org/p/chromium/issues/detail?id=680046 is fixed
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should work on Chrome if --enable-experimental-web-platform-features is set (sorry, forgot to mention that).
The Firefox bug is also: https://bugzilla.mozilla.org/show_bug.cgi?id=1540913

# firefox also errors, "SyntaxError: dynamic module import is not implemented"
self._test_es6(['-s', 'USE_PTHREADS'])