diff options
-rw-r--r-- | src/mscorlib/src/System/IO/FileStream.cs | 3 | ||||
-rw-r--r-- | src/mscorlib/src/System/IO/Stream.cs | 27 | ||||
-rw-r--r-- | src/vm/comutilnative.cpp | 54 | ||||
-rw-r--r-- | src/vm/comutilnative.h | 6 | ||||
-rw-r--r-- | src/vm/ecalllist.h | 6 | ||||
-rw-r--r-- | src/vm/metasig.h | 4 | ||||
-rw-r--r-- | src/vm/mscorlib.h | 4 |
7 files changed, 86 insertions, 18 deletions
diff --git a/src/mscorlib/src/System/IO/FileStream.cs b/src/mscorlib/src/System/IO/FileStream.cs index 0952300dfb..3258940b53 100644 --- a/src/mscorlib/src/System/IO/FileStream.cs +++ b/src/mscorlib/src/System/IO/FileStream.cs @@ -1778,9 +1778,6 @@ namespace System.IO { return; } -#if FEATURE_CORECLR - internal override bool OverridesBeginEnd { get { return true; } } -#endif [System.Security.SecuritySafeCritical] // auto-generated [HostProtection(ExternalThreading = true)] diff --git a/src/mscorlib/src/System/IO/Stream.cs b/src/mscorlib/src/System/IO/Stream.cs index d62bcbd855..4a90945d22 100644 --- a/src/mscorlib/src/System/IO/Stream.cs +++ b/src/mscorlib/src/System/IO/Stream.cs @@ -285,19 +285,7 @@ namespace System.IO { return new ManualResetEvent(false); } - internal virtual bool OverridesBeginEnd - { - get - { -#if FEATURE_CORECLR - return false; // methods aren't exposed outside of mscorlib -#else - return true; // have to assume they are overridden as they're exposed -#endif - } - } - - [HostProtection(ExternalThreading=true)] + [HostProtection(ExternalThreading=true)] public virtual IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state) { Contract.Ensures(Contract.Result<IAsyncResult>() != null); @@ -438,9 +426,13 @@ namespace System.IO { : BeginEndReadAsync(buffer, offset, count); } + [System.Security.SecuritySafeCritical] + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private extern bool HasOverridenBeginEndRead(); + private Task<Int32> BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count) { - if (!OverridesBeginEnd) + if (!HasOverridenBeginEndRead()) { return (Task<Int32>)BeginReadInternal(buffer, offset, count, null, null, serializeAsynchronously: true, apm: false); } @@ -751,6 +743,8 @@ namespace System.IO { return WriteAsync(buffer, offset, count, CancellationToken.None); } + + [HostProtection(ExternalThreading = true)] [ComVisible(false)] public virtual Task WriteAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken) @@ -762,10 +756,13 @@ namespace System.IO { : BeginEndWriteAsync(buffer, offset, count); } + [System.Security.SecuritySafeCritical] + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private extern bool HasOverridenBeginEndWrite(); private Task BeginEndWriteAsync(Byte[] buffer, Int32 offset, Int32 count) { - if (!OverridesBeginEnd) + if (!HasOverridenBeginEndWrite()) { return (Task)BeginWriteInternal(buffer, offset, count, null, null, serializeAsynchronously: true, apm: false); } diff --git a/src/vm/comutilnative.cpp b/src/vm/comutilnative.cpp index 9664bf9325..1b21f12cda 100644 --- a/src/vm/comutilnative.cpp +++ b/src/vm/comutilnative.cpp @@ -3159,3 +3159,57 @@ INT32 QCALLTYPE CoreFxGlobalization::HashSortKey(PCBYTE pSortKey, INT32 cbSortKe return retVal; } #endif //FEATURE_COREFX_GLOBALIZATION + +static MethodTable * g_pStreamMT; +static WORD g_slotBeginRead, g_slotEndRead; +static WORD g_slotBeginWrite, g_slotEndWrite; + +FCIMPL1(FC_BOOL_RET, StreamNative::HasOverridenBeginEndRead, Object *stream) +{ + FCALL_CONTRACT; + + if (stream == NULL) + FC_RETURN_BOOL(TRUE); + + if (g_pStreamMT == NULL || g_slotBeginRead == 0 || g_slotEndRead == 0) + { + HELPER_METHOD_FRAME_BEGIN_RET_1(stream); + g_pStreamMT = MscorlibBinder::GetClass(CLASS__STREAM); + g_slotBeginRead = MscorlibBinder::GetMethod(METHOD__STREAM__BEGIN_READ)->GetSlot(); + g_slotEndRead = MscorlibBinder::GetMethod(METHOD__STREAM__END_READ)->GetSlot(); + HELPER_METHOD_FRAME_END(); + } + + MethodTable * pMT = stream->GetMethodTable(); + + FC_RETURN_BOOL( + pMT->GetRestoredSlot(g_slotBeginRead) != g_pStreamMT->GetRestoredSlot(g_slotBeginRead) || + pMT->GetRestoredSlot(g_slotEndRead) != g_pStreamMT->GetRestoredSlot(g_slotEndRead) + ); +} +FCIMPLEND + +FCIMPL1(FC_BOOL_RET, StreamNative::HasOverridenBeginEndWrite, Object *stream) +{ + FCALL_CONTRACT; + + if (stream == NULL) + FC_RETURN_BOOL(TRUE); + + if (g_pStreamMT == NULL || g_slotBeginWrite == 0 || g_slotEndWrite == 0) + { + HELPER_METHOD_FRAME_BEGIN_RET_1(stream); + g_pStreamMT = MscorlibBinder::GetClass(CLASS__STREAM); + g_slotBeginWrite = MscorlibBinder::GetMethod(METHOD__STREAM__BEGIN_WRITE)->GetSlot(); + g_slotEndWrite = MscorlibBinder::GetMethod(METHOD__STREAM__END_WRITE)->GetSlot(); + HELPER_METHOD_FRAME_END(); + } + + MethodTable * pMT = stream->GetMethodTable(); + + FC_RETURN_BOOL( + pMT->GetRestoredSlot(g_slotBeginWrite) != g_pStreamMT->GetRestoredSlot(g_slotBeginWrite) || + pMT->GetRestoredSlot(g_slotEndWrite) != g_pStreamMT->GetRestoredSlot(g_slotEndWrite) + ); +} +FCIMPLEND diff --git a/src/vm/comutilnative.h b/src/vm/comutilnative.h index 3a9b35a365..111619f25c 100644 --- a/src/vm/comutilnative.h +++ b/src/vm/comutilnative.h @@ -316,4 +316,10 @@ public: }; #endif // FEATURE_COREFX_GLOBALIZATION +class StreamNative { +public: + static FCDECL1(FC_BOOL_RET, HasOverridenBeginEndRead, Object *stream); + static FCDECL1(FC_BOOL_RET, HasOverridenBeginEndWrite, Object *stream); +}; + #endif // _COMUTILNATIVE_H_ diff --git a/src/vm/ecalllist.h b/src/vm/ecalllist.h index 504802b50d..7aa41efe41 100644 --- a/src/vm/ecalllist.h +++ b/src/vm/ecalllist.h @@ -2069,6 +2069,11 @@ FCFuncStart(gVersioningHelperFuncs) FCFuncElement("GetRuntimeId", GetRuntimeId_Wrapper) FCFuncEnd() +FCFuncStart(gStreamFuncs) + FCFuncElement("HasOverridenBeginEndRead", StreamNative::HasOverridenBeginEndRead) + FCFuncElement("HasOverridenBeginEndWrite", StreamNative::HasOverridenBeginEndWrite) +FCFuncEnd() + #ifndef FEATURE_CORECLR FCFuncStart(gConsoleStreamFuncs) FCFuncElement("WaitForAvailableConsoleInput", ConsoleStreamHelper::WaitForAvailableConsoleInput) @@ -2420,6 +2425,7 @@ FCClassElement("SizedReference", "System", gSizedRefHandleFuncs) FCClassElement("StackBuilderSink", "System.Runtime.Remoting.Messaging", gStackBuilderSinkFuncs) #endif FCClassElement("StackTrace", "System.Diagnostics", gDiagnosticsStackTrace) +FCClassElement("Stream", "System.IO", gStreamFuncs) FCClassElement("String", "System", gStringFuncs) FCClassElement("StringBuilder", "System.Text", gStringBufferFuncs) FCClassElement("StringExpressionSet", "System.Security.Util", gCOMStringExpressionSetFuncs) diff --git a/src/vm/metasig.h b/src/vm/metasig.h index c64ab675e3..7836fbaa47 100644 --- a/src/vm/metasig.h +++ b/src/vm/metasig.h @@ -679,6 +679,10 @@ DEFINE_METASIG_T(SM(RefCleanupWorkList_SafeHandle_RetIntPtr, r(C(CLEANUP_WORK_LI DEFINE_METASIG_T(IM(RuntimeTypeHandle_RefException_RetBool, g(RT_TYPE_HANDLE) r(C(EXCEPTION)), F)) DEFINE_METASIG_T(IM(RuntimeTypeHandle_RetRuntimeTypeHandle, g(RT_TYPE_HANDLE), g(RT_TYPE_HANDLE))) +DEFINE_METASIG_T(IM(ArrByte_Int_Int_AsyncCallback_Object_RetIAsyncResult, a(b) i i C(ASYNCCALLBACK) j, C(IASYNCRESULT))) +DEFINE_METASIG_T(IM(IAsyncResult_RetInt, C(IASYNCRESULT), i)) +DEFINE_METASIG_T(IM(IAsyncResult_RetVoid, C(IASYNCRESULT), v)) + // Undefine macros in case we include the file again in the compilation unit #undef DEFINE_METASIG diff --git a/src/vm/mscorlib.h b/src/vm/mscorlib.h index 8fb7853bb0..978b79d5b7 100644 --- a/src/vm/mscorlib.h +++ b/src/vm/mscorlib.h @@ -1495,6 +1495,10 @@ DEFINE_CLASS(STACK_TRACE, Diagnostics, StackTrace) DEFINE_METHOD(STACK_TRACE, GET_MANAGED_STACK_TRACE_HELPER, GetManagedStackTraceStringHelper, SM_Bool_RetStr) DEFINE_CLASS(STREAM, IO, Stream) +DEFINE_METHOD(STREAM, BEGIN_READ, BeginRead, IM_ArrByte_Int_Int_AsyncCallback_Object_RetIAsyncResult) +DEFINE_METHOD(STREAM, END_READ, EndRead, IM_IAsyncResult_RetInt) +DEFINE_METHOD(STREAM, BEGIN_WRITE, BeginWrite, IM_ArrByte_Int_Int_AsyncCallback_Object_RetIAsyncResult) +DEFINE_METHOD(STREAM, END_WRITE, EndWrite, IM_IAsyncResult_RetVoid) // Defined as element type alias // DEFINE_CLASS(INTPTR, System, IntPtr) |