diff --git a/src/coreclr/hosts/corerun/wasm/libCorerun.extpost.js b/src/coreclr/hosts/corerun/wasm/libCorerun.extpost.js index cd20391385721a..80c0efdcb3e102 100644 --- a/src/coreclr/hosts/corerun/wasm/libCorerun.extpost.js +++ b/src/coreclr/hosts/corerun/wasm/libCorerun.extpost.js @@ -25,7 +25,7 @@ export function selfRun() { runtimeId: 0, runtimeBuildInfo: { productVersion: "corerun", - gitHash: "corerun", + gitHash: null, buildConfiguration: "corerun", wasmEnableThreads: false, wasmEnableSIMD: true, diff --git a/src/native/corehost/browserhost/host/index.ts b/src/native/corehost/browserhost/host/index.ts index e5ad69465288ec..3eadb4cb94c3c6 100644 --- a/src/native/corehost/browserhost/host/index.ts +++ b/src/native/corehost/browserhost/host/index.ts @@ -5,6 +5,8 @@ import type { InternalExchange, BrowserHostExports, RuntimeAPI, BrowserHostExpor import { InternalExchangeIndex } from "./types"; import { } from "./cross-linked"; // ensure ambient symbols are declared +import GitHash from "consts:gitHash"; + import { runMain, runMainAndExit, registerDllBytes, installVfsFile, loadIcuData, initializeCoreCLR } from "./host"; export function dotnetInitializeModule(internals: InternalExchange): void { @@ -15,6 +17,9 @@ export function dotnetInitializeModule(internals: InternalExchange): void { }; const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI]; if (typeof runtimeApi !== "object") throw new Error("Expected internals to have RuntimeAPI"); + if (runtimeApi.runtimeBuildInfo.gitHash && runtimeApi.runtimeBuildInfo.gitHash !== GitHash) { + throw new Error(`Mismatched git hashes between loader and runtime. Loader: ${runtimeApi.runtimeBuildInfo.gitHash}, BrowserHost: ${GitHash}`); + } Object.assign(runtimeApi, runtimeApiLocal); internals[InternalExchangeIndex.BrowserHostExportsTable] = browserHostExportsToTable({ diff --git a/src/native/libs/System.Native.Browser/diagnostics/index.ts b/src/native/libs/System.Native.Browser/diagnostics/index.ts index 0de83b1ebf0ae2..8550abfb275891 100644 --- a/src/native/libs/System.Native.Browser/diagnostics/index.ts +++ b/src/native/libs/System.Native.Browser/diagnostics/index.ts @@ -3,6 +3,9 @@ import type { DiagnosticsExportsTable, InternalExchange, DiagnosticsExports } from "./types"; import { InternalExchangeIndex } from "../types"; + +import GitHash from "consts:gitHash"; + import { dotnetUpdateInternals, dotnetUpdateInternalsSubscriber } from "./cross-module"; import { registerExit } from "./exit"; import { symbolicateStackTrace } from "./symbolicate"; @@ -11,6 +14,13 @@ import { installLoggingProxy } from "./console-proxy"; export function dotnetInitializeModule(internals: InternalExchange): void { if (!Array.isArray(internals)) throw new Error("Expected internals to be an array"); + const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI]; + if (typeof runtimeApi !== "object") throw new Error("Expected internals to have RuntimeAPI"); + + if (runtimeApi.runtimeBuildInfo.gitHash && runtimeApi.runtimeBuildInfo.gitHash !== GitHash) { + throw new Error(`Mismatched git hashes between loader and runtime. Loader: ${runtimeApi.runtimeBuildInfo.gitHash}, Diagnostics: ${GitHash}`); + } + internals[InternalExchangeIndex.DiagnosticsExportsTable] = diagnosticsExportsToTable({ symbolicateStackTrace, }); diff --git a/src/native/libs/System.Native.Browser/libSystem.Native.Browser.footer.js b/src/native/libs/System.Native.Browser/libSystem.Native.Browser.footer.js index 75d01139c89e4d..ff5f4523b1fc12 100644 --- a/src/native/libs/System.Native.Browser/libSystem.Native.Browser.footer.js +++ b/src/native/libs/System.Native.Browser/libSystem.Native.Browser.footer.js @@ -29,6 +29,7 @@ } }, dotnetInitializeModule: exports.dotnetInitializeModule, + gitHash: exports.gitHash, }, $DOTNET__deps: commonDeps, $DOTNET__postset: "DOTNET.selfInitialize()", @@ -36,7 +37,7 @@ for (const exportName of Reflect.ownKeys(exports)) { const name = String(exportName); - if (name === "dotnetInitializeModule") continue; + if (name === "dotnetInitializeModule" || name === "gitHash") continue; const fn = lib[name] = exports[name]; if (fn.__deps) { lib[name + "__deps"] = fn.__deps; diff --git a/src/native/libs/System.Native.Browser/native/index.ts b/src/native/libs/System.Native.Browser/native/index.ts index 776f6258ff8859..9bdecaacda58e8 100644 --- a/src/native/libs/System.Native.Browser/native/index.ts +++ b/src/native/libs/System.Native.Browser/native/index.ts @@ -4,12 +4,24 @@ import type { InternalExchange, NativeBrowserExports, NativeBrowserExportsTable } from "../types"; import { InternalExchangeIndex } from "../types"; +import GitHash from "consts:gitHash"; + export { SystemJS_RandomBytes } from "./crypto"; export { SystemJS_GetLocaleInfo } from "./globalization-locale"; export { SystemJS_RejectMainPromise, SystemJS_ResolveMainPromise, SystemJS_ConsoleClear } from "./main"; export { SystemJS_ScheduleTimer, SystemJS_ScheduleBackgroundJob } from "./timer"; +export const gitHash = GitHash; export function dotnetInitializeModule(internals: InternalExchange): void { + if (!Array.isArray(internals)) throw new Error("Expected internals to be an array"); + + const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI]; + if (typeof runtimeApi !== "object") throw new Error("Expected internals to have RuntimeAPI"); + + if (runtimeApi.runtimeBuildInfo.gitHash && runtimeApi.runtimeBuildInfo.gitHash !== DOTNET.gitHash) { + throw new Error(`Mismatched git hashes between loader and runtime. Loader: ${runtimeApi.runtimeBuildInfo.gitHash}, DOTNET: ${DOTNET.gitHash}`); + } + internals[InternalExchangeIndex.NativeBrowserExportsTable] = nativeBrowserExportsToTable({ }); dotnetUpdateInternals(internals, dotnetUpdateInternalsSubscriber); diff --git a/src/native/libs/System.Native.Browser/utils/index.ts b/src/native/libs/System.Native.Browser/utils/index.ts index ec57f307d23d37..95434eb7bd8ae2 100644 --- a/src/native/libs/System.Native.Browser/utils/index.ts +++ b/src/native/libs/System.Native.Browser/utils/index.ts @@ -5,6 +5,8 @@ import type { InternalExchange, BrowserUtilsExports, RuntimeAPI, BrowserUtilsExp import { InternalExchangeIndex } from "../types"; import { } from "./cross-module"; // ensure ambient symbols are declared +import GitHash from "consts:gitHash"; + import { setHeapB32, setHeapB8, setHeapU8, setHeapU16, setHeapU32, setHeapI8, setHeapI16, setHeapI32, setHeapI52, setHeapU52, setHeapI64Big, setHeapF32, setHeapF64, getHeapB32, getHeapB8, getHeapU8, getHeapU16, getHeapU32, getHeapI8, getHeapI16, getHeapI32, getHeapI52, getHeapU52, getHeapI64Big, getHeapF32, getHeapF64, @@ -20,9 +22,15 @@ import { registerRuntime } from "./runtime-list"; import { registerCDAC } from "./cdac"; export function dotnetInitializeModule(internals: InternalExchange): void { - initPolyfills(); + if (!Array.isArray(internals)) throw new Error("Expected internals to be an array"); const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI]; if (typeof runtimeApi !== "object") throw new Error("Expected internals to have RuntimeAPI"); + + if (runtimeApi.runtimeBuildInfo.gitHash && runtimeApi.runtimeBuildInfo.gitHash !== GitHash) { + throw new Error(`Mismatched git hashes between loader and runtime. Loader: ${runtimeApi.runtimeBuildInfo.gitHash}, BrowserUtils: ${GitHash}`); + } + + initPolyfills(); registerRuntime(runtimeApi); registerCDAC(runtimeApi); diff --git a/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/index.ts b/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/index.ts index 20a0cc4e766b45..a48445f1c938b7 100644 --- a/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/index.ts +++ b/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/index.ts @@ -3,17 +3,25 @@ import type { InternalExchange, RuntimeAPI, RuntimeExports, RuntimeExportsTable } from "./types"; import { InternalExchangeIndex } from "../types"; + +import GitHash from "consts:gitHash"; + import { dotnetUpdateInternals, dotnetUpdateInternalsSubscriber } from "./cross-module"; import { ENVIRONMENT_IS_NODE } from "./per-module"; export function dotnetInitializeModule(internals: InternalExchange): void { if (!Array.isArray(internals)) throw new Error("Expected internals to be an array"); + const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI]; + if (typeof runtimeApi !== "object") throw new Error("Expected internals to have RuntimeAPI"); + + if (runtimeApi.runtimeBuildInfo.gitHash && runtimeApi.runtimeBuildInfo.gitHash !== GitHash) { + throw new Error(`Mismatched git hashes between loader and runtime. Loader: ${runtimeApi.runtimeBuildInfo.gitHash}, Runtime: ${GitHash}`); + } + const runtimeApiLocal: Partial = { getAssemblyExports, setModuleImports, }; - const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI]; - if (typeof runtimeApi !== "object") throw new Error("Expected internals to have RuntimeAPI"); Object.assign(runtimeApi, runtimeApiLocal); internals[InternalExchangeIndex.RuntimeExportsTable] = runtimeExportsToTable({ diff --git a/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/libSystem.Runtime.InteropServices.JavaScript.Native.footer.js b/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/libSystem.Runtime.InteropServices.JavaScript.Native.footer.js index 3544781dd9fa2a..08f2c813c3d5a7 100644 --- a/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/libSystem.Runtime.InteropServices.JavaScript.Native.footer.js +++ b/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/libSystem.Runtime.InteropServices.JavaScript.Native.footer.js @@ -29,6 +29,7 @@ } }, dotnetInitializeModule: exports.dotnetInitializeModule, + gitHash: exports.gitHash, }, $DOTNET_INTEROP__postset: "DOTNET_INTEROP.selfInitialize()", $DOTNET_INTEROP__deps: commonDeps, @@ -36,7 +37,7 @@ for (const exportName of Reflect.ownKeys(exports)) { const name = String(exportName); - if (name === "dotnetInitializeModule") continue; + if (name === "dotnetInitializeModule" || name === "gitHash") continue; lib[name] = exports[name]; } diff --git a/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/native/cross-linked.ts b/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/native/cross-linked.ts index ea10f4707c6a6c..f2caa4fb684a7b 100644 --- a/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/native/cross-linked.ts +++ b/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/native/cross-linked.ts @@ -3,3 +3,6 @@ import { } from "../../Common/JavaScript/cross-linked"; +declare global { + export const DOTNET_INTEROP: any; +} diff --git a/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/native/index.ts b/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/native/index.ts index 3dc342b2746f37..021eb895af80a0 100644 --- a/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/native/index.ts +++ b/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/native/index.ts @@ -5,6 +5,8 @@ import type { InternalExchange, InteropJavaScriptExports, InteropJavaScriptExpor import { InternalExchangeIndex } from "../types"; import { } from "./cross-linked"; // ensure ambient symbols are declared +import GitHash from "consts:gitHash"; + // eslint-disable-next-line @typescript-eslint/no-unused-vars export function SystemInteropJS_InvokeJSImportST(function_handle: JSFnHandle, args: JSMarshalerArguments) { // WASM-TODO implementation @@ -12,7 +14,16 @@ export function SystemInteropJS_InvokeJSImportST(function_handle: JSFnHandle, ar return - 1; } +export const gitHash = GitHash; export function dotnetInitializeModule(internals: InternalExchange): void { + if (!Array.isArray(internals)) throw new Error("Expected internals to be an array"); + const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI]; + if (typeof runtimeApi !== "object") throw new Error("Expected internals to have RuntimeAPI"); + + if (runtimeApi.runtimeBuildInfo.gitHash && runtimeApi.runtimeBuildInfo.gitHash !== DOTNET_INTEROP.gitHash) { + throw new Error(`Mismatched git hashes between loader and runtime. Loader: ${runtimeApi.runtimeBuildInfo.gitHash}, DOTNET_INTEROP: ${DOTNET_INTEROP.gitHash}`); + } + internals[InternalExchangeIndex.InteropJavaScriptExportsTable] = interopJavaScriptExportsToTable({ }); // eslint-disable-next-line @typescript-eslint/no-unused-vars