emscripten-core / emscripten-core/emscripten

Some Emscripten's .js libraries are only compatible with closure `--language-in UNSTABLE` due to public class fields

Open
#23,179 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

Description

We try to update Emscripten, but found out that there's some issues with Emscripten with Closure. It all relates to the use of public class fields in JavaScript libraries that are compiled by Closure.

Failing Godot build log (ignore "Bad type annotation." errors)

```
❯ scons target=template_release platform=web use_closure_compiler=yes
scons: Reading SConscript files ...
SCons cache enabled... (path: ".scons_cache__master__web__template_release")
Current cache limit is 5.0 GiB (used: 4.97 GiB)
Auto-detected 16 CPU cores available for build parallelism. Using 15 cores by default. You can override it with the `-j` or `num_jobs` arguments.
SCU: Generating build files... (max includes per SCU: 8)
Building for platform "web", architecture "wasm32", target "template_release".
Checking for C header file mntent.h... (cached) yes
scons: done reading SConscript files.
scons: Building targets ...
[ 84%] em++ -o bin/godot.web.template_release.wasm32.nothreads.js -sASSERTIONS=1 -sINITIAL_MEMORY=32MB --closure 1 -sMAX_WEBGL_VERSION=2 -sOFFSCREEN_FRAMEBUFFER=1 -sGL_ENABLE_GET_PROC_ADDRESS=0 -sSTACK_SIZE=5120KB -sWASM_BIGINT -sENVIRONMENT=web,worker -sMODULARIZE=1 -sEXPORT_NAME='Godot' -sSUPPORT_LONGJMP='wasm' -sALLOW_MEMORY_GROWTH=1 -sINVOKE_RUN=0 -sEXPORTED_RUNTIME_METHODS=['callMain','cwrap'] -sEXIT_RUNTIME=1 -sGL_WORKAROUND_SAFARI_GETCONTEXT_BUG=0 -s -Os --js-library /Users/adamscott/dev/builds/godot/modules/webxr/native/library_godot_webxr.js --js-library /Users/adamscott/dev/builds/godot/modules/websocket/library_godot_websocket.js --js-library /Users/adamscott/dev/builds/godot/modules/webrtc/library_godot_webrtc.js --js-library /Users/adamscott/dev/builds/godot/platform/web/js/libs/library_godot_audio.js --js-library /Users/adamscott/dev/builds/godot/platform/web/js/libs/library_godot_display.js --js-library /Users/adamscott/dev/builds/godot/platform/web/js/libs/library_godot_fetch.js --js-library /Users/adamscott/dev/builds/godot/platform/web/js/libs/library_godot_os.js --js-library /Users/adamscott/dev/builds/godot/platform/web/js/libs/library_godot_runtime.js --js-library /Users/adamscott/dev/builds/godot/platform/web/js/libs/library_godot_input.js --js-library /Users/adamscott/dev/builds/godot/platform/web/js/libs/library_godot_webgl2.js --js-library /Users/adamscott/dev/builds/godot/platform/web/js/libs/library_godot_javascript_singleton.js platform/web/audio_driver_web.web.template_release.wasm32.nothreads.o platform/web/display_server_web.web.template_release.wasm32.nothreads.o platform/web/http_client_web.web.template_release.wasm32.nothreads.o platform/web/javascript_bridge_singleton.web.template_release.wasm32.nothreads.o platform/web/web_main.web.template_release.wasm32.nothreads.o platform/web/os_web.web.template_release.wasm32.nothreads.o platform/web/web_runtime.web.template_release.wasm32.nothreads.o main/libmain.web.template_release.wasm32.nothreads.a modules/libmodules.web.template_release.wasm32.nothreads.a modules/libmodule_ktx.web.template_release.wasm32.nothreads.a modules/libmodule_msdfgen.web.template_release.wasm32.nothreads.a modules/libmodule_theora.web.template_release.wasm32.nothreads.a modules/libmodule_vorbis.web.template_release.wasm32.nothreads.a modules/libmodule_basis_universal.web.template_release.wasm32.nothreads.a modules/libmodule_bcdec.web.template_release.wasm32.nothreads.a modules/libmodule_bmp.web.template_release.wasm32.nothreads.a modules/libmodule_csg.web.template_release.wasm32.nothreads.a modules/libmodule_dds.web.template_release.wasm32.nothreads.a modules/libmodule_enet.web.template_release.wasm32.nothreads.a modules/libmodule_fbx.web.template_release.wasm32.nothreads.a modules/libmodule_freetype.web.template_release.wasm32.nothreads.a modules/libmodule_gdscript.web.template_release.wasm32.nothreads.a modules/libmodule_gltf.web.template_release.wasm32.nothreads.a modules/libmodule_godot_physics_2d.web.template_release.wasm32.nothreads.a modules/libmodule_godot_physics_3d.web.template_release.wasm32.nothreads.a modules/libmodule_gridmap.web.template_release.wasm32.nothreads.a modules/libmodule_hdr.web.template_release.wasm32.nothreads.a modules/libmodule_interactive_music.web.template_release.wasm32.nothreads.a modules/libmodule_jolt_physics.web.template_release.wasm32.nothreads.a modules/libmodule_jpg.web.template_release.wasm32.nothreads.a modules/libmodule_jsonrpc.web.template_release.wasm32.nothreads.a modules/libmodule_mbedtls.web.template_release.wasm32.nothreads.a modules/libmodule_meshoptimizer.web.template_release.wasm32.nothreads.a modules/libmodule_minimp3.web.template_release.wasm32.nothreads.a modules/libmodule_mobile_vr.web.template_release.wasm32.nothreads.a modules/libmodule_multiplayer.web.template_release.wasm32.nothreads.a modules/libmodule_navigation.web.template_release.wasm32.nothreads.a modules/libmodule_noise.web.template_release.wasm32.nothreads.a modules/libmodule_ogg.web.template_release.wasm32.nothreads.a modules/libmodule_regex.web.template_release.wasm32.nothreads.a modules/libmodule_svg.web.template_release.wasm32.nothreads.a modules/libmodule_text_server_adv.web.template_release.wasm32.nothreads.a modules/libmodule_tga.web.template_release.wasm32.nothreads.a modules/libmodule_upnp.web.template_release.wasm32.nothreads.a modules/libmodule_vhacd.web.template_release.wasm32.nothreads.a modules/libmodule_webp.web.template_release.wasm32.nothreads.a modules/libmodule_webrtc.web.template_release.wasm32.nothreads.a modules/libmodule_websocket.web.template_release.wasm32.nothreads.a modules/libmodule_webxr.web.template_release.wasm32.nothreads.a modules/libmodule_zip.web.template_release.wasm32.nothreads.a platform/libplatform.web.template_release.wasm32.nothreads.a drivers/libdrivers.web.template_release.wasm32.nothreads.a scene/libscene.web.template_release.wasm32.nothreads.a servers/libservers.web.template_release.wasm32.nothreads.a core/libcore.web.template_release.wasm32.nothreads.a modules/text_server_adv/libharfbuzz_builtin.web.template_release.wasm32.nothreads.a modules/text_server_adv/libgraphite_builtin.web.template_release.wasm32.nothreads.a modules/text_server_adv/libicu_builtin.web.template_release.wasm32.nothreads.a modules/freetype/libfreetype_builtin.web.template_release.wasm32.nothreads.a modules/msdfgen/libmsdfgen_builtin.web.template_release.wasm32.nothreads.a -lidbfs.js
[100%] Building node count database .scons_node_count
[100%] Building compilation database compile_commands.json
[100%] building:ERROR: Closure compiler run failed:

building:ERROR: /var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js:8359:38: WARNING - [JSC_TYPE_PARSE_ERROR] Bad type annotation. missing closing ] See https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler for more information.
8359| * @param {SampleOptions} [options={{}}] Optional params
^

/var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js:8376:38: WARNING - [JSC_TYPE_PARSE_ERROR] Bad type annotation. missing closing ] See https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler for more information.
8376| * @param {SampleOptions} [options={{}}] Optional params
^

/var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js:8569:42: WARNING - [JSC_TYPE_PARSE_ERROR] Bad type annotation. missing closing ] See https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler for more information.
8569| * @param {SampleNodeOptions} [options={{}}] Optional params
^

/var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js:804:2: ERROR - [JSC_LANGUAGE_FEATURE] This language feature is only supported for UNSTABLE mode or better: Public class fields.
804| name="ExitStatus";
^

/var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js:2307:4: ERROR - [JSC_LANGUAGE_FEATURE] This language feature is only supported for UNSTABLE mode or better: Public class fields.
2307| name="ErrnoError";
^

/var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js:2329:4: ERROR - [JSC_LANGUAGE_FEATURE] This language feature is only supported for UNSTABLE mode or better: Public class fields.
2329| shared={};
^

/var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js:2331:4: ERROR - [JSC_LANGUAGE_FEATURE] This language feature is only supported for UNSTABLE mode or better: Public class fields.
2331| node=null;
^

/var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js:2361:4: ERROR - [JSC_LANGUAGE_FEATURE] This language feature is only supported for UNSTABLE mode or better: Public class fields.
2361| node_ops={};
^

/var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js:2362:4: ERROR - [JSC_LANGUAGE_FEATURE] This language feature is only supported for UNSTABLE mode or better: Public class fields.
2362| stream_ops={};
^

/var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js:2363:4: ERROR - [JSC_LANGUAGE_FEATURE] This language feature is only supported for UNSTABLE mode or better: Public class fields.
2363| readMode=292 | 73;
^

/var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js:2364:4: ERROR - [JSC_LANGUAGE_FEATURE] This language feature is only supported for UNSTABLE mode or better: Public class fields.
2364| writeMode=146;
^

/var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js:2365:4: ERROR - [JSC_LANGUAGE_FEATURE] This language feature is only supported for UNSTABLE mode or better: Public class fields.
2365| mounted=null;
^

/var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js:3731:6: ERROR - [JSC_LANGUAGE_FEATURE] This language feature is only supported for UNSTABLE mode or better: Public class fields.
3731| lengthKnown=false;
^

/var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js:3732:6: ERROR - [JSC_LANGUAGE_FEATURE] This language feature is only supported for UNSTABLE mode or better: Public class fields.
3732| chunks=[];
^

/var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js:3735:6: ERROR - [JSC_LANGUAGE_FEATURE] This language feature is only supported for UNSTABLE mode or better: Public class fields.
3735| getter=undefined;
^

/var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js:3736:6: ERROR - [JSC_LANGUAGE_FEATURE] This language feature is only supported for UNSTABLE mode or better: Public class fields.
3736| _length=0;
^

/var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js:3737:6: ERROR - [JSC_LANGUAGE_FEATURE] This language feature is only supported for UNSTABLE mode or better: Public class fields.
3737| _chunkSize=0;
^

14 error(s), 3 warning(s)

em++: error: closure compiler failed (rc: 14): /Users/adamscott/dev/builds/emsdk/node/20.18.0_64bit/bin/node --max_old_space_size=8192 /Users/adamscott/dev/builds/emsdk/upstream/emscripten/node_modules/.bin/google-closure-compiler --compilation_level ADVANCED_OPTIMIZATIONS --language_in UNSTABLE --language_out NO_TRANSPILE --emit_use_strict=false --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/src/closure-externs/closure-externs.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/src/closure-externs/modularize-externs.js --language_in ECMASCRIPT_2021 --externs /Users/adamscott/dev/builds/godot/modules/webxr/native/webxr.externs.js --externs /Users/adamscott/dev/builds/godot/platform/web/js/libs/library_godot_webgl2.externs.js --js /var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_8xbutj_k/godot.web.template_release.wasm32.nothreads.jso1.js --js_output_file tmp7lhm9jqe.cc.js the error message may be clearer with -g1 and EMCC_DEBUG=2 set
scons: *** [bin/godot.web.template_release.wasm32.nothreads.js] Error 1
scons: building terminated because of errors.
[Time elapsed: 00:00:50.55]
Purging 1 text file from cache...

```

