Skip to content

Commit 97a78d3

Browse files
authored
[browser][coreCLR] TypeScript host skeleton (#119866)
1 parent bf4802d commit 97a78d3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+2569
-2356
lines changed

src/coreclr/hosts/corerun/CMakeLists.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,13 @@ else(CLR_CMAKE_HOST_WIN32)
5656
System.Native.Browser-Static)
5757
set(JS_SYSTEM_NATIVE_BROWSER
5858
"${CLR_ARTIFACTS_OBJ_DIR}/native/browser-${CMAKE_BUILD_TYPE}-wasm/System.Native.Browser/libSystem.Native.Browser.js")
59+
set(JS_SYSTEM_BROWSER_UTILS
60+
"${CLR_ARTIFACTS_OBJ_DIR}/native/browser-${CMAKE_BUILD_TYPE}-wasm/System.Native.Browser/libSystem.Browser.Utils.js")
5961
set(JS_CORE_RUN_PRE
6062
"${CMAKE_CURRENT_SOURCE_DIR}/libCorerun.pre.js")
6163
set_target_properties(corerun PROPERTIES
62-
LINK_DEPENDS "${JS_CORE_RUN_PRE};${JS_SYSTEM_NATIVE_BROWSER};"
63-
LINK_FLAGS "--pre-js ${JS_CORE_RUN_PRE} --js-library ${JS_SYSTEM_NATIVE_BROWSER}"
64+
LINK_DEPENDS "${JS_CORE_RUN_PRE};${JS_SYSTEM_NATIVE_BROWSER};${JS_SYSTEM_BROWSER_UTILS};"
65+
LINK_FLAGS "--pre-js ${JS_CORE_RUN_PRE} --js-library ${JS_SYSTEM_NATIVE_BROWSER} --js-library ${JS_SYSTEM_BROWSER_UTILS}"
6466
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
6567
target_link_options(corerun PRIVATE
6668
-fwasm-exceptions

src/coreclr/hosts/corewasmrun/CMakeLists.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ target_compile_options(corewasmrun PRIVATE -fwasm-exceptions)
2020

2121
set(JS_SYSTEM_NATIVE_BROWSER
2222
"${CLR_ARTIFACTS_OBJ_DIR}/native/browser-${CMAKE_BUILD_TYPE}-wasm/System.Native.Browser/libSystem.Native.Browser.js")
23+
set(JS_SYSTEM_BROWSER_UTILS
24+
"${CLR_ARTIFACTS_OBJ_DIR}/native/browser-${CMAKE_BUILD_TYPE}-wasm/System.Native.Browser/libSystem.Browser.Utils.js")
2325
set(JS_CORE_WASM_RUN_PRE
2426
"${CMAKE_CURRENT_SOURCE_DIR}/libCorewasmrun.pre.js")
2527
set_target_properties(corewasmrun PROPERTIES
26-
LINK_DEPENDS "${JS_CORE_WASM_RUN_PRE};${JS_SYSTEM_NATIVE_BROWSER};"
27-
LINK_FLAGS "--pre-js ${JS_CORE_WASM_RUN_PRE} --js-library ${JS_SYSTEM_NATIVE_BROWSER}"
28+
LINK_DEPENDS "${JS_CORE_WASM_RUN_PRE};${JS_SYSTEM_NATIVE_BROWSER};${JS_SYSTEM_BROWSER_UTILS};"
29+
LINK_FLAGS "--pre-js ${JS_CORE_WASM_RUN_PRE} --js-library ${JS_SYSTEM_NATIVE_BROWSER} --js-library ${JS_SYSTEM_BROWSER_UTILS}"
2830
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
2931
target_link_options(corewasmrun PRIVATE
3032
-fwasm-exceptions

src/native/.eslintignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
11
./corehost/browserhost/loader/dotnet.d.ts
2-
./**/*.js
3-
./**/*.mjs

src/native/.eslintrc.cjs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ module.exports = {
2020
"node_modules/**/*.*",
2121
"bin/**/*.*",
2222
"obj/**/*.*",
23-
"**/*.js",
24-
"**/*.mjs",
2523
"dotnet.d.ts",
2624
],
2725
"rules": {

src/native/corehost/browserhost/CMakeLists.txt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ target_compile_options(browserhost PRIVATE
5050

5151
set(JS_SYSTEM_NATIVE_BROWSER
5252
"${CLR_ARTIFACTS_OBJ_DIR}/native/browser-${CMAKE_BUILD_TYPE}-wasm/System.Native.Browser/libSystem.Native.Browser.js")
53+
set(JS_SYSTEM_BROWSER_UTILS
54+
"${CLR_ARTIFACTS_OBJ_DIR}/native/browser-${CMAKE_BUILD_TYPE}-wasm/System.Native.Browser/libSystem.Browser.Utils.js")
5355
set(JS_SYSTEM_RUNTIME_INTEROPSERVICES_JAVASCRIPT_NATIVE
5456
"${CLR_ARTIFACTS_OBJ_DIR}/native/browser-${CMAKE_BUILD_TYPE}-wasm/System.Runtime.InteropServices.JavaScript.Native/libSystem.Runtime.InteropServices.JavaScript.Native.js")
5557
set(JS_BROWSER_HOST
@@ -58,8 +60,8 @@ set(JS_SYSTEM_NATIVE_BROWSER_EXPOST
5860
"${CMAKE_CURRENT_SOURCE_DIR}/../../libs/System.Native.Browser/libSystem.Native.Browser.extpost.js")
5961

6062
set_target_properties(browserhost PROPERTIES
61-
LINK_DEPENDS "${JS_SYSTEM_NATIVE_BROWSER};${JS_SYSTEM_RUNTIME_INTEROPSERVICES_JAVASCRIPT_NATIVE};${JS_BROWSER_HOST};${JS_SYSTEM_NATIVE_BROWSER_EXPOST};"
62-
LINK_FLAGS "--js-library ${JS_SYSTEM_NATIVE_BROWSER} --js-library ${JS_SYSTEM_RUNTIME_INTEROPSERVICES_JAVASCRIPT_NATIVE} --js-library ${JS_BROWSER_HOST} --extern-post-js ${JS_SYSTEM_NATIVE_BROWSER_EXPOST}"
63+
LINK_DEPENDS "${JS_SYSTEM_NATIVE_BROWSER};${JS_SYSTEM_BROWSER_UTILS};${JS_SYSTEM_RUNTIME_INTEROPSERVICES_JAVASCRIPT_NATIVE};${JS_BROWSER_HOST};${JS_SYSTEM_NATIVE_BROWSER_EXPOST};"
64+
LINK_FLAGS "--js-library ${JS_SYSTEM_NATIVE_BROWSER} --js-library ${JS_SYSTEM_BROWSER_UTILS} --js-library ${JS_SYSTEM_RUNTIME_INTEROPSERVICES_JAVASCRIPT_NATIVE} --js-library ${JS_BROWSER_HOST} --extern-post-js ${JS_SYSTEM_NATIVE_BROWSER_EXPOST}"
6365
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
6466

6567
if (UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG)
@@ -72,9 +74,9 @@ if (UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG)
7274
)
7375
endif ()
7476

75-
# TODO-WASM -sWASM_BIGINT=1
76-
# TODO-WASM -emit-llvm
77-
# TODO-WASM --source-map-base http://microsoft.com
77+
# WASM-TODO -sWASM_BIGINT=1
78+
# WASM-TODO -emit-llvm
79+
# WASM-TODO --source-map-base http://microsoft.com
7880
target_link_options(browserhost PRIVATE
7981
-sINITIAL_MEMORY=134217728
8082
-sMAXIMUM_MEMORY=2147483648
@@ -85,7 +87,7 @@ target_link_options(browserhost PRIVATE
8587
-sEXPORT_ES6=1
8688
-sEXIT_RUNTIME=0
8789
-sEXPORTED_RUNTIME_METHODS=UTF8ToString,cwrap,ccall,HEAPU8,HEAPU32,HEAPU64,BROWSER_HOST
88-
-sEXPORTED_FUNCTIONS=_posix_memalign,_free,stackAlloc,stackRestore,stackSave,_browserHostInitializeCoreCLR,_browserHostExecuteAssembly,___cpp_exception
90+
-sEXPORTED_FUNCTIONS=_posix_memalign,_free,stackAlloc,stackRestore,stackSave,_BrowserHost_InitializeCoreCLR,_BrowserHost_ExecuteAssembly,___cpp_exception
8991
-sEXPORT_NAME=createDotnetRuntime
9092
-fwasm-exceptions
9193
-msimd128

src/native/corehost/browserhost/ReadMe.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ It is **Emscripten application** statically linked from libraries.
1919
- `host/index.ts` -> compiled -> `libBrowserHost.js` linked -> `dotnet.native.js`
2020
- `libBrowserHost.footer.js` -> compiled -> `libBrowserHost.js` linked -> `dotnet.native.js`
2121
- `libSystem.Native.Browser.js` linked -> `dotnet.native.js`
22+
- `libSystem.Browser.Utils.js` linked -> `dotnet.native.js`
2223
- `libSystem.Runtime.InteropServices.JavaScript.Native.js` linked -> `dotnet.native.js`
2324
- `browserhost.cpp` compiled + linked -> `dotnet.native.wasm`
2425
- `libSystem.Native.Browser.a` linked -> `dotnet.native.wasm`

src/native/corehost/browserhost/browserhost.cpp

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ extern "C"
5050
const void* GlobalizationResolveDllImport(const char* name);
5151
const void* CompressionResolveDllImport(const char* name);
5252

53-
bool browserHostExternalAssemblyProbe(const char* pathPtr, /*out*/ void **outDataStartPtr, /*out*/ int64_t* outSize);
54-
void browserHostResolveMain(int exitCode);
55-
void browserHostRejectMain(const char *reason);
53+
bool BrowserHost_ExternalAssemblyProbe(const char* pathPtr, /*out*/ void **outDataStartPtr, /*out*/ int64_t* outSize);
54+
void BrowserHost_ResolveMain(int exitCode);
55+
void BrowserHost_RejectMain(const char *reason);
5656
}
5757

5858
// The current CoreCLR instance details.
@@ -64,13 +64,6 @@ static void log_error_info(const char* line)
6464
std::fprintf(stderr, "log error: %s\n", line);
6565
}
6666

67-
static bool external_assembly_probe(const char* path, /*out*/ void **data_start, /*out*/ int64_t* size)
68-
{
69-
*size = 0;
70-
*data_start = nullptr;
71-
return browserHostExternalAssemblyProbe(path, data_start, size);;
72-
}
73-
7467
static const void* pinvoke_override(const char* library_name, const char* entry_point_name)
7568
{
7669
if (strcmp(library_name, "libSystem.Native") == 0)
@@ -107,9 +100,11 @@ static std::vector<const char*> propertyKeys;
107100
static std::vector<const char*> propertyValues;
108101
static pal::char_t ptr_to_string_buffer[STRING_LENGTH("0xffffffffffffffff") + 1];
109102

110-
extern "C" int browserHostInitializeCoreCLR(void)
103+
// WASM-TODO: pass TPA via argument, not env
104+
// WASM-TODO: pass app_path via argument, not env
105+
// WASM-TODO: pass search_paths via argument, not env
106+
extern "C" int BrowserHost_InitializeCoreCLR(void)
111107
{
112-
//WASM-TODO: does getenv return UTF8 ?
113108
pal::getenv(HOST_PROPERTY_APP_PATHS, &app_path);
114109
pal::getenv(HOST_PROPERTY_NATIVE_DLL_SEARCH_DIRECTORIES, &search_paths);
115110
pal::getenv(HOST_PROPERTY_TRUSTED_PLATFORM_ASSEMBLIES, &tpa);
@@ -124,7 +119,7 @@ extern "C" int browserHostInitializeCoreCLR(void)
124119

125120
host_runtime_contract host_contract = { sizeof(host_runtime_contract), nullptr };
126121
host_contract.pinvoke_override = &pinvoke_override;
127-
host_contract.external_assembly_probe = &external_assembly_probe;
122+
host_contract.external_assembly_probe = &BrowserHost_ExternalAssemblyProbe;
128123

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

@@ -144,7 +139,8 @@ extern "C" int browserHostInitializeCoreCLR(void)
144139
}
145140

146141
// WASM-TODO: browser needs async entrypoint
147-
extern "C" int browserHostExecuteAssembly(const char* assemblyPath)
142+
// WASM-TODO: don't coreclr_shutdown_2 when browser
143+
extern "C" int BrowserHost_ExecuteAssembly(const char* assemblyPath)
148144
{
149145
int exit_code;
150146
int retval = coreclr_execute_assembly(CurrentClrInstance, CurrentAppDomainId, 0, nullptr, assemblyPath, (uint32_t*)&exit_code);
@@ -164,11 +160,11 @@ extern "C" int browserHostExecuteAssembly(const char* assemblyPath)
164160
std::fprintf(stderr, "coreclr_shutdown_2 failed - Error: 0x%08x\n", retval);
165161
exit_code = -1;
166162
// WASM-TODO: this is too trivial
167-
browserHostRejectMain("coreclr_shutdown_2 failed");
163+
BrowserHost_RejectMain("coreclr_shutdown_2 failed");
168164
}
169165

170166
// WASM-TODO: this is too trivial
171167
// because nothing runs continuations yet and also coreclr_execute_assembly is sync looping
172-
browserHostResolveMain(exit_code);
168+
BrowserHost_ResolveMain(exit_code);
173169
return retval;
174170
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
import { } from "../../../libs/Common/JavaScript/cross-linked";
5+
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
import type { CharPtr, VoidPtr, VoidPtrPtr } from "./types";
5+
import { } from "./cross-linked"; // ensure ambient symbols are declared
6+
7+
const loadedAssemblies : Map<string, { ptr: number, length: number }> = new Map();
8+
9+
export function registerDllBytes(bytes: Uint8Array, asset: { name: string }) {
10+
const sp = Module.stackSave();
11+
try {
12+
const sizeOfPtr = 4;
13+
const ptrPtr = Module.stackAlloc(sizeOfPtr);
14+
if (Module._posix_memalign(ptrPtr as any, 16, bytes.length)) {
15+
throw new Error("posix_memalign failed");
16+
}
17+
18+
const ptr = Module.HEAPU32[ptrPtr as any >>> 2];
19+
Module.HEAPU8.set(bytes, ptr);
20+
loadedAssemblies.set(asset.name, { ptr, length: bytes.length });
21+
} finally {
22+
Module.stackRestore(sp);
23+
}
24+
}
25+
26+
// bool BrowserHost_ExternalAssemblyProbe(const char* pathPtr, /*out*/ void **outDataStartPtr, /*out*/ int64_t* outSize);
27+
export function BrowserHost_ExternalAssemblyProbe(pathPtr:CharPtr, outDataStartPtr:VoidPtrPtr, outSize:VoidPtr) {
28+
const path = Module.UTF8ToString(pathPtr);
29+
const assembly = loadedAssemblies.get(path);
30+
if (assembly) {
31+
Module.HEAPU32[outDataStartPtr as any >>> 2] = assembly.ptr;
32+
// int64_t target
33+
Module.HEAPU32[outSize as any >>> 2] = assembly.length;
34+
Module.HEAPU32[((outSize as any) + 4) >>> 2] = 0;
35+
return true;
36+
}
37+
Module.HEAPU32[outDataStartPtr as any >>> 2] = 0;
38+
Module.HEAPU32[outSize as any >>> 2] = 0;
39+
Module.HEAPU32[((outSize as any) + 4) >>> 2] = 0;
40+
return false;
41+
}
42+
43+
export function BrowserHost_ResolveMain(exitCode:number) {
44+
dotnetLoaderExports.resolveRunMainPromise(exitCode);
45+
}
46+
47+
export function BrowserHost_RejectMain(reason:any) {
48+
dotnetLoaderExports.rejectRunMainPromise(reason);
49+
}
50+
51+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
52+
export async function runMain(mainAssemblyName?: string, args?: string[]): Promise<number> {
53+
// int BrowserHost_ExecuteAssembly(char * assemblyPath)
54+
const res = Module.ccall("BrowserHost_ExecuteAssembly", "number", ["string"], [mainAssemblyName]) as number;
55+
if (res != 0) {
56+
const reason = new Error("Failed to execute assembly");
57+
dotnetApi.exit(res, reason);
58+
throw reason;
59+
}
60+
61+
return dotnetLoaderExports.getRunMainPromise();
62+
}
63+
64+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
65+
export async function runMainAndExit(mainAssemblyName?: string, args?: string[]): Promise<number> {
66+
try {
67+
await runMain(mainAssemblyName, args);
68+
} catch (error) {
69+
dotnetApi.exit(1, error);
70+
throw error;
71+
}
72+
dotnetApi.exit(0, null);
73+
return 0;
74+
}
75+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
import type { InternalExchange, BrowserHostExports, RuntimeAPI, BrowserHostExportsTable } from "./types";
5+
import { InternalExchangeIndex } from "./types";
6+
import { } from "./cross-linked"; // ensure ambient symbols are declared
7+
8+
import { runMain, runMainAndExit, registerDllBytes } from "./host";
9+
10+
export function dotnetInitializeModule(internals: InternalExchange): void {
11+
const runtimeApiLocal: Partial<RuntimeAPI> = {
12+
runMain,
13+
runMainAndExit,
14+
};
15+
Object.assign(internals[InternalExchangeIndex.RuntimeAPI], runtimeApiLocal);
16+
17+
internals[InternalExchangeIndex.BrowserHostExportsTable] = browserHostExportsToTable({
18+
registerDllBytes,
19+
});
20+
dotnetUpdateInternals(internals, dotnetUpdateInternalsSubscriber);
21+
function browserHostExportsToTable(map:BrowserHostExports):BrowserHostExportsTable {
22+
// keep in sync with browserHostExportsFromTable()
23+
return [
24+
map.registerDllBytes,
25+
];
26+
}
27+
}
28+
29+
export { BrowserHost_ExternalAssemblyProbe, BrowserHost_ResolveMain, BrowserHost_RejectMain } from "./host";

0 commit comments

Comments
 (0)