summaryrefslogtreecommitdiffstats
path: root/toolkit/components/ml/content/Utils.sys.mjs
blob: b3a25e84d7d380bbc5b3473af4b4f04cf3f0ce2a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

/**
 * Converts an ArrayBuffer to a Blob URL.
 *
 * @param {ArrayBuffer} buffer - The ArrayBuffer to convert.
 * @returns {string} The Blob URL.
 */
export function arrayBufferToBlobURL(buffer) {
  let blob = new Blob([buffer], { type: "application/wasm" });
  return URL.createObjectURL(blob);
}

/**
 * Validate some simple Wasm that uses a SIMD operation.
 */
function detectSimdSupport() {
  return WebAssembly.validate(
    new Uint8Array(
      // ```
      // ;; Detect SIMD support.
      // ;; Compile by running: wat2wasm --enable-all simd-detect.wat
      //
      // (module
      //   (func (result v128)
      //     i32.const 0
      //     i8x16.splat
      //     i8x16.popcnt
      //   )
      // )
      // ```

      // prettier-ignore
      [
        0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x05, 0x01, 0x60, 0x00,
        0x01, 0x7b, 0x03, 0x02, 0x01, 0x00, 0x0a, 0x0a, 0x01, 0x08, 0x00, 0x41, 0x00,
        0xfd, 0x0f, 0xfd, 0x62, 0x0b
      ]
    )
  );
}

let cachedRuntimeWasmFilename = null;

/**
 * Determines the appropriate WebAssembly (Wasm) filename based on the runtime capabilities of the browser.
 * This function considers both SIMD and multi-threading support.
 * It returns a filename that matches the browser's capabilities, ensuring the most optimized version of the Wasm file is used.
 *
 * The result is cached to avoid re-computation.
 *
 * @param {Window|null} browsingContext - The browsing context to use for feature detection.
 * @returns {string} The filename of the Wasm file best suited for the current browser's capabilities.
 */
export function getRuntimeWasmFilename(browsingContext = null) {
  if (cachedRuntimeWasmFilename != null) {
    return cachedRuntimeWasmFilename;
  }

  // The cross-origin isolation flag is used to determine if we have multi-threading support.
  const hasMultiThreadSupport = browsingContext
    ? browsingContext.crossOriginIsolated
    : false;

  let res;
  if (detectSimdSupport()) {
    res = hasMultiThreadSupport
      ? "ort-wasm-simd-threaded.wasm"
      : "ort-wasm-simd.wasm";
  } else {
    res = hasMultiThreadSupport ? "ort-wasm-threaded.wasm" : "ort-wasm.wasm";
  }
  cachedRuntimeWasmFilename = res;
  return res;
}