**Not reproducible in:** 3.1.62, 3.1.70
**Reproducible in:** 3.1.71, 3.1.74

### Steps to reproduce

1. Unzip [closure.zip](https://github.com/user-attachments/files/18155825/closure.zip) (a minimal reproduction project)
2. Open that directory in a terminal
3. Run `EMCC_CLOSURE_ARGS="--language_in ECMASCRIPT_2021" emmake make`
4. See that closure complains.

Closure complaints

```
❯ EMCC_CLOSURE_ARGS="--language_in ECMASCRIPT_2021" emmake make
make: make
emcc main.c --closure 1 --bind -s ASSERTIONS=1 -s MODULARIZE=1 -s EXPORT_NAME="'HelloWorld'" -s WASM=1 -s AGGRESSIVE_VARIABLE_ELIMINATION=1 -s INLINING_LIMIT=1 -s NO_EXIT_RUNTIME=1 -s EXPORTED_FUNCTIONS="['_main']" -lexceptions.js -std=c23 -O3 -o main.wasm.js
building:ERROR: Closure compiler run failed:

building:ERROR: /var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_ubzw6ekg/main.wasm.jso1.js:881:2: ERROR - [JSC_LANGUAGE_FEATURE] This language feature is only supported for UNSTABLE mode or better: Public class fields.
881| name="ExitStatus";
^

1 error(s), 0 warning(s)

emcc: error: closure compiler failed (rc: 1): /Users/adamscott/dev/builds/emsdk/node/20.18.0_64bit/bin/node --max_old_space_size=8192 /Users/adamscott/dev/builds/emsdk/upstream/emscripten/node_modules/.bin/google-closure-compiler --compilation_level ADVANCED_OPTIMIZATIONS --language_in UNSTABLE --language_out NO_TRANSPILE --emit_use_strict=false --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/src/closure-externs/closure-externs.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/src/closure-externs/modularize-externs.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/src/closure-externs/node-externs.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/net.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/events.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/repl.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/util.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/dgram.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/vm.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/stream.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/child_process.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/core.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/os.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/readline.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/punycode.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/https.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/domain.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/dns.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/tty.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/querystring.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/path.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/string_decoder.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/cluster.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/zlib.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/url.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/tls.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/process.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/http.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/buffer.js --externs /Users/adamscott/dev/builds/emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/fs.js --language_in ECMASCRIPT_2021 --js /var/folders/68/jzztkd794zn93hqll8l7lryw0000gn/T/emscripten_temp_ubzw6ekg/main.wasm.jso1.js --js_output_file tmpjz_db2m6.cc.js the error message may be clearer with -g1 and EMCC_DEBUG=2 set
make: *** [all] Error 1
emmake: error: 'make' failed (returned 2)
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.