Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 8 additions & 32 deletions src/native/corehost/browserhost/browserhost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,44 +89,20 @@ static const void* pinvoke_override(const char* library_name, const char* entry_
return nullptr;
}

static pal::string_t app_path;
static pal::string_t search_paths;
static pal::string_t tpa;
static const pal::string_t app_domain_name = "corehost";
static const pal::string_t exe_path = "/managed";
static std::vector<const char*> propertyKeys;
static std::vector<const char*> propertyValues;
static pal::char_t ptr_to_string_buffer[STRING_LENGTH("0xffffffffffffffff") + 1];

// WASM-TODO: pass TPA via argument, not env
// WASM-TODO: pass app_path via argument, not env
// WASM-TODO: pass search_paths via argument, not env
extern "C" int BrowserHost_InitializeCoreCLR(void)
static host_runtime_contract host_contract = { sizeof(host_runtime_contract), nullptr };

extern "C" void* BrowserHost_CreateHostContract(void)
{
pal::getenv(HOST_PROPERTY_APP_PATHS, &app_path);
pal::getenv(HOST_PROPERTY_NATIVE_DLL_SEARCH_DIRECTORIES, &search_paths);
pal::getenv(HOST_PROPERTY_TRUSTED_PLATFORM_ASSEMBLIES, &tpa);

// Set base initialization properties.
propertyKeys.push_back(HOST_PROPERTY_APP_PATHS);
propertyValues.push_back(app_path.c_str());
propertyKeys.push_back(HOST_PROPERTY_NATIVE_DLL_SEARCH_DIRECTORIES);
propertyValues.push_back(search_paths.c_str());
propertyKeys.push_back(HOST_PROPERTY_TRUSTED_PLATFORM_ASSEMBLIES);
propertyValues.push_back(tpa.c_str());

host_runtime_contract host_contract = { sizeof(host_runtime_contract), nullptr };
host_contract.pinvoke_override = &pinvoke_override;
host_contract.external_assembly_probe = &BrowserHost_ExternalAssemblyProbe;
return &host_contract;
}

pal::snwprintf(ptr_to_string_buffer, ARRAY_SIZE(ptr_to_string_buffer), _X("0x%zx"), (size_t)(&host_contract));

propertyKeys.push_back(HOST_PROPERTY_RUNTIME_CONTRACT);
propertyValues.push_back(ptr_to_string_buffer);

