Unverified Commit 4e93aa7f authored by Tomáš Rohlínek's avatar Tomáš Rohlínek
Browse files

Fix build

parent 5be348e7
Loading
Loading
Loading
Loading
+67 −6
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ type TinyModuleFactory = (opts: {
  print: (text: string) => void;
  printErr: (text: string) => void;
  locateFile?: (path: string) => string;
  wasmBinary?: Uint8Array;
}) => Promise<TinyModule>;

export type PipelineResult = {
@@ -40,6 +41,11 @@ const defaultModulePaths: Record<TinyModuleKind, string> = {
  as: "../public/wasm/tinyas.js",
  vm: "../public/wasm/tinyvm.js",
};
const wasmNameByKind: Record<TinyModuleKind, string> = {
  cc: "tinycc.wasm",
  as: "tinyas.wasm",
  vm: "tinyvm.wasm",
};

function getModulePaths(): Record<TinyModuleKind, string> {
  const injected = (globalThis as {
@@ -58,6 +64,65 @@ function getInlineWasmBinaries(): Record<string, string> {
  }).__TINY_WASM_INLINE_BINARIES ?? {};
}

const inlineWasmByteCache = new Map<string, Uint8Array>();

function basename(path: string): string {
  return path.replace(/^.*[\\/]/, "");
}

function decodeDataUrlToBytes(dataUrl: string): Uint8Array {
  const commaIndex = dataUrl.indexOf(",");
  if (commaIndex < 0 || !dataUrl.startsWith("data:")) {
    throw new Error("invalid wasm data URL");
  }

  const header = dataUrl.slice(0, commaIndex);
  const payload = dataUrl.slice(commaIndex + 1);
  const isBase64 = /;base64(?:;|$)/i.test(header);

  if (isBase64) {
    const binary = atob(payload);
    const bytes = new Uint8Array(binary.length);
    for (let i = 0; i < binary.length; i += 1) {
      bytes[i] = binary.charCodeAt(i);
    }
    return bytes;
  }

  const decoded = decodeURIComponent(payload);
  const bytes = new Uint8Array(decoded.length);
  for (let i = 0; i < decoded.length; i += 1) {
    bytes[i] = decoded.charCodeAt(i);
  }
  return bytes;
}

function resolveInlineWasmDataUrl(moduleKind: TinyModuleKind, requestedPath: string): string | undefined {
  const inline = getInlineWasmBinaries();
  const candidates = [requestedPath, basename(requestedPath), wasmNameByKind[moduleKind]];
  for (const key of candidates) {
    const value = inline[key];
    if (value) {
      return value;
    }
  }
  return undefined;
}

function resolveInlineWasmBytes(moduleKind: TinyModuleKind): Uint8Array | undefined {
  const dataUrl = resolveInlineWasmDataUrl(moduleKind, wasmNameByKind[moduleKind]);
  if (!dataUrl) {
    return undefined;
  }
  const cached = inlineWasmByteCache.get(dataUrl);
  if (cached) {
    return cached;
  }
  const bytes = decodeDataUrlToBytes(dataUrl);
  inlineWasmByteCache.set(dataUrl, bytes);
  return bytes;
}

let cachedFactories:
  | {
      cc: TinyModuleFactory;
@@ -114,16 +179,12 @@ async function runTool(
    noInitialRun: true,
    print: (text) => stdout.push(text),
    printErr: (text) => stderr.push(text),
    wasmBinary: resolveInlineWasmBytes(moduleKind),
    locateFile: (path) => {
      const inlineWasm = getInlineWasmBinaries()[path];
      const inlineWasm = resolveInlineWasmDataUrl(moduleKind, path);
      if (inlineWasm) {
        return inlineWasm;
      }
      const wasmNameByKind: Record<TinyModuleKind, string> = {
        cc: "tinycc.wasm",
        as: "tinyas.wasm",
        vm: "tinyvm.wasm",
      };
      return `../public/wasm/${wasmNameByKind[moduleKind]}`;
    },
  });