Skip to content

minification error breaks wasm2js initialization with -O2 --memory-init-file 0 #8886

@bvibber

Description

@bvibber

I'm trying to update ogv.js's upstream-llvm compatible builds to work with the latest goodies, including JS builds using wasm2js, but I seem to be having some trouble with minification at -O2 or above breaking the memory init functions when using --memory-init-file 0.

Using a latest-upstream build on macOS:

emcc (Emscripten gcc/clang-like replacement) 1.38.37 (commit d33f7a29002a2463a7956cd53a559b97a52f9560)

This code fragment from wasm2js.h:

    function(mem) {
      var _mem = new Uint8Array(mem);
      return function(offset, s) {
        if (typeof Buffer === 'undefined') {
          var bytes = atob(s);
          for (var i = 0; i < bytes.length; i++)
            _mem[offset + i] = bytes.charCodeAt(i);
        } else {
          var bytes = Buffer.from(s, 'base64');
          for (var i = 0; i < bytes.length; i++)
            _mem[offset + i] = bytes[i];
        }
      }
    }

ends up becoming this in output (exact var names vary depending on code built):

                    function(mem) {
                        var N = new Uint8Array(mem);
                        return (function(offset, s) {
                            if (typeof Buffer === "undefined") {
                                var O = atob(s);
                                for (var P = 0; R < Q.length; R++)
                                    N[offset + R] = Q.charCodeAt(R)
                            } else {
                                var Q = Buffer.from(s, "base64");
                                for (var R = 0; R < Q.length; R++)
                                    N[offset + R] = Q[R]
                            }
                        }
                        )
                    }

Note that the var bytes definitions becomes both a var O and a var Q in the separate if/else branches, but the uses in both branches are for Q. This causes an exception during initialization:

Uncaught (in promise) abort("TypeError: Cannot read property 'length' of undefined"). Build with -s ASSERTIONS=1 for more info.

because Q is hoisted and left at undefined rather than being set to the expected value.

Example test case:

#include <stdio.h>

int main(int argc, const char **argv) {
    printf("Hello, world\n");
    return 0;
}
emcc --memory-init-file 0 -O2 -s WASM=0 -o hi.html hi.c

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions