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

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

Open
adamscott opened this issue Dec 16, 2024 · 3 comments

Comments

@adamscott
Copy link

adamscott commented Dec 16, 2024

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 (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)
@adamscott adamscott changed the title Some Emscripten's .js libraries are only compatible with closure --language-in UNSTABLE Some Emscripten's .js libraries are only compatible with closure --language-in UNSTABLE due to public class fields Dec 16, 2024
@adamscott
Copy link
Author

Seems to be caused by #22808.

@sbc100
Copy link
Collaborator

sbc100 commented Dec 16, 2024

Yes, we had to use UNSTABLE in order to get class member initialization supported. I think closure is just a little out of date here. I think that fact that they are missing from ECMASCRIPT_2021 is perhaps closure bug because it looks like they have been available in browser since 2018/2019: https://caniuse.com/mdn-javascript_classes_public_class_fields.

Is there some reason that you need to pass --language_in ECMASCRIPT_2021 in EMCC_CLOSURE_ARGS? Can you perhaps just remove that?

@sbc100
Copy link
Collaborator

sbc100 commented Dec 16, 2024

I did a little digging and found out what might be going on here. Apparently public class fields were stage 3 and shipping in browsers for many years before they finally make it into a stage 4 spec in ES2022.

However, they were shipping and usable on all browsers as far back as 2018/2019.

I'm not sure I can think of any good reason to override emscripten's --language_in .. but maybe I'm missing something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants