Skip to content

Add experimental support for the proposed JS base64 API #24168

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

Merged
merged 1 commit into from
Apr 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions site/source/docs/tools_reference/settings_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
Emscripten Compiler Settings
============================

The following is a complete list of settings that can be passed
to emscripten via ``-s`` on the command line. For example
``-sASSERTIONS`` or ``-sASSERTIONS=0``. For more details see the
:ref:`emcc <emcc-s-option-value>` documentation.
The following is a complete list of settings that can be passed to emscripten
via ``-s`` on the command line. For example ``-sASSERTIONS`` or
``-sASSERTIONS=0``. For more details see the :ref:`emcc <emcc-s-option-value>`
documentation.

Unless otherwise noted these settings only apply when linking
and have no effect during compilation.
Unless otherwise noted these settings only apply when linking and have no effect
during compilation.

.. Auto-generated by update_settings_docs.py. **DO NOT EDIT**

Expand Down Expand Up @@ -3355,3 +3355,17 @@ Experimental support for wasm ESM integration.
Requires EXPORT_ES6 and MODULARIZE=instance

Default value: false

.. _js_base64_api:

JS_BASE64_API
=============

Enable use of the JS arraybuffer-base64 API:
https://github.com/tc39/proposal-arraybuffer-base64
To run the resulting code currently requires passing `--js_base_64` to node
or chrome.

.. note:: This is an experimental setting

Default value: false
4 changes: 4 additions & 0 deletions src/lib/libbase64.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ addToLibrary({
`,
$base64Decode__docs: '/** @noinline */',
$base64Decode: (b64) => {
#if JS_BASE64_API
return Uint8Array.fromBase64(b64);
#else
#if ENVIRONMENT_MAY_BE_NODE
if (ENVIRONMENT_IS_NODE) {
var buf = Buffer.from(b64, 'base64');
Expand All @@ -42,5 +45,6 @@ addToLibrary({
output[j+2] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];
}
return output;
#endif
},
});
8 changes: 8 additions & 0 deletions src/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -2193,6 +2193,14 @@ var SOURCE_PHASE_IMPORTS = false;
// [link]
var WASM_ESM_INTEGRATION = false;

// Enable use of the JS arraybuffer-base64 API:
// https://github.com/tc39/proposal-arraybuffer-base64
// To run the resulting code currently requires passing `--js_base_64` to node
// or chrome.
// [experimental]
// [link]
var JS_BASE64_API = false;

// For renamed settings the format is:
// [OLD_NAME, NEW_NAME]
// For removed settings (which now effectively have a fixed value and can no
Expand Down
11 changes: 11 additions & 0 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -16017,3 +16017,14 @@ def test_locate_file_abspath_esm(self, args):
output_suffix='.mjs',
emcc_args=['--pre-js', 'pre.js',
'--extern-post-js', test_file('modularize_post_js.js')] + args)

@requires_node_canary
def test_js_base64_api(self):
self.node_args += ['--js_base_64']
self.do_runf('hello_world.c', 'hello, world!', emcc_args=['-sSINGLE_FILE'], output_basename='baseline')
self.do_runf('hello_world.c', 'hello, world!', emcc_args=['-sSINGLE_FILE', '-sJS_BASE64_API', '-Wno-experimental'])
# We expect the resulting JS file to be smaller because it doesn't contain the
# base64 decoding code
baseline_size = os.path.getsize('baseline.js')
js_api_size = os.path.getsize('hello_world.js')
self.assertLess(js_api_size, baseline_size)
3 changes: 3 additions & 0 deletions tools/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,9 @@ def phase_linker_setup(options, linker_args): # noqa: C901, PLR0912, PLR0915
if options.oformat == OFormat.MJS:
default_setting('EXPORT_ES6', 1)

if settings.JS_BASE64_API:
diagnostics.warning('experimental', '-sJS_BASE64_API is still experimental and not yet supported in browsers')

if settings.WASM_ESM_INTEGRATION:
diagnostics.warning('experimental', '-sWASM_ESM_INTEGRATION is still experimental and not yet supported in browsers')
default_setting('EXPORT_ES6', 1)
Expand Down
12 changes: 6 additions & 6 deletions tools/maint/update_settings_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@
Emscripten Compiler Settings
============================

The following is a complete list of settings that can be passed
to emscripten via ``-s`` on the command line. For example
``-sASSERTIONS`` or ``-sASSERTIONS=0``. For more details see the
:ref:`emcc <emcc-s-option-value>` documentation.
The following is a complete list of settings that can be passed to emscripten
via ``-s`` on the command line. For example ``-sASSERTIONS`` or
``-sASSERTIONS=0``. For more details see the :ref:`emcc <emcc-s-option-value>`
documentation.

Unless otherwise noted these settings only apply when linking
and have no effect during compilation.
Unless otherwise noted these settings only apply when linking and have no effect
during compilation.

.. Auto-generated by update_settings_docs.py. **DO NOT EDIT**
'''
Expand Down