extern "C" int BrowserHost_InitializeCoreCLR(int propertiesCount, const char** propertyKeys, const char** propertyValues)
{
coreclr_set_error_writer(log_error_info);

int retval = coreclr_initialize(exe_path.c_str(), app_domain_name.c_str(), (int)propertyKeys.size(), propertyKeys.data(), propertyValues.data(), &CurrentClrInstance, &CurrentAppDomainId);
int retval = coreclr_initialize("/managed", "corehost", propertiesCount, propertyKeys, propertyValues, &CurrentClrInstance, &CurrentAppDomainId);

if (retval < 0)
{
Expand Down
53 changes: 51 additions & 2 deletions src/native/corehost/browserhost/host/host.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import type { CharPtr, VfsAsset, VoidPtr, VoidPtrPtr } from "./types";
import type { CharPtr, CharPtrPtr, VfsAsset, VoidPtr, VoidPtrPtr } from "./types";
import { _ems_ } from "../../../libs/Common/JavaScript/ems-ambient";

const loadedAssemblies: Map<string, { ptr: number, length: number }> = new Map();
Expand Down Expand Up @@ -90,8 +90,57 @@ export function installVfsFile(bytes: Uint8Array, asset: VfsAsset) {
);
}


const HOST_PROPERTY_RUNTIME_CONTRACT = "HOST_RUNTIME_CONTRACT";
const HOST_PROPERTY_TRUSTED_PLATFORM_ASSEMBLIES = "TRUSTED_PLATFORM_ASSEMBLIES";
const HOST_PROPERTY_ENTRY_ASSEMBLY_NAME = "ENTRY_ASSEMBLY_NAME";
const HOST_PROPERTY_NATIVE_DLL_SEARCH_DIRECTORIES = "NATIVE_DLL_SEARCH_DIRECTORIES";
const HOST_PROPERTY_APP_PATHS = "APP_PATHS";
const APP_CONTEXT_BASE_DIRECTORY = "APP_CONTEXT_BASE_DIRECTORY";
const RUNTIME_IDENTIFIER = "RUNTIME_IDENTIFIER";

export function initializeCoreCLR(): number {
return _ems_._BrowserHost_InitializeCoreCLR();
const loaderConfig = _ems_.dotnetApi.getConfig();
const hostContractPtr = _ems_._BrowserHost_CreateHostContract();
const runtimeConfigProperties = new Map<string, string>();
if (loaderConfig.runtimeConfig?.runtimeOptions?.configProperties) {
for (const [key, value] of Object.entries(loaderConfig.runtimeConfig?.runtimeOptions?.configProperties)) {
runtimeConfigProperties.set(key, "" + value);
}
}
const assemblyPaths = loaderConfig.resources!.assembly.map(a => "/" + a.virtualPath);
const coreAssemblyPaths = loaderConfig.resources!.coreAssembly.map(a => "/" + a.virtualPath);
const tpa = [...coreAssemblyPaths, ...assemblyPaths].join(":");
runtimeConfigProperties.set(HOST_PROPERTY_TRUSTED_PLATFORM_ASSEMBLIES, tpa);
runtimeConfigProperties.set(HOST_PROPERTY_NATIVE_DLL_SEARCH_DIRECTORIES, loaderConfig.virtualWorkingDirectory!);
runtimeConfigProperties.set(HOST_PROPERTY_APP_PATHS, loaderConfig.virtualWorkingDirectory!);
runtimeConfigProperties.set(HOST_PROPERTY_ENTRY_ASSEMBLY_NAME, loaderConfig.mainAssemblyName!);
runtimeConfigProperties.set(APP_CONTEXT_BASE_DIRECTORY, "/");
runtimeConfigProperties.set(RUNTIME_IDENTIFIER, "browser-wasm");
runtimeConfigProperties.set(HOST_PROPERTY_RUNTIME_CONTRACT, `0x${(hostContractPtr as unknown as number).toString(16)}`);

const buffers: VoidPtr[] = [];
const appctx_keys = _ems_._malloc(4 * runtimeConfigProperties.size) as any as CharPtrPtr;
const appctx_values = _ems_._malloc(4 * runtimeConfigProperties.size) as any as CharPtrPtr;
buffers.push(appctx_keys as any);
buffers.push(appctx_values as any);

let propertyCount = 0;
for (const [key, value] of runtimeConfigProperties.entries()) {
const keyPtr = _ems_.dotnetBrowserUtilsExports.stringToUTF8Ptr(key);
const valuePtr = _ems_.dotnetBrowserUtilsExports.stringToUTF8Ptr(value);
_ems_.dotnetApi.setHeapU32((appctx_keys as any) + (propertyCount * 4), keyPtr);
_ems_.dotnetApi.setHeapU32((appctx_values as any) + (propertyCount * 4), valuePtr);
propertyCount++;
buffers.push(keyPtr as any);
buffers.push(valuePtr as any);
}

const res = _ems_._BrowserHost_InitializeCoreCLR(propertyCount, appctx_keys, appctx_values);
for (const buf of buffers) {
_ems_._free(buf as any);
}
return res;
}

// bool BrowserHost_ExternalAssemblyProbe(const char* pathPtr, /*out*/ void **outDataStartPtr, /*out*/ int64_t* outSize);
Expand Down
46 changes: 20 additions & 26 deletions src/native/corehost/browserhost/libBrowserHost.footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@
const exports = {};
libBrowserHost(exports);

// libBrowserHostFn is too complex for acorn-optimizer.mjs to find the dependencies
let explicitDeps = [
"wasm_load_icu_data", "BrowserHost_CreateHostContract", "BrowserHost_InitializeCoreCLR", "BrowserHost_ExecuteAssembly"
];
let commonDeps = [
"$DOTNET", "$DOTNET_INTEROP", "$ENV", "$FS", "$NODEFS",
"$libBrowserHostFn",
"wasm_load_icu_data", "BrowserHost_InitializeCoreCLR", "BrowserHost_ExecuteAssembly"
...explicitDeps
];
const lib = {
$BROWSER_HOST: {
Expand All @@ -35,28 +39,18 @@
exports.dotnetInitializeModule(dotnetInternals);
BROWSER_HOST.assignExports(exports, BROWSER_HOST);

const HOST_PROPERTY_TRUSTED_PLATFORM_ASSEMBLIES = "TRUSTED_PLATFORM_ASSEMBLIES";
const HOST_PROPERTY_ENTRY_ASSEMBLY_NAME = "ENTRY_ASSEMBLY_NAME";
const HOST_PROPERTY_NATIVE_DLL_SEARCH_DIRECTORIES = "NATIVE_DLL_SEARCH_DIRECTORIES";
const HOST_PROPERTY_APP_PATHS = "APP_PATHS";

const config = dotnetInternals[2/*InternalExchangeIndex.LoaderConfig*/];
if (!config.resources.assembly ||
!config.resources.coreAssembly ||
config.resources.coreAssembly.length === 0 ||
!config.mainAssemblyName ||
!config.virtualWorkingDirectory ||
!config.environmentVariables) {
const loaderConfig = dotnetInternals[2/*InternalExchangeIndex.LoaderConfig*/];
if (!loaderConfig.resources.assembly ||
!loaderConfig.resources.coreAssembly ||
loaderConfig.resources.coreAssembly.length === 0 ||
!loaderConfig.mainAssemblyName ||
!loaderConfig.virtualWorkingDirectory ||
!loaderConfig.environmentVariables) {
throw new Error("Invalid runtime config, cannot initialize the runtime.");
}
const assemblyPaths = config.resources.assembly.map(a => "/" + a.virtualPath);
const coreAssemblyPaths = config.resources.coreAssembly.map(a => "/" + a.virtualPath);
config.environmentVariables[HOST_PROPERTY_TRUSTED_PLATFORM_ASSEMBLIES] = [...coreAssemblyPaths, ...assemblyPaths].join(":");
config.environmentVariables[HOST_PROPERTY_NATIVE_DLL_SEARCH_DIRECTORIES] = config.virtualWorkingDirectory;
config.environmentVariables[HOST_PROPERTY_APP_PATHS] = config.virtualWorkingDirectory;
config.environmentVariables[HOST_PROPERTY_ENTRY_ASSEMBLY_NAME] = config.mainAssemblyName;
for (const key in config.environmentVariables) {
ENV[key] = config.environmentVariables[key];

for (const key in loaderConfig.environmentVariables) {
ENV[key] = loaderConfig.environmentVariables[key];
}

if (ENVIRONMENT_IS_NODE) {
Expand All @@ -68,25 +62,25 @@
}
}
},
// libBrowserHostFn is too complex for acorn-optimizer.mjs to find the dependencies
AJSDCE_Deps: function () {
_BrowserHost_InitializeCoreCLR();
_BrowserHost_ExecuteAssembly();
},
},
$libBrowserHostFn: libBrowserHost,
$BROWSER_HOST__postset: "BROWSER_HOST.selfInitialize()",
$BROWSER_HOST__deps: commonDeps,
};

let assignExportsBuilder = "";
let explicitImportsBuilder = "";
for (const exportName of Reflect.ownKeys(exports)) {
const name = String(exportName);
if (name === "dotnetInitializeModule") continue;
lib[name] = () => "dummy";
assignExportsBuilder += `_${String(name)} = exports.${String(name)};\n`;
}
for (const importName of explicitDeps) {
explicitImportsBuilder += `_${importName}();\n`;
}
lib.$BROWSER_HOST.assignExports = new Function("exports", assignExportsBuilder);
lib.$BROWSER_HOST.explicitImports = new Function(explicitImportsBuilder);

autoAddDeps(lib, "$BROWSER_HOST");
addToLibrary(lib);
Expand Down
8 changes: 8 additions & 0 deletions src/native/corehost/browserhost/loader/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ function mergeConfigs(target: LoaderConfigInternal, source: Partial<LoaderConfig
source.diagnosticTracing = source.diagnosticTracing !== undefined ? source.diagnosticTracing : target.diagnosticTracing;
source.environmentVariables = { ...target.environmentVariables, ...source.environmentVariables };
source.runtimeOptions = [...target.runtimeOptions!, ...source.runtimeOptions!];
source.runtimeConfig!.runtimeOptions!.configProperties = { ...target.runtimeConfig!.runtimeOptions!.configProperties!, ...source.runtimeConfig!.runtimeOptions!.configProperties! };
Object.assign(target, source);
return target;
}
Expand Down Expand Up @@ -87,6 +88,13 @@ function normalizeConfig(target: LoaderConfigInternal) {
normalizeResources(target.resources!);
if (!target.environmentVariables) target.environmentVariables = {};
if (!target.runtimeOptions) target.runtimeOptions = [];
if (!target.runtimeConfig) {
target.runtimeConfig = { runtimeOptions: { configProperties: {} }, };
} else if (!target.runtimeConfig.runtimeOptions) {
target.runtimeConfig.runtimeOptions = { configProperties: {} };
} else if (!target.runtimeConfig.runtimeOptions.configProperties) {
target.runtimeConfig.runtimeOptions.configProperties = {};
}
}

function normalizeResources(target: Assets) {
Expand Down
5 changes: 3 additions & 2 deletions src/native/libs/Common/JavaScript/types/ems-ambient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type {
EmscriptenModuleInternal, InternalExchange, InternalExchangeSubscriber,
RuntimeAPI, LoaderExports, BrowserUtilsExports, RuntimeExports,
VoidPtr, JSMarshalerArguments, CSFnHandle, TypedArray,
MemOffset
MemOffset, CharPtrPtr
} from "../types";

// we want to use the cross-module symbols defined in closure of dotnet.native.js
Expand All @@ -27,7 +27,8 @@ export type EmsAmbientSymbolsType = EmscriptenModuleInternal & {
_GetDotNetRuntimeContractDescriptor: () => void;
_SystemJS_ExecuteTimerCallback: () => void;
_SystemJS_ExecuteBackgroundJobCallback: () => void;
_BrowserHost_InitializeCoreCLR: () => number;
_BrowserHost_CreateHostContract: () => VoidPtr;
_BrowserHost_InitializeCoreCLR: (propertiesCount: number, propertyKeys: CharPtrPtr, propertyValues: CharPtrPtr) => number;
_BrowserHost_ExecuteAssembly: (mainAssemblyNamePtr: number, argsLength: number, argsPtr: number) => number;
_wasm_load_icu_data: (dataPtr: VoidPtr) => number;
_SystemInteropJS_GetManagedStackTrace: (args: JSMarshalerArguments) => void;
Expand Down
4 changes: 2 additions & 2 deletions src/native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
"scripts": {
"rollup:stub": "node rollup.stub.js",
"rollup:cmake": "rollup -c --environment ",
"rollup:release": "rollup -c --environment Configuration:Release,ProductVersion:11.0.0-dev,ContinuousIntegrationBuild:false",
"rollup:debug": "rollup -c --environment Configuration:Debug,ProductVersion:11.0.0-dev,ContinuousIntegrationBuild:false",
"rollup:release": "rollup -c --environment Configuration:Release,ProductVersion:11.0,ContinuousIntegrationBuild:false",
"rollup:debug": "rollup -c --environment Configuration:Debug,ProductVersion:11.0,ContinuousIntegrationBuild:false",
"lint": "eslint --no-color --max-warnings=0 \"./**/*.ts\" \"./**/*.js\"",
"format": "eslint --fix \"./**/*.ts\" \"./*.js\""
},
Expand Down
2 changes: 1 addition & 1 deletion src/native/rollup.config.defines.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ if (process.env.ProductVersion === undefined) {
export const configuration = process.env.Configuration !== "Release" && process.env.Configuration !== "RELEASE" ? "Debug" : "Release";
export const productVersion = process.env.ProductVersion;
export const isContinuousIntegrationBuild = process.env.ContinuousIntegrationBuild === "true" ? true : false;
export const staticLibDestination = process.env.StaticLibDestination || "../../artifacts/bin/browser-wasm.Debug/corehost";
export const staticLibDestination = process.env.StaticLibDestination || `../../artifacts/obj/native/net${productVersion}-browser-${configuration}-wasm/lib`;

console.log(`Rollup configuration: Configuration=${configuration}, ProductVersion=${productVersion}, ContinuousIntegrationBuild=${isContinuousIntegrationBuild}`);

Expand Down
Loading