Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
d114103
rebase
pavelsavara Oct 22, 2025
4f633d3
wip
pavelsavara Oct 22, 2025
27daa57
cleanup
pavelsavara Oct 22, 2025
775afc3
cleanup
pavelsavara Oct 22, 2025
53facd5
Update src/coreclr/vm/qcallentrypoints.cpp
pavelsavara Oct 23, 2025
58b16dd
Update src/coreclr/vm/qcallentrypoints.cpp
pavelsavara Oct 23, 2025
3f36576
Update src/coreclr/vm/assembly.cpp
pavelsavara Oct 23, 2025
f76d16c
Update src/coreclr/vm/assembly.cpp
pavelsavara Oct 23, 2025
c03375c
Update src/coreclr/vm/assembly.cpp
pavelsavara Oct 23, 2025
cfd23db
Update src/coreclr/vm/assembly.cpp
pavelsavara Oct 23, 2025
e823885
Update src/coreclr/vm/qcallentrypoints.cpp
pavelsavara Oct 23, 2025
72fa2de
Update src/coreclr/vm/wasm/helpers.cpp
pavelsavara Oct 23, 2025
f533328
Update src/coreclr/vm/wasm/helpers.cpp
pavelsavara Oct 23, 2025
7e95e6d
Update src/coreclr/vm/assembly.cpp
pavelsavara Oct 23, 2025
cebd055
Update src/coreclr/vm/assembly.cpp
pavelsavara Oct 23, 2025
66f38f2
Update src/coreclr/vm/assembly.cpp
pavelsavara Oct 23, 2025
7586670
Update src/coreclr/vm/assembly.cpp
pavelsavara Oct 23, 2025
bad0ec9
Update src/coreclr/vm/assembly.cpp
pavelsavara Oct 23, 2025
748dcc3
Update src/coreclr/vm/assembly.cpp
pavelsavara Oct 23, 2025
7803d72
feedback
pavelsavara Oct 23, 2025
e3e48c5
Merge branch 'main' into browser_async_main
pavelsavara Oct 24, 2025
063a40c
wip
pavelsavara Oct 24, 2025
f6ce84a
Merge branch 'main' into browser_async_main
pavelsavara Oct 27, 2025
d20157a
feedback
pavelsavara Oct 27, 2025
f210f97
propagate exit code and exception for corerun
pavelsavara Oct 27, 2025
a3a4cd4
Merge branch 'main' into browser_async_main
pavelsavara Oct 27, 2025
2bcffb1
fix browserhost
pavelsavara Oct 27, 2025
409c2f1
fix
pavelsavara Oct 27, 2025
d85edbc
fix
pavelsavara Oct 27, 2025
e0e16a5
Update src/native/corehost/browserhost/host/host.ts
pavelsavara Oct 27, 2025
0af8464
Update src/native/libs/System.Native.Browser/utils/strings.ts
pavelsavara Oct 27, 2025
38c6ead
feedback
pavelsavara Oct 27, 2025
2ad67c9
cleanup
pavelsavara Oct 27, 2025
f439d0c
Merge branch 'main' into browser_async_main
pavelsavara Oct 29, 2025
1c23039
implement https://github.com/dotnet/runtime/issues/121046
pavelsavara Oct 29, 2025
2f62f04
Update src/libraries/System.Private.CoreLib/src/System/Runtime/Compil…
pavelsavara Oct 29, 2025
e62473b
feedback
pavelsavara Oct 29, 2025
6730a82
Update src/coreclr/vm/assembly.cpp
pavelsavara Oct 30, 2025
9565dbb
feedback
pavelsavara Oct 30, 2025
9ed35b1
Merge branch 'main' into browser_async_main
pavelsavara Oct 30, 2025
55a5f6e
fix
pavelsavara Oct 30, 2025
8383b8a
feedback
pavelsavara Oct 31, 2025
6795541
Merge branch 'main' into browser_async_main
pavelsavara Oct 31, 2025
f54121f
GCPROTECT_BEGIN
pavelsavara Nov 3, 2025
8e748fd
Merge branch 'main' into browser_async_main
pavelsavara Nov 3, 2025
cae9ae9
Update src/libraries/System.Private.CoreLib/src/System/Runtime/Compil…
pavelsavara Nov 3, 2025
efd3396
Update src/libraries/System.Private.CoreLib/src/System/Runtime/Compil…
pavelsavara Nov 3, 2025
8cf4102
Update src/libraries/System.Private.CoreLib/src/System/Runtime/Compil…
pavelsavara Nov 3, 2025
ab944ff
Update src/coreclr/vm/assembly.cpp
pavelsavara Nov 3, 2025
6ae68d6
Update src/coreclr/vm/assembly.cpp
pavelsavara Nov 3, 2025
ff4dbe0
doc feedback
pavelsavara Nov 3, 2025
0a423d0
Merge branch 'main' into browser_async_main
pavelsavara Nov 3, 2025
78bdb31
Update src/coreclr/vm/assembly.cpp
pavelsavara Nov 4, 2025
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
6 changes: 6 additions & 0 deletions docs/workflow/building/coreclr/wasm.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ In config below please replace `/path/to/runtime/` by a **absolute unix path** t
"env": {
"CORE_ROOT":"/path/to/runtime/artifacts/bin/coreclr/browser.wasm.Debug/IL/"
},
"runtimeArgs": [
"--stack-trace-limit=1000"
],
"args": [
"/path/to/runtime/artifacts/bin/coreclr/browser.wasm.Debug/IL/helloworld.dll"
],
Expand All @@ -140,6 +143,9 @@ In config below please replace `/path/to/runtime/` by a **absolute unix path** t
"skipFiles": [
"<node_internals>/**"
],
"runtimeArgs": [
"--stack-trace-limit=1000"
],
"args": [
"HelloWorld.dll"
],
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/hosts/corerun/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,13 @@ else()
LINK_FLAGS "--pre-js ${JS_CORE_RUN_PRE} --js-library ${JS_SYSTEM_NATIVE_BROWSER} --js-library ${JS_SYSTEM_BROWSER_UTILS}"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
target_link_options(corerun PRIVATE
-sEXIT_RUNTIME=1
-sEXIT_RUNTIME=0
-sINITIAL_MEMORY=134217728
-sMAXIMUM_MEMORY=2147483648
-sALLOW_MEMORY_GROWTH=1
-sSTACK_SIZE=5MB
-sWASM_BIGINT=1
-sEXPORTED_RUNTIME_METHODS=cwrap,ccall,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAP64,HEAPU64,HEAPF32,HEAPF64,safeSetTimeout,maybeExit,exitJS,abort,lengthBytesUTF8,UTF8ToString,stringToUTF8Array
-sEXPORTED_FUNCTIONS=_main,_GetDotNetRuntimeContractDescriptor
-sENVIRONMENT=node,shell,web
-Wl,-error-limit=0)
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/hosts/corerun/corerun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,7 @@ static int run(const configuration& config)
actions.after_execute_assembly();
}

#if !defined(TARGET_BROWSER)
int latched_exit_code = 0;
result = coreclr_shutdown2_func(CurrentClrInstance, CurrentAppDomainId, &latched_exit_code);
if (FAILED(result))
Expand All @@ -553,6 +554,10 @@ static int run(const configuration& config)
::free((void*)s_core_libs_path);
::free((void*)s_core_root_path);
return exit_code;
#else // TARGET_BROWSER
// In browser we don't shutdown the runtime here as we want to keep it alive
return 0;
#endif // TARGET_BROWSER
}

// Display the command line options
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/vm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,9 @@ elseif(CLR_CMAKE_TARGET_ARCH_RISCV64)
gcinfodecoder.cpp
)
elseif(CLR_CMAKE_TARGET_ARCH_WASM)
set(VM_HEADERS_WKS_ARCH_ASM
${ARCH_SOURCES_DIR}/entrypoints.h
)
set(VM_SOURCES_WKS_ARCH
${ARCH_SOURCES_DIR}/calldescrworkerwasm.cpp
${ARCH_SOURCES_DIR}/profiler.cpp
Expand Down
97 changes: 93 additions & 4 deletions src/coreclr/vm/assembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1060,8 +1060,10 @@ void Assembly::AddDiagnosticStartupHookPath(LPCWSTR wszPath)

enum CorEntryPointType
{
EntryManagedMain, // void main(String[])
EntryCrtMain // unsigned main(void)
EntryManagedMain, // void/int/uint Main(string[])
EntryCrtMain, // void/int/uint Main(void)
EntryManagedMainAsync, // Task<int> Main(String[])
EntryManagedMainAsyncVoid, // Task Main(String[])
};

void DECLSPEC_NORETURN ThrowMainMethodException(MethodDesc* pMD, UINT resID)
Expand Down Expand Up @@ -1127,6 +1129,29 @@ void ValidateMainMethod(MethodDesc * pFD, CorEntryPointType *pType)
if (FAILED(sig.GetElemType(&nReturnType)))
ThrowMainMethodException(pFD, BFA_BAD_SIGNATURE);

#if defined(TARGET_BROWSER)
// WASM-TODO: this validation is too trivial, but that's OK for now because we plan to remove browser specific hack later.
// https://github.com/dotnet/runtime/issues/121064
if (nReturnType == ELEMENT_TYPE_GENERICINST)
{
if (nParamCount > 1)
ThrowMainMethodException(pFD, IDS_EE_TO_MANY_ARGUMENTS_IN_MAIN);

// this is Task<int> Main(String[] args)
*pType = EntryManagedMainAsync;
return;
}
if (nReturnType == ELEMENT_TYPE_CLASS)
{
if (nParamCount > 1)
ThrowMainMethodException(pFD, IDS_EE_TO_MANY_ARGUMENTS_IN_MAIN);

// this is Task Main(String[] args)
*pType = EntryManagedMainAsyncVoid;
return;
}
#endif // TARGET_BROWSER

if ((nReturnType != ELEMENT_TYPE_VOID) && (nReturnType != ELEMENT_TYPE_I4) && (nReturnType != ELEMENT_TYPE_U4))
ThrowMainMethodException(pFD, IDS_EE_MAIN_METHOD_HAS_INVALID_RTN);

Expand Down Expand Up @@ -1172,7 +1197,10 @@ static void RunMainInternal(Param* pParam)
GCPROTECT_BEGIN(StrArgArray);

// Build the parameter array and invoke the method.
if (pParam->EntryType == EntryManagedMain) {
if (pParam->EntryType == EntryManagedMain
|| pParam->EntryType == EntryManagedMainAsync
|| pParam->EntryType == EntryManagedMainAsyncVoid)
{
if (pParam->stringArgs == NULL) {
// Allocate a COM Array object with enough slots for cCommandArgs - 1
StrArgArray = (PTRARRAYREF) AllocateObjectArray((pParam->cCommandArgs - pParam->numSkipArgs), g_pStringClass);
Expand All @@ -1195,8 +1223,37 @@ static void RunMainInternal(Param* pParam)
*pParam->piRetVal = 0;
threadStart.Call(&stackVar);
}
// WASM-TODO: remove this
// https://github.com/dotnet/runtime/issues/121064
#if defined(TARGET_BROWSER)
else if (pParam->EntryType == EntryManagedMainAsync)
{
*pParam->piRetVal = 0;
MethodDescCallSite mainWrapper(METHOD__ASYNC_HELPERS__HANDLE_ASYNC_ENTRYPOINT);

OBJECTREF exitCodeTask = threadStart.Call_RetOBJECTREF(&stackVar);
ARG_SLOT stackVarWrapper[] =
{
ObjToArgSlot(exitCodeTask)
};
mainWrapper.Call(stackVarWrapper);
}
else if (pParam->EntryType == EntryManagedMainAsyncVoid)
{
*pParam->piRetVal = 0;
MethodDescCallSite mainWrapper(METHOD__ASYNC_HELPERS__HANDLE_ASYNC_ENTRYPOINT_VOID);

OBJECTREF exitCodeTask = threadStart.Call_RetOBJECTREF(&stackVar);
ARG_SLOT stackVarWrapper[] =
{
ObjToArgSlot(exitCodeTask)
};
mainWrapper.Call(stackVarWrapper);
}
#endif // TARGET_BROWSER
else
{
// Call the main method
*pParam->piRetVal = (INT32)threadStart.Call_RetArgSlot(&stackVar);
SetLatchedExitCode(*pParam->piRetVal);
}
Expand Down Expand Up @@ -1401,8 +1458,10 @@ INT32 Assembly::ExecuteMainMethod(PTRARRAYREF *stringArgs, BOOL waitForOtherThre
//to decide when the process should get torn down. So, don't call it from
// AppDomain.ExecuteAssembly()
if (pMeth) {
#if !defined(TARGET_BROWSER)
if (waitForOtherThreads)
RunMainPost();
#endif // !TARGET_BROWSER
}
else {
StackSString displayName;
Expand Down Expand Up @@ -1482,14 +1541,15 @@ MethodDesc* Assembly::GetEntryPoint()
COMPlusThrowHR(COR_E_BADIMAGEFORMAT, IDS_EE_ILLEGAL_TOKEN_FOR_MAIN, displayName);
}

MethodTable * pInitialMT;
if (mdParent != COR_GLOBAL_PARENT_TOKEN) {
GCX_COOP();
// This code needs a class init frame, because without it, the
// debugger will assume any code that results from searching for a
// type handle (ie, loading an assembly) is the first line of a program.
DebuggerClassInitMarkFrame __dcimf;

MethodTable * pInitialMT = ClassLoader::LoadTypeDefOrRefThrowing(pModule, mdParent,
pInitialMT = ClassLoader::LoadTypeDefOrRefThrowing(pModule, mdParent,
ClassLoader::ThrowIfNotFound,
ClassLoader::FailIfUninstDefOrRef).GetMethodTable();

Expand All @@ -1502,6 +1562,35 @@ MethodDesc* Assembly::GetEntryPoint()
m_pEntryPoint = pModule->FindMethod(mdEntry);
}

#if defined(TARGET_BROWSER)
// WASM-TODO: this lookup by name is too trivial, but that's OK for now because we plan to remove browser specific hack later.
// https://github.com/dotnet/runtime/issues/121064
if (m_pEntryPoint)
{
// if this is async method we need to find the original method, instead of the roslyn generated wrapper
LPCUTF8 szName = m_pEntryPoint->GetName();
size_t nameLength = strlen(szName);
LPCUTF8 szEnd = szName + nameLength - 1;
DWORD dwAttrs = m_pEntryPoint->GetAttrs();
if (IsMdSpecialName(dwAttrs) && (*szName == '<') && (*szEnd == '>'))
{
// look for "<Name>$"
LPUTF8 pszAsyncName = (LPUTF8)new char[nameLength + 2];
snprintf (pszAsyncName, nameLength + 2, "%s$", szName);
m_pEntryPoint = MemberLoader::FindMethodByName(pInitialMT, pszAsyncName);

if (m_pEntryPoint == NULL)
{
// look for "Name" by trimming the first and last character of "<Name>"
pszAsyncName [nameLength - 1] = '\0';
m_pEntryPoint = MemberLoader::FindMethodByName(pInitialMT, pszAsyncName + 1);
}

delete[] pszAsyncName;
}
}
#endif // TARGET_BROWSER

RETURN m_pEntryPoint;
}

Expand Down
11 changes: 11 additions & 0 deletions src/coreclr/vm/corelib.h
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,17 @@ DEFINE_METHOD(ASYNC_HELPERS, CAPTURE_CONTINUATION_CONTEXT, CaptureContinuat
DEFINE_METHOD(ASYNC_HELPERS, CAPTURE_CONTEXTS, CaptureContexts, NoSig)
DEFINE_METHOD(ASYNC_HELPERS, RESTORE_CONTEXTS, RestoreContexts, NoSig)

#ifdef TARGET_BROWSER
DEFINE_METHOD(ASYNC_HELPERS, HANDLE_ASYNC_ENTRYPOINT, HandleAsyncEntryPoint, SM_TaskOfInt_RetInt)
DEFINE_METHOD(ASYNC_HELPERS, HANDLE_ASYNC_ENTRYPOINT_VOID, HandleAsyncEntryPoint, SM_Task_RetVoid)

DEFINE_CLASS(TIMER_QUEUE, Threading, TimerQueue)
DEFINE_METHOD(TIMER_QUEUE, TIMER_HANDLER, TimerHandler, SM_RetVoid)

DEFINE_CLASS(THREAD_POOL, Threading, ThreadPool)
DEFINE_METHOD(THREAD_POOL, BACKGROUND_JOB_HANDLER, BackgroundJobHandler, SM_RetVoid)
#endif // TARGET_BROWSER

DEFINE_CLASS(SPAN_HELPERS, System, SpanHelpers)
DEFINE_METHOD(SPAN_HELPERS, MEMSET, Fill, SM_RefByte_Byte_UIntPtr_RetVoid)
DEFINE_METHOD(SPAN_HELPERS, MEMZERO, ClearWithoutReferences, SM_RefByte_UIntPtr_RetVoid)
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/vm/metasig.h
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,8 @@ DEFINE_METASIG_T(IM(RetTask, _, C(TASK)))

DEFINE_METASIG_T(IM(Exception_RetValueTask, C(EXCEPTION), g(VALUETASK)))
DEFINE_METASIG_T(IM(RetValueTask, _, g(VALUETASK)))
DEFINE_METASIG_T(SM(Task_RetVoid, C(TASK), v))
DEFINE_METASIG_T(SM(TaskOfInt_RetInt, GI(C(TASK_1), 1, i), i))

DEFINE_METASIG_T(GM(Exception_RetTaskOfT, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, C(EXCEPTION), GI(C(TASK_1), 1, M(0))))
DEFINE_METASIG_T(GM(T_RetTaskOfT, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, M(0), GI(C(TASK_1), 1, M(0))))
Expand Down
10 changes: 10 additions & 0 deletions src/coreclr/vm/qcallentrypoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@

#include "versionresilienthashcode.h"

#ifdef TARGET_BROWSER
#include "entrypoints.h"
#endif // TARGET_BROWSER

static const Entry s_QCall[] =
{
DllImportEntry(ArgIterator_Init)
Expand Down Expand Up @@ -540,6 +544,12 @@ static const Entry s_QCall[] =
DllImportEntry(IsInstanceOf_NoCacheLookup)
DllImportEntry(VersionResilientHashCode_TypeHashCode)
DllImportEntry(TailCallHelp_AllocTailCallArgBufferInternal)
#ifdef TARGET_BROWSER
DllImportEntry(SystemJS_ResolveMainPromise)
DllImportEntry(SystemJS_RejectMainPromise)
DllImportEntry(SystemJS_ScheduleTimer)
DllImportEntry(SystemJS_ScheduleBackgroundJob)
#endif // TARGET_BROWSER
};

const void* QCallResolveDllImport(const char* name)
Expand Down
18 changes: 18 additions & 0 deletions src/coreclr/vm/wasm/entrypoints.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#ifndef HAVE_WASM_ENTRYPOINTS_H
#define HAVE_WASM_ENTRYPOINTS_H

#include <stdint.h>
#include <string.h>

#ifdef TARGET_BROWSER
extern "C" void SystemJS_ResolveMainPromise(int exitCode);
extern "C" void SystemJS_RejectMainPromise(const char16_t *message, int messageLength, const char16_t *stackTrace, int stackTraceLength);
extern "C" void SystemJS_ScheduleTimer(int shortestDueTimeMs);
extern "C" void SystemJS_ScheduleBackgroundJob();

#endif

#endif // HAVE_WASM_ENTRYPOINTS_H
18 changes: 18 additions & 0 deletions src/coreclr/vm/wasm/helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -649,3 +649,21 @@ void InvokeUnmanagedMethod(MethodDesc *targetMethod, int8_t *pArgs, int8_t *pRet
{
PORTABILITY_ASSERT("Attempted to execute unmanaged code from interpreter on wasm, this is not yet implemented");
}

// WASM-TODO: use [UnmanagedCallersOnly] once is supported in wasm
// https://github.com/dotnet/runtime/issues/121006
extern "C" void SystemJS_ExecuteTimerCallback()
{
ARG_SLOT stackVarWrapper[] = { };
MethodDescCallSite timerHandler(METHOD__TIMER_QUEUE__TIMER_HANDLER);
timerHandler.Call(stackVarWrapper);
}

// WASM-TODO: use [UnmanagedCallersOnly] once is supported in wasm
// https://github.com/dotnet/runtime/issues/121006
extern "C" void SystemJS_ExecuteBackgroundJobCallback()
{
ARG_SLOT stackVarWrapper[] = { };
MethodDescCallSite backgroundJobHandler(METHOD__THREAD_POOL__BACKGROUND_JOB_HANDLER);
backgroundJobHandler.Call(stackVarWrapper);
}
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,8 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\BypassReadyToRunAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\AccessedThroughPropertyAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\AsyncHelpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\AsyncHelpers.Browser.cs" Condition="'$(TargetsBrowser)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\AsyncHelpers.NonBrowser.cs" Condition="'$(TargetsBrowser)' != 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\AsyncIteratorMethodBuilder.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\AsyncIteratorStateMachineAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\AsyncMethodBuilderAttribute.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace System.Runtime.CompilerServices
{
public static partial class AsyncHelpers
{
public static void HandleAsyncEntryPoint(Task task)
{
task.ContinueWith(t =>
{
if (t.IsCanceled)
{
CancelMainPromise();
}
else if (t.IsFaulted)
{
RejectMainPromise(t.Exception);
}
else
{
SystemJS_ResolveMainPromise(0);
}
}, TaskScheduler.Default);
}

public static int HandleAsyncEntryPoint(Task<int> task)
{
task.ContinueWith(t =>
{
if (t.IsCanceled)
{
CancelMainPromise();
}
else if (t.IsFaulted)
{
RejectMainPromise(t.Exception);
}
else
{
SystemJS_ResolveMainPromise(t.Result);
}
}, TaskScheduler.Default);
// dummy exit code, real exit code will be passed via SystemJS_ResolveMainPromise
return 0x0BADF00D;
}

private static void CancelMainPromise()
{
string message = "Task was canceled";
SystemJS_RejectMainPromise(message, message.Length, string.Empty, 0);
}

private static void RejectMainPromise(Exception ex)
{
Exception inner = ex.InnerException ?? ex;
string message = inner.GetType().Name + ": " + (inner.Message ?? "");
string stackTrace = inner.StackTrace ?? "";
SystemJS_RejectMainPromise(message, message.Length, stackTrace, stackTrace.Length);
}

[LibraryImport(RuntimeHelpers.QCall)]
private static unsafe partial void SystemJS_RejectMainPromise(
[MarshalAs(UnmanagedType.LPWStr)] string pMessage, int messageLength,
[MarshalAs(UnmanagedType.LPWStr)] string pStackTrace, int stackTraceLength);

[LibraryImport(RuntimeHelpers.QCall)]
private static partial void SystemJS_ResolveMainPromise(int exitCode);
}
}
Loading
Loading