diff --git a/.cargo/config.toml b/.cargo/config.toml deleted file mode 100644 index c316f0961..000000000 --- a/.cargo/config.toml +++ /dev/null @@ -1,2 +0,0 @@ -[target.wasm32-unknown-unknown] -rustflags=["--cfg=web_sys_unstable_apis"] diff --git a/web/packages/core/package.json b/web/packages/core/package.json index c74082bad..e759687c2 100644 --- a/web/packages/core/package.json +++ b/web/packages/core/package.json @@ -9,15 +9,30 @@ "pkg/" ], "scripts": { - "build": "npm run build:cargo && npm run build:wasm-bindgen && npm run build:wasm-opt && npm run build:ts", + "build": "npm run build:ruffle_web && npm run build:ruffle_web-wasm_extensions && npm run build:ts", + + "//1": "# Unfortunately, we have to set $RUSTFLAGS here, instead of in .cargo/config.toml (for example), because it's not possible to specify them per-profile; see cargo issue #7878.", + "//2": "# Enabling 'build-std' would also be great, but it's not stable yet.", + + "build:ruffle_web": "cross-env OUT_NAME=ruffle_web RUSTFLAGS=\"--cfg=web_sys_unstable_apis\" npm run build:cargo_bindgen_opt", + "build:ruffle_web-wasm_extensions": "echo \"Building module with WebAssembly extensions\" && cross-env OUT_NAME=ruffle_web-wasm_extensions RUSTFLAGS=\"--cfg=web_sys_unstable_apis -C target-feature=+bulk-memory,+simd128,+nontrapping-fptoint,+sign-ext\" npm run build:cargo_bindgen_opt", + + "//3": "# This just chains together the three commands after it.", + "build:cargo_bindgen_opt": "npm run build:cargo && npm run build:wasm-bindgen && npm run build:wasm-opt", + "build:cargo": "cross-env-shell \"cargo build --release --target wasm32-unknown-unknown --features \\\"$CARGO_FEATURES\\\"\"", - "build:wasm-bindgen": "wasm-bindgen ../../../target/wasm32-unknown-unknown/release/ruffle_web.wasm --target web --out-dir ./pkg --out-name ruffle_web", - "build:wasm-opt": "wasm-opt -o ./pkg/ruffle_web_bg.wasm -O -g ./pkg/ruffle_web_bg.wasm || npm run build:wasm-opt-failed", + "build:wasm-bindgen": "cross-env-shell \"wasm-bindgen ../../../target/wasm32-unknown-unknown/release/ruffle_web.wasm --target web --out-dir ./pkg --out-name $OUT_NAME\"", + "build:wasm-opt": "cross-env-shell \"wasm-opt -o ./pkg/${OUT_NAME}_bg.wasm -O -g ./pkg/${OUT_NAME}_bg.wasm || npm run build:wasm-opt-failed\"", + "build:wasm-opt-failed": "echo 'NOTE: Since wasm-opt could not be found (or it failed), the resulting module might not perform that well, but it should still work.' && echo ; [ \"$CI\" != true ] # > nul", + "build:ts": "tsc -d && node tools/set_version.js", "docs": "typedoc", "test": "cross-env TS_NODE_COMPILER_OPTIONS={\\\"module\\\":\\\"commonjs\\\"} mocha" }, + "dependencies": { + "wasm-feature-detect": "^1.2.11" + }, "devDependencies": { "@types/mocha": "^9.0.0", "@typescript-eslint/eslint-plugin": "^5.8.1", diff --git a/web/packages/core/src/load-ruffle.ts b/web/packages/core/src/load-ruffle.ts index 6367acf36..df10bdab4 100644 --- a/web/packages/core/src/load-ruffle.ts +++ b/web/packages/core/src/load-ruffle.ts @@ -2,7 +2,12 @@ * Conditional ruffle loader */ -import init, { Ruffle } from "../pkg/ruffle_web"; +import { + bulkMemory, + simd, + saturatedFloatToInt, + signExtensions, +} from "wasm-feature-detect"; import { setPolyfillsOnLoad } from "./js-polyfills"; import { publicPath } from "./public-path"; import { Config } from "./config"; @@ -27,13 +32,40 @@ async function fetchRuffle(config: Config): Promise { // libraries, if needed. setPolyfillsOnLoad(); + // NOTE: Keep this list in sync with $RUSTFLAGS in the CI build config! + const extensionsSupported: boolean = ( + await Promise.all([ + bulkMemory(), + simd(), + saturatedFloatToInt(), + signExtensions(), + ]) + ).every(Boolean); + + if (!extensionsSupported) { + console.log( + "Some WebAssembly extensions are NOT available, falling back to the vanilla WebAssembly module" + ); + } + __webpack_public_path__ = publicPath(config); + + // Note: The argument passed to import() has to be a simple string literal, + // otherwise some bundler will get confused and won't include the module? + const { default: init, Ruffle } = await (extensionsSupported + ? import("../pkg/ruffle_web-wasm_extensions") + : import("../pkg/ruffle_web")); + await init(); return Ruffle; } -let lastLoaded: Promise | null = null; +type Ruffle = + | typeof import("../pkg/ruffle_web")["Ruffle"] + | typeof import("../pkg/ruffle_web-wasm_extensions")["Ruffle"]; + +let lastLoaded: Promise | null = null; /** * Obtain an instance of `Ruffle`. @@ -44,7 +76,7 @@ let lastLoaded: Promise | null = null; * @returns A ruffle constructor that may be used to create new Ruffle * instances. */ -export function loadRuffle(config: Config): Promise { +export function loadRuffle(config: Config): Promise { if (lastLoaded == null) { lastLoaded = fetchRuffle(config); } diff --git a/web/packages/core/tsconfig.json b/web/packages/core/tsconfig.json index cf67a8297..07f15fef3 100644 --- a/web/packages/core/tsconfig.json +++ b/web/packages/core/tsconfig.json @@ -2,7 +2,7 @@ "extends": "@tsconfig/recommended/tsconfig.json", "compilerOptions": { "target": "es2017", - "module": "es2015", + "module": "es2020", "moduleResolution": "node", "strict": true, "outDir": "pkg", diff --git a/web/packages/extension/tsconfig.json b/web/packages/extension/tsconfig.json index ea6ca817f..175cd503b 100644 --- a/web/packages/extension/tsconfig.json +++ b/web/packages/extension/tsconfig.json @@ -2,7 +2,7 @@ "extends": "@tsconfig/recommended/tsconfig.json", "compilerOptions": { "target": "es2017", - "module": "es2015", + "module": "es2020", "moduleResolution": "node", "strict": true, },