Skip to content

Commit

Permalink
Merge branch 'main' into disable-shakeread-azl
Browse files Browse the repository at this point in the history
  • Loading branch information
vcsjones authored Feb 1, 2025
2 parents a34ce4a + ad7b829 commit 72c83d2
Show file tree
Hide file tree
Showing 92 changed files with 2,687 additions and 1,307 deletions.
5 changes: 0 additions & 5 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,6 @@
<WasmCommonTargetsPath>$([MSBuild]::NormalizeDirectory($(WasmProjectRoot), 'build'))</WasmCommonTargetsPath>
</PropertyGroup>

<PropertyGroup Condition="'$(DotNetBuildRuntimeNativeAOTRuntimePack)' == 'true'">
<BuildNativeAOTRuntimePack>true</BuildNativeAOTRuntimePack>
<SkipLibrariesNativeRuntimePackages>true</SkipLibrariesNativeRuntimePackages>
</PropertyGroup>

<PropertyGroup Condition="'$(DotNetBuildMonoCrossAOT)' == 'true'">
<BuildMonoAOTCrossCompilerOnly>true</BuildMonoAOTCrossCompilerOnly>
<MonoCrossAOTTargetOS>android+browser+wasi</MonoCrossAOTTargetOS>
Expand Down
44 changes: 16 additions & 28 deletions docs/design/specs/runtime-async.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ These are proposed modifications to the ECMA-335 specification for runtime-async

### I.8.4.5 Sync and Async Methods

