Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Stream.HasOverridenBeginEndXXX #72252

Merged
merged 2 commits into from
Jul 16, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ private MethodIL TryGetIntrinsicMethodIL(MethodDesc method)
}
}
break;
case "Stream":
{
if (owningType.Namespace == "System.IO")
return StreamIntrinsics.EmitIL(method);
}
break;
}

return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;

using Internal.TypeSystem;

using Debug = System.Diagnostics.Debug;

namespace Internal.IL.Stubs
{
/// <summary>
/// Provides method bodies for System.IO.Stream intrinsics.
/// </summary>
public static class StreamIntrinsics
{
public static MethodIL EmitIL(MethodDesc method)
{
Debug.Assert(((MetadataType)method.OwningType).Name == "Stream");

bool isRead = method.Name == "HasOverriddenBeginEndRead";
if (!isRead && method.Name != "HasOverriddenBeginEndWrite")
return null;

TypeDesc streamClass = method.OwningType;
MethodDesc beginMethod = streamClass.GetMethod(isRead ? "BeginRead" : "BeginWrite", null);
MethodDesc endMethod = streamClass.GetMethod(isRead ? "EndRead" : "EndWrite", null);

ILEmitter emitter = new ILEmitter();
ILCodeStream codestream = emitter.NewCodeStream();

ILCodeLabel lOverriden = emitter.NewCodeLabel();

ILToken beginMethodToken = emitter.NewToken(beginMethod);
codestream.EmitLdArg(0);
codestream.Emit(ILOpcode.ldvirtftn, beginMethodToken);
codestream.Emit(ILOpcode.ldftn, beginMethodToken);
codestream.Emit(ILOpcode.bne_un, lOverriden);

ILToken endMethodToken = emitter.NewToken(endMethod);
codestream.EmitLdArg(0);
codestream.Emit(ILOpcode.ldvirtftn, endMethodToken);
codestream.Emit(ILOpcode.ldftn, endMethodToken);
codestream.Emit(ILOpcode.bne_un, lOverriden);

codestream.EmitLdc(0);
codestream.Emit(ILOpcode.ret);

codestream.EmitLabel(lOverriden);
codestream.EmitLdc(1);
codestream.Emit(ILOpcode.ret);

return emitter.Link(method);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,12 @@ protected override void EmitCode(NodeFactory factory, ref ARM64Emitter encoder,

case ReadyToRunHelperId.ResolveVirtualFunction:
{
// Not tested
encoder.EmitINT3();

MethodDesc targetMethod = (MethodDesc)Target;
if (targetMethod.OwningType.IsInterface)
{
// Not tested
encoder.EmitINT3();

encoder.EmitMOV(encoder.TargetRegister.Arg1, factory.InterfaceDispatchCell(targetMethod));
encoder.EmitJMP(factory.ExternSymbol("RhpResolveInterfaceMethod"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@
<Link>IL\Stubs\MethodBaseGetCurrentMethodThunk.Sorting.cs</Link>
</Compile>
<Compile Include="..\..\Common\TypeSystem\IL\Stubs\RuntimeHelpersIntrinsics.cs" Link="IL\Stubs\RuntimeHelpersIntrinsics.cs" />
<Compile Include="..\..\Common\TypeSystem\IL\Stubs\StreamIntrinsics.cs" Link="IL\Stubs\StreamIntrinsics.cs" />
<Compile Include="..\..\Common\TypeSystem\IL\Stubs\TypeGetTypeMethodThunk.cs">
<Link>IL\Stubs\TypeGetTypeMethodThunk.cs</Link>
</Compile>
Expand Down
16 changes: 2 additions & 14 deletions src/libraries/System.Private.CoreLib/src/System/IO/Stream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -449,17 +449,13 @@ private async ValueTask<int> ReadAtLeastAsyncCore(Memory<byte> buffer, int minim
return totalRead;
}

#if NATIVEAOT // TODO: https://github.com/dotnet/corert/issues/3251
private static bool HasOverriddenBeginEndRead() => true;

private static bool HasOverriddenBeginEndWrite() => true;
#else
[Intrinsic]
[MethodImpl(MethodImplOptions.InternalCall)]
private extern bool HasOverriddenBeginEndRead();

[Intrinsic]
[MethodImpl(MethodImplOptions.InternalCall)]
private extern bool HasOverriddenBeginEndWrite();
#endif

private Task<int> BeginEndReadAsync(byte[] buffer, int offset, int count)
{
Expand Down Expand Up @@ -1227,9 +1223,6 @@ public override int ReadByte()

public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
{
#if NATIVEAOT
throw new NotImplementedException(); // TODO: https://github.com/dotnet/corert/issues/3251
#else
bool overridesBeginRead = _stream.HasOverriddenBeginEndRead();

lock (_stream)
Expand All @@ -1244,7 +1237,6 @@ public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, Asy
_stream.BeginRead(buffer, offset, count, callback, state) :
_stream.BeginReadInternal(buffer, offset, count, callback, state, serializeAsynchronously: true, apm: true);
}
#endif
}

public override int EndRead(IAsyncResult asyncResult)
Expand Down Expand Up @@ -1302,9 +1294,6 @@ public override void WriteByte(byte b)

public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
{
#if NATIVEAOT
throw new NotImplementedException(); // TODO: https://github.com/dotnet/corert/issues/3251
#else
bool overridesBeginWrite = _stream.HasOverriddenBeginEndWrite();

lock (_stream)
Expand All @@ -1319,7 +1308,6 @@ public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, As
_stream.BeginWrite(buffer, offset, count, callback, state) :
_stream.BeginWriteInternal(buffer, offset, count, callback, state, serializeAsynchronously: true, apm: true);
}
#endif
}

public override void EndWrite(IAsyncResult asyncResult)
Expand Down
1 change: 0 additions & 1 deletion src/libraries/tests.proj
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,6 @@
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Globalization\tests\System.Globalization.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Globalization\tests\NlsTests\System.Globalization.Nls.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Globalization.Calendars\tests\CalendarTestWithConfigSwitch\System.Globalization.CalendarsWithConfigSwitch.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.IO\tests\System.IO.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Linq.Queryable\tests\System.Linq.Queryable.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Management\tests\System.Management.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Net.WebSockets\tests\System.Net.WebSockets.Tests.csproj" />
Expand Down