summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mscorlib/src/System/IO/FileStream.cs3
-rw-r--r--src/mscorlib/src/System/IO/Stream.cs27
-rw-r--r--src/vm/comutilnative.cpp54
-rw-r--r--src/vm/comutilnative.h6
-rw-r--r--src/vm/ecalllist.h6
-rw-r--r--src/vm/metasig.h4
-rw-r--r--src/vm/mscorlib.h4
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)