Methods may be either 'sync' or 'async'. Async method definitions are methods attributed with `[MethodImpl(MethodImplOptions.Async)]`. Inside async method bodies, certain methods are also invokable by a special signature encoding, described in [### I.8.6.1.5 Method signatures].
Methods may be either 'sync' or 'async'. Async method definitions are methods attributed with `[MethodImpl(MethodImplOptions.Async)]`.

Applicability of `MethodImplOptions.Async`:
* The `[MethodImpl(MethodImplOptions.Async)]` only has effect when applied to method definitions that return generic or nongeneric variants of Task or ValueTask.
Expand All @@ -21,30 +21,39 @@ Applicability of `MethodImplOptions.Async`:
* Applying `MethodImplOptions.Async` to methods with `byref` or `ref-like` parameters is invalid.
* Applying `MethodImplOptions.Async` to vararg methods is invalid.

_[Note: these rules operate before generic substitution, meaning that a method which only meets requirements after substitution would not be considered as valid.]_

Sync methods are all other methods.

Unlike sync methods, async methods support suspension. Suspension allows async methods to yield control flow back to their caller at certain well-defined suspension points, and resume execution of the remaining method at a later time or location, potentially on another thread.

Async methods also do not have matching return type conventions as sync methods. For sync methods, the stack should contain a value convertible to the stated return type before the `ret` instruction. For async methods, the stack should be empty in the case of `Task` or `ValueTask`, or the type argument in the case of `Task<T>` or `ValueTask<T>`.

Async methods support the following suspension points:
Async methods support suspension using one of the following methods:

* Calling another method through the secondary encoding described in [### I.8.6.1.5 Method signatures]. No special instructions need to be provided. If the callee suspends, the caller will suspend as well.
* Using new .NET runtime APIs to "await" an "INotifyCompletion" type. The signatures of these methods shall be:
```C#
namespace System.Runtime.CompilerServices
{
public static class RuntimeHelpers
{
[MethodImpl(MethodImplOptions.Async)]
public static Task AwaitAwaiterFromRuntimeAsync<TAwaiter>(TAwaiter awaiter) where TAwaiter : INotifyCompletion { ... }
public static void AwaitAwaiterFromRuntimeAsync<TAwaiter>(TAwaiter awaiter) where TAwaiter : INotifyCompletion { ... }
[MethodImpl(MethodImplOptions.Async)]
public static void UnsafeAwaitAwaiterFromRuntimeAsync<TAwaiter>(TAwaiter awaiter) where TAwaiter : ICriticalNotifyCompletion

[MethodImpl(MethodImplOptions.Async)]
public static void Await(Task task);
[MethodImpl(MethodImplOptions.Async)]
public static Task UnsafeAwaitAwaiterFromRuntimeAsync<TAwaiter>(TAwaiter awaiter) where TAwaiter : ICriticalNotifyCompletion
public static void Await(ValueTask task);
[MethodImpl(MethodImplOptions.Async)]
public static T Await<T>(Task<T> task);
[MethodImpl(MethodImplOptions.Async)]
public static T Await<T>(ValueTask<T> task);
}
}
```

Each of the above methods will have semantics analogous to the current AsyncTaskMethodBuilder.AwaitOnCompleted/AwaitUnsafeOnCompleted methods. After calling this method, it can be presumed that the task has completed.
These methods are only legal to call inside async methods. The `...AwaitAwaiter...` methods will have semantics analogous to the current `AsyncTaskMethodBuilder.AwaitOnCompleted/AwaitUnsafeOnCompleted` methods. After calling either method, it can be presumed that the task or awaiter has completed. The `Await` methods perform suspension like the `AwaitAwaiter...` methods, but are optimized for calling on the return value of a call to an async method. To achieve maximum performance, the IL sequence of two `call` instructions -- one to the async method and immediately one to the `Await` method -- should be preferred.

Only local variables which are "hoisted" may be used across suspension points. That is, only "hoisted" local variables will have their state preserved after returning from a suspension. On methods with the `localsinit` flag set, non-"hoisted" local variables will be initialized to their default value when resuming from suspension. Otherwise, these variables will have an undefined value. To identify "hoisted" local variables, they must have an optional custom modifier to the `System.Runtime.CompilerServices.HoistedLocal` class, which will be a new .NET runtime API. This custom modifier must be the last custom modifier on the variable. It is invalid for by-ref variables, or variables with a by-ref-like type, to be marked hoisted. Hoisted local variables are stored in managed memory and cannot be converted to unmanaged pointers without explicit pinning.
The code generator is free to ignore the `HoistedLocal` modifier if it can prove that this makes no observable difference in the execution of the generated program. This can be observable in diagnostics since it may mean the value of a local with the `HoistedLocal` modifier will not be available after certain suspension points.
Expand All @@ -59,31 +68,10 @@ Other restrictions are likely to be permanent, including
* Suspension points may not appear in exception handling blocks.
* Only four types will be supported as the return type for "runtime-async" methods: `System.Threading.Task`, `System.Threading.ValueTask`, `System.Threading.Task<T>`, and `System.Threading.ValueTask<T>`

All async methods effectively have two entry points, or signatures. The first signature is the one present in method definitions: a `Task` or `ValueTask` returning method. The second signature is a "secondary signature", described in further detail in [I.8.6.1.5 Method signatures].

Callers may retrieve a Task/ValueTask return type from an async method via calling its primary, definitional signature. This functionality is available in both sync and async methods.

### II.23.1.11 Flags for methods [MethodImplAttributes]

| Flag | Value | Description |
| ------------- | ------------- | ------------- |
| . . . | . . . | . . . |
|Async |0x0400 |Method is an Async Method.|

### I.8.6.1.5 Method signatures

The list of relevant components is augmented to include sync vs. async method types. Async methods have some additions to normal signature compatibility.

Async methods are capable of calling certain methods using an "unwrapping signature." The target method must return one of `Task`, `ValueTask`, `Task<T>`, or `ValueTask<T>`.

The unwrapping signature is generated based on the primary signature. The transformation is as follows:
* If the target method return type is `Task` or `ValueTask`, the return type of the unwrapping signature is `void` with the first custom modifier on the return type being the original type.
* Otherwise, the return type is the type argument of the return type (either ``Task`1`` or ``ValueTask`1``) with the first custom modifier on the return type being the original type.

It is an error to declare a method with an "unwrapping signature".

_[Note: these rules operate before generic substitution, meaning that a method which only meets requirements after substitution would not be considered as valid.]_

### II.15.4.6 async methods

In certain cases described in [I.8.6.1.5 Method signatures], MethodDef definitions for some methods may have two valid invocation signatures. All call sites to a "secondary" signature must use a MethodRef, even if the method is definined inside the same module or assembly. The "primary" definition can be called using a regular `MethodDef` token.
6 changes: 0 additions & 6 deletions eng/DotNetBuild.props
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,8 @@
<ShortStack Condition="'$(TargetOS)' == 'maccatalyst'">true</ShortStack>
<ShortStack Condition="'$(TargetOS)' == 'android'">true</ShortStack>
<ShortStack Condition="'$(TargetOS)' == 'linux-bionic'">true</ShortStack>
<!-- NativeAOT builds are short -->
<ShortStack Condition="'$(DotNetBuildRuntimeNativeAOTRuntimePack)' == 'true'">true</ShortStack>
<!-- Mono LLVM builds are short -->
<ShortStack Condition="'$(DotNetBuildMonoEnableLLVM)' == 'true' or '$(DotNetBuildMonoAOTEnableLLVM)' == 'true'">true</ShortStack>
<!-- Mono AOT cross compiler builds are short -->
<ShortStack Condition="'$(DotNetBuildMonoCrossAOT)' == 'true'">true</ShortStack>
</PropertyGroup>

<Target Name="GetRuntimeSourceBuildCommandConfiguration"
Expand Down Expand Up @@ -72,11 +68,9 @@
<InnerBuildArgs>$(InnerBuildArgs) /p:AdditionalRuntimeIdentifierParent=$(BaseOS) /p:BaseOS=$(BaseOS)</InnerBuildArgs>
<!-- Pass through special build modes controlled by properties -->
<InnerBuildArgs Condition="'$(DotNetBuildRuntimeWasmEnableThreads)' == 'true'">$(InnerBuildArgs) /p:WasmEnableThreads=true</InnerBuildArgs>
<InnerBuildArgs Condition="'$(DotNetBuildRuntimeNativeAOTRuntimePack)' != ''">$(InnerBuildArgs) /p:DotNetBuildRuntimeNativeAOTRuntimePack=$(DotNetBuildRuntimeNativeAOTRuntimePack)</InnerBuildArgs>
<InnerBuildArgs Condition="'$(DotNetBuildMonoEnableLLVM)' != ''">$(InnerBuildArgs) /p:MonoEnableLLVM=$(DotNetBuildMonoEnableLLVM)</InnerBuildArgs>
<InnerBuildArgs Condition="'$(DotNetBuildMonoAOTEnableLLVM)' != ''">$(InnerBuildArgs) /p:MonoAOTEnableLLVM=$(DotNetBuildMonoAOTEnableLLVM)</InnerBuildArgs>
<InnerBuildArgs Condition="'$(DotNetBuildMonoBundleLLVMOptimizer)' != ''">$(InnerBuildArgs) /p:MonoBundleLLVMOptimizer=$(DotNetBuildMonoBundleLLVMOptimizer)</InnerBuildArgs>
<InnerBuildArgs Condition="'$(DotNetBuildMonoCrossAOT)' != ''">$(InnerBuildArgs) /p:DotNetBuildMonoCrossAOT=$(DotNetBuildMonoCrossAOT)</InnerBuildArgs>
<InnerBuildArgs Condition="'$(DotNetBuildAllRuntimePacks)' != ''">$(InnerBuildArgs) /p:DotNetBuildAllRuntimePacks=$(DotNetBuildAllRuntimePacks)</InnerBuildArgs>
<InnerBuildArgs Condition="'$(PgoInstrument)' == 'true'">$(InnerBuildArgs) $(FlagParameterPrefix)pgoinstrument</InnerBuildArgs>

Expand Down
14 changes: 6 additions & 8 deletions eng/Subsets.props
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@
<DefaultSubsets Condition="'$(TargetsLinuxBionic)' == 'true' and '$(MonoSupported)' != 'true'">clr.nativeaotruntime+clr.nativeaotlibs+libs+packs</DefaultSubsets>
<!-- In source build, mono is only supported as primary runtime flavor. -->
<DefaultSubsets Condition="'$(DotNetBuildSourceOnly)' == 'true' and '$(PrimaryRuntimeFlavor)' != 'Mono'">clr+libs+tools+host+packs</DefaultSubsets>
<DefaultSubsets Condition="'$(DotNetBuildRuntimeNativeAOTRuntimePack)' == 'true'">clr.nativeaotlibs+clr.nativeaotruntime+libs+packs</DefaultSubsets>
<DefaultSubsets Condition="'$(DotNetBuildMonoCrossAOT)' == 'true'">mono+packs</DefaultSubsets>
</PropertyGroup>

Expand All @@ -85,7 +84,7 @@
<_subset Condition="'$(Subset)' != ''">+$(Subset.ToLowerInvariant())+</_subset>
<_subset Condition="'$(Subset)' == ''">+$(DefaultSubsets)+</_subset>
</PropertyGroup>


<PropertyGroup Condition="'$(RuntimeFlavor)' == ''">
<RuntimeFlavor Condition="('$(TargetsMobile)' == 'true' or '$(TargetsLinuxBionic)' == 'true') and ($(_subset.Contains('+clr.nativeaotlibs+')) or $(_subset.Contains('+clr.runtime+')))">CoreCLR</RuntimeFlavor>
Expand Down Expand Up @@ -605,11 +604,10 @@
</When>
<Otherwise>
<PropertyGroup>
<_BuildCoreCLRRuntimePack Condition="'$(RuntimeFlavor)' == 'CoreCLR' and '$(CoreCLRSupported)' == 'true' and '$(BuildNativeAOTRuntimePack)' != 'true'">true</_BuildCoreCLRRuntimePack>
<_BuildMonoRuntimePack Condition="'$(RuntimeFlavor)' == 'Mono' and '$(MonoSupported)' == 'true' and '$(BuildNativeAOTRuntimePack)' != 'true'">true</_BuildMonoRuntimePack>
<_BuildNativeAOTRuntimePack Condition="'$(BuildNativeAOTRuntimePack)' == 'true'">true</_BuildNativeAOTRuntimePack>
<_BuildHostPack Condition="'$(RuntimeFlavor)' == '$(PrimaryRuntimeFlavor)' and '$(TargetsMobile)' != 'true' and '$(BuildNativeAOTRuntimePack)' != 'true'">true</_BuildHostPack>
<_BuildBundle Condition="'$(BuildNativeAOTRuntimePack)' != 'true' and '$(RuntimeFlavor)' == '$(PrimaryRuntimeFlavor)' and '$(TargetsMobile)' != 'true'">true</_BuildBundle>
<_BuildCoreCLRRuntimePack Condition="'$(RuntimeFlavor)' == 'CoreCLR' and '$(CoreCLRSupported)' == 'true'">true</_BuildCoreCLRRuntimePack>
<_BuildMonoRuntimePack Condition="'$(RuntimeFlavor)' == 'Mono' and '$(MonoSupported)' == 'true'">true</_BuildMonoRuntimePack>
<_BuildHostPack Condition="'$(RuntimeFlavor)' == '$(PrimaryRuntimeFlavor)' and '$(TargetsMobile)' != 'true'">true</_BuildHostPack>
<_BuildBundle Condition="'$(RuntimeFlavor)' == '$(PrimaryRuntimeFlavor)' and '$(TargetsMobile)' != 'true'">true</_BuildBundle>
</PropertyGroup>

<PropertyGroup Condition="'$(DotNetBuildAllRuntimePacks)' == 'true' and '$(DotNetBuildSourceOnly)' != 'true'">
Expand All @@ -632,7 +630,7 @@
<ItemGroup>
<SharedFrameworkProjectToBuild Include="$(InstallerProjectRoot)pkg\sfx\Microsoft.NETCore.App\Microsoft.NETCore.App.Ref.sfxproj" />
</ItemGroup>
<ItemGroup Condition="'$(BuildNativeAOTRuntimePack)' != 'true'">
<ItemGroup>
<SharedFrameworkProjectToBuild Condition="'$(RuntimeFlavor)' != 'Mono' and ('$(TargetsMobile)' != 'true' and '$(TargetsLinuxBionic)' != 'true')" Include="$(InstallerProjectRoot)pkg\sfx\Microsoft.NETCore.App\Microsoft.NETCore.App.Crossgen2.sfxproj" />
<SharedFrameworkProjectToBuild Condition="'$(RuntimeFlavor)' == '$(PrimaryRuntimeFlavor)' and '$(TargetsMobile)' != 'true'" Include="$(InstallerProjectRoot)pkg\sfx\installers\dotnet-host.proj" />
<SharedFrameworkProjectToBuild Condition="'$(RuntimeFlavor)' == '$(PrimaryRuntimeFlavor)' and '$(TargetsMobile)' != 'true'" Include="$(InstallerProjectRoot)pkg\sfx\installers\dotnet-hostfxr.proj" />
Expand Down
Loading

0 comments on commit 72c83d2

Please sign in to comment.