-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement
Stream.HasOverridenBeginEndXXX
(#72252)
Fixes dotnet/corert#3251. `Stream.HasOverriddenBeginEndRead`/`Stream.HasOverriddenBeginEndWrite` are magic methods that call into the runtime on both CoreCLR and Mono to find out whether `Stream.BeginRead`/`EndRead`/`BeginWrite`/`EndWrite` are overriden on the current class. Since we don't have a runtime in NativeAOT, implement this in the compiler. The answer to this question is expressible in IL: load function pointer to the method virtually and non-virtually and compare. I'm not calling into `FunctionPointerOps` because I can't imagine a scenario where this wouldn't work, but I can be persuaded to call to `FunctionPointerOps` to do the comparison. Should make us pass all System.IO libraries tests.
- Loading branch information
1 parent
96cac6b
commit fae5314
Showing
6 changed files
with
68 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
src/coreclr/tools/Common/TypeSystem/IL/Stubs/StreamIntrinsics.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters