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

Safari iOS 14.3 fails to load wasm even with -sMIN_SAFARI_VERSION=120000 #19718

Closed
ricardperez opened this issue Jun 26, 2023 · 5 comments
Closed

Comments

@ricardperez
Copy link

ricardperez commented Jun 26, 2023

Please include the following in your bug report:

Version of emscripten/emsdk:
3.1.26
I tested and verified that things work as expected in 3.1.25.

Please include the output emcc -v here

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.26 (8eaf19f1c6a9a1b0cd0f9a91657366829e34ae5c)
clang version 16.0.0 (https://github.com/llvm/llvm-project f81f0cb75a2808a67d2662f044ad07628fc9d900)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/bin

Failing command line in full:
N/A

Full link command and output with -v appended:
Even for runtime issues it helps a lot if you can include the full link command.
Adding -v to the link command will show all of the sub-commands run which
can help us diagnose your issue.

This is the output of both build and link as I do it all in a single step:

 "/Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/bin/clang" --version
 "/Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/bin/clang++" -target wasm32-unknown-emscripten -fignore-exceptions -fvisibility=default -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr -DEMSCRIPTEN -I/Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/emscripten/cache/sysroot/include/SDL --sysroot=/Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/emscripten/cache/sysroot -Xclang -iwithsysroot/include/compat -O2 -v lib.cpp -c -o /var/folders/nw/669_3plx2jl5sts50b2x101r0000gn/T/emscripten_temp_g2dafa7q/lib_0.o
clang version 16.0.0 (https://github.com/llvm/llvm-project f81f0cb75a2808a67d2662f044ad07628fc9d900)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/bin
 (in-process)
 "/Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/bin/clang-16" -cc1 -triple wasm32-unknown-emscripten -emit-obj --mrelax-relocations -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name lib.cpp -mrelocation-model static -mframe-pointer=none -ffp-contract=on -fno-rounding-math -mconstructor-aliases -target-cpu generic -mllvm -treat-scalable-fixed-error-as-warning -debugger-tuning=gdb -v -fcoverage-compilation-dir=/Users/ricardperez/gitlab/ricard/hello-webassembly -resource-dir /Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/lib/clang/16 -D EMSCRIPTEN -I /Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/emscripten/cache/sysroot/include/SDL -isysroot /Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/emscripten/cache/sysroot -internal-isystem /Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten/c++/v1 -internal-isystem /Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1 -internal-isystem /Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/lib/clang/16/include -internal-isystem /Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten -internal-isystem /Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/emscripten/cache/sysroot/include -O2 -fdeprecated-macro -fdebug-compilation-dir=/Users/ricardperez/gitlab/ricard/hello-webassembly -ferror-limit 19 -fvisibility=default -fgnuc-version=4.2.1 -fcxx-exceptions -fignore-exceptions -fexceptions -fcolor-diagnostics -vectorize-loops -vectorize-slp -iwithsysroot/include/compat -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr -o /var/folders/nw/669_3plx2jl5sts50b2x101r0000gn/T/emscripten_temp_g2dafa7q/lib_0.o -x c++ lib.cpp
clang -cc1 version 16.0.0 based upon LLVM 16.0.0git default target x86_64-apple-darwin22.5.0
ignoring nonexistent directory "/Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten/c++/v1"
ignoring nonexistent directory "/Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten"
#include "..." search starts here:
#include <...> search starts here:
 /Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/emscripten/cache/sysroot/include/SDL
 /Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/emscripten/cache/sysroot/include/compat
 /Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1
 /Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/lib/clang/16/include
 /Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/emscripten/cache/sysroot/include
End of search list.
 "/Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/bin/wasm-ld" -o lib.wasm /var/folders/nw/669_3plx2jl5sts50b2x101r0000gn/T/emscripten_temp_g2dafa7q/lib_0.o -L/Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten -lGL -lal -lhtml5 -lstubs -lnoexit -lc -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --import-undefined --strip-debug --export-if-defined=main --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=__main_argc_argv --export=stackSave --export=stackRestore --export=stackAlloc --export=__wasm_call_ctors --export=__errno_location --export=__get_temp_ret --export=__set_temp_ret --export=malloc --export=__cxa_is_pointer_type --export-table -z stack-size=5242880 --initial-memory=16777216 --no-entry --max-memory=2147483648 --global-base=1024
 "/Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/bin/wasm-emscripten-finalize" --dyncalls-i64 --pass-arg=legalize-js-interface-exported-helpers lib.wasm -o lib.wasm --detect-features
 "/Users/ricardperez/gitlab/emscripten-core/emsdk/node/15.14.0_64bit/bin/node" /Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/emscripten/src/compiler.js /var/folders/nw/669_3plx2jl5sts50b2x101r0000gn/T/tmpxbial42l.json
 "/Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/bin/wasm-opt" --strip-dwarf --signext-lowering --post-emscripten -O2 --low-memory-unused --zero-filled-memory --pass-arg=directize-initial-contents-immutable --strip-debug --strip-producers lib.wasm -o lib.wasm --mvp-features --enable-mutable-globals --enable-sign-ext
 "/Users/ricardperez/gitlab/emscripten-core/emsdk/node/15.14.0_64bit/bin/node" /Users/ricardperez/gitlab/emscripten-core/emsdk/upstream/emscripten/tools/acorn-optimizer.js /var/folders/nw/669_3plx2jl5sts50b2x101r0000gn/T/emscripten_temp_g2dafa7q/lib.js JSDCE minifyWhitespace -o /var/folders/nw/669_3plx2jl5sts50b2x101r0000gn/T/emscripten_temp_g2dafa7q/lib.jso1.js

The issue

I have discovered that my application is not working on iOS 14.3 (and lower) - and it should.

This is the error I am seeing:

Screenshot 2023-06-26 at 18 04 26

The issue started to happen when the emscripten toolchain was bumped from version 3.1.23 to 3.1.34. I have done different builds with different Emscripten versions and this only happens starting at 3.1.26. Checking the release notes in the changelog I see this:

  • Inline with the recent changes to llvm and binaryen, emscripten will now, by default, enable the sign-extension and mutable-globals WebAssembly proposals. In order to do so the default minimum safari version (MIN_SAFARI_VERSION) was updated from 12.0 to 14.1, and support for the old EdgeHTML engine (MIN_EDGE_VERSION) was removed by default. If you want to continue to support these older engines you can use these settings (-sMIN_SAFARI_VERSION=120000 and/or -sMIN_EDGE_VERSION=44) to revert to the previous defaults, which will result in the new proposals being disabled. Note that in order to avoid support for the sign-extension emscripten uses a binaryen pass, so targeting older browsers requires the running of wasm-opt and is therefore incompatible with ERROR_ON_WASM_CHANGES_AFTER_LINK (i.e. fast linking). (Bump min browser versions such they all support llvm default features #17690)

This explicitly says that iOS min version was changed from 12.0.0 to 14.1. I am testing with iOS 14.3, so in theory I should not be affected by this. But anyway I tried to link with the recommended flag -sMIN_SAFARI_VERSION=120000. It didn't help. See the next section.

Reproduction sample

I managed to create a sample project to reproduce the problem.

It helped me to discover that the optimisation flags make a difference to the result. Using none or little optmisiations (-O0 & -O1) it will work fine when I also use -s MIN_SAFARI_VERSION=120000. But bigger optimisations (-O2 and more) will always fail with the error no matter if MIN_SAFARI_VERSION was set or not.

This is the project setup I am using:

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>WebAssembly using Emscripten</title>
</head>
<body style="background-color:#1D1E20; color:wheat">
    <h1>Test</h1>
    <script>
        const worker = new Worker('worker.js');
    </script>
</body>
</html>

worker.js

importScripts('lib.js');

lib.cpp

#include <iostream>

int main() {
    std::cout << "Hello from c++" << std::endl;
    return 0;
}

And this is the build script:

source "/Users/ricardperez/gitlab/emscripten-core/emsdk/emsdk_env.sh" &> /dev/null

emsdk install 3.1.26
emsdk activate 3.1.26

em++ lib.cpp -o lib.js -O2 -sMIN_SAFARI_VERSION=120000
# note that using -O1 makes it work as expected
# emrun index.html

Any clue of what might be causing the problem?

@ricardperez ricardperez changed the title Safari iOS 14.0.3 fails to load wasm even with sMIN_SAFARI_VERSION=120000 Safari iOS 14.3 fails to load wasm even with sMIN_SAFARI_VERSION=120000 Jun 26, 2023
@ricardperez ricardperez changed the title Safari iOS 14.3 fails to load wasm even with sMIN_SAFARI_VERSION=120000 Safari iOS 14.3 fails to load wasm even with -sMIN_SAFARI_VERSION=120000 Jun 26, 2023
@ricardperez
Copy link
Author

Using -g3 I get a similar error:

failed to asynchronously prepare wasm: CompileError: WebAssembly.Module doesn't parse at byte 164: invalid opcode 192, in function at index 2

When I run wasm-objdump -x ~/sample-project/lib.wasm I see this in the output:

 - func[2] sig=0 <emscripten_resize_heap> <- env.emscripten_resize_heap

@ricardperez
Copy link
Author

I started testing with newer emscripten versions than 3.1.34. I installed 3.1.40 and it did work as expected, no error when -sMIN_SAFARI_VERSION=120000 is provided.

I did some tests, and the first version that gave me expected results is 3.1.37. I couldn't find anything in the changelog talking about any related fix.

Tomorrow I will try my real project with such version and see.

@sbc100
Copy link
Collaborator

sbc100 commented Jun 26, 2023

I believe this was fixed in binaryen: WebAssembly/binaryen#5676

The original bug was #19121, and I guess this a duplicate of that one?

@ricardperez
Copy link
Author

Alright, thanks @sbc100.

Shall the release notes for 3.1.37 be updated to reflect such fix maybe? This would made my life easier to identify the problem I guess.

@eatsjobs
Copy link

Compiling with emsdk v3.1.23 here is the resulting not working code

On Safari 14.3 there's also another problem: WebGLRederingContext is not available in Worker scope and this code fails at line 7

createContext: function (canvas, webGLContextAttributes) {
    if (!canvas.getContextSafariWebGL2Fixed) {
      canvas.getContextSafariWebGL2Fixed = canvas.getContext;
      function fixedGetContext(ver, attrs) {        
        var gl = canvas.getContextSafariWebGL2Fixed(ver, attrs);
        // WebGLRenderingContext is not available in scope. this will throw an error
        return ver == "webgl" == gl instanceof WebGLRenderingContext ? gl : null;
      }
      canvas.getContext = fixedGetContext;
    }
    var ctx = canvas.getContext("webgl", webGLContextAttributes);
    if (!ctx) return 0;
    var handle = GL.registerContext(ctx, webGLContextAttributes);
    return handle;
  },

while this works correctly

createContext: function (canvas, webGLContextAttributes) {
    if (!canvas.getContextSafariWebGL2Fixed) {
      canvas.getContextSafariWebGL2Fixed = canvas.getContext;
      function fixedGetContext(ver, attrs) {
        try { 
          var gl = canvas.getContextSafariWebGL2Fixed(ver, attrs);
          // WebGLRenderingContext is not available in scope. but the error will be handled
          return ver == "webgl" == gl instanceof WebGLRenderingContext ? gl : null;
       } catch(e) {
          return null;
       }        
      }
      canvas.getContext = fixedGetContext;
    }
    var ctx = canvas.getContext("webgl", webGLContextAttributes);
    if (!ctx) return 0;
    var handle = GL.registerContext(ctx, webGLContextAttributes);
    return handle;
  },

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

3 participants