Skip to content

Commit cadac51

Browse files
authored
Add experimental support for the JS base64 API (#24168)
See https://github.com/tc39/proposal-arraybuffer-base64
1 parent 5ab7f5e commit cadac51

File tree

6 files changed

+52
-12
lines changed

6 files changed

+52
-12
lines changed

site/source/docs/tools_reference/settings_reference.rst

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
Emscripten Compiler Settings
55
============================
66

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

12-
Unless otherwise noted these settings only apply when linking
13-
and have no effect during compilation.
12+
Unless otherwise noted these settings only apply when linking and have no effect
13+
during compilation.
1414

1515
.. Auto-generated by update_settings_docs.py. **DO NOT EDIT**
1616
@@ -3355,3 +3355,17 @@ Experimental support for wasm ESM integration.
33553355
Requires EXPORT_ES6 and MODULARIZE=instance
33563356

33573357
Default value: false
3358+
3359+
.. _js_base64_api:
3360+
3361+
JS_BASE64_API
3362+
=============
3363+
3364+
Enable use of the JS arraybuffer-base64 API:
3365+
https://github.com/tc39/proposal-arraybuffer-base64
3366+
To run the resulting code currently requires passing `--js_base_64` to node
3367+
or chrome.
3368+
3369+
.. note:: This is an experimental setting
3370+
3371+
Default value: false

src/lib/libbase64.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ addToLibrary({
2222
`,
2323
$base64Decode__docs: '/** @noinline */',
2424
$base64Decode: (b64) => {
25+
#if JS_BASE64_API
26+
return Uint8Array.fromBase64(b64);
27+
#else
2528
#if ENVIRONMENT_MAY_BE_NODE
2629
if (ENVIRONMENT_IS_NODE) {
2730
var buf = Buffer.from(b64, 'base64');
@@ -42,5 +45,6 @@ addToLibrary({
4245
output[j+2] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];
4346
}
4447
return output;
48+
#endif
4549
},
4650
});

src/settings.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2193,6 +2193,14 @@ var SOURCE_PHASE_IMPORTS = false;
21932193
// [link]
21942194
var WASM_ESM_INTEGRATION = false;
21952195

2196+
// Enable use of the JS arraybuffer-base64 API:
2197+
// https://github.com/tc39/proposal-arraybuffer-base64
2198+
// To run the resulting code currently requires passing `--js_base_64` to node
2199+
// or chrome.
2200+
// [experimental]
2201+
// [link]
2202+
var JS_BASE64_API = false;
2203+
21962204
// For renamed settings the format is:
21972205
// [OLD_NAME, NEW_NAME]
21982206
// For removed settings (which now effectively have a fixed value and can no

test/test_other.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16017,3 +16017,14 @@ def test_locate_file_abspath_esm(self, args):
1601716017
output_suffix='.mjs',
1601816018
emcc_args=['--pre-js', 'pre.js',
1601916019
'--extern-post-js', test_file('modularize_post_js.js')] + args)
16020+
16021+
@requires_node_canary
16022+
def test_js_base64_api(self):
16023+
self.node_args += ['--js_base_64']
16024+
self.do_runf('hello_world.c', 'hello, world!', emcc_args=['-sSINGLE_FILE'], output_basename='baseline')
16025+
self.do_runf('hello_world.c', 'hello, world!', emcc_args=['-sSINGLE_FILE', '-sJS_BASE64_API', '-Wno-experimental'])
16026+
# We expect the resulting JS file to be smaller because it doesn't contain the
16027+
# base64 decoding code
16028+
baseline_size = os.path.getsize('baseline.js')
16029+
js_api_size = os.path.getsize('hello_world.js')
16030+
self.assertLess(js_api_size, baseline_size)

tools/link.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,9 @@ def phase_linker_setup(options, linker_args): # noqa: C901, PLR0912, PLR0915
784784
if options.oformat == OFormat.MJS:
785785
default_setting('EXPORT_ES6', 1)
786786

787+
if settings.JS_BASE64_API:
788+
diagnostics.warning('experimental', '-sJS_BASE64_API is still experimental and not yet supported in browsers')
789+
787790
if settings.WASM_ESM_INTEGRATION:
788791
diagnostics.warning('experimental', '-sWASM_ESM_INTEGRATION is still experimental and not yet supported in browsers')
789792
default_setting('EXPORT_ES6', 1)

tools/maint/update_settings_docs.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@
3434
Emscripten Compiler Settings
3535
============================
3636
37-
The following is a complete list of settings that can be passed
38-
to emscripten via ``-s`` on the command line. For example
39-
``-sASSERTIONS`` or ``-sASSERTIONS=0``. For more details see the
40-
:ref:`emcc <emcc-s-option-value>` documentation.
37+
The following is a complete list of settings that can be passed to emscripten
38+
via ``-s`` on the command line. For example ``-sASSERTIONS`` or
39+
``-sASSERTIONS=0``. For more details see the :ref:`emcc <emcc-s-option-value>`
40+
documentation.
4141
42-
Unless otherwise noted these settings only apply when linking
43-
and have no effect during compilation.
42+
Unless otherwise noted these settings only apply when linking and have no effect
43+
during compilation.
4444
4545
.. Auto-generated by update_settings_docs.py. **DO NOT EDIT**
4646
'''

0 commit comments

Comments
 (0)