Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichal Strehovský <MichalStrehovsky@users.noreply.github.com>2017-05-19 07:47:46 +0300
committerGitHub <noreply@github.com>2017-05-19 07:47:46 +0300
commit011a6804018dc8cde17df31891e5de6053a2e83e (patch)
tree2ac38ca4500e14487d9ccac3177f4dfe5f8fc73f /src
parent4afa5041466f0742105f35c886a7bbd47ca01765 (diff)
parente2915ae7dadd03843b6d070b5950b974c0fb988f (diff)
Merge pull request #3654 from dotnet/nmirror
Merge nmirror to master
Diffstat (limited to 'src')
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericLookupResult.cs175
-rw-r--r--src/Native/Runtime/Debug.h6
-rw-r--r--src/Native/Runtime/DebuggerHook.cpp48
-rw-r--r--src/Native/Runtime/DebuggerHook.h1
-rw-r--r--src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FileAttributes.cs17
-rw-r--r--src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindClose.cs16
-rw-r--r--src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs43
-rw-r--r--src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs94
-rw-r--r--src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems6
-rw-r--r--src/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs32
-rw-r--r--src/System.Private.CoreLib/src/System.Private.CoreLib.csproj5
-rw-r--r--src/System.Private.CoreLib/src/System/IO/File.Unix.cs14
-rw-r--r--src/System.Private.CoreLib/src/System/IO/File.Windows.cs136
-rw-r--r--src/System.Private.CoreLib/src/System/IO/File.cs47
-rw-r--r--src/System.Private.CoreLib/src/System/Resources/FileBasedResourceGroveler.cs4
-rw-r--r--src/System.Private.CoreLib/src/System/Resources/ResourceReader.cs4
-rw-r--r--src/System.Private.CoreLib/src/System/Runtime/InteropServices/BestFitMappingAttribute.cs (renamed from src/System.Private.Interop/src/System/Runtime/InteropServices/BestFitMappingAttribute.cs)4
-rw-r--r--src/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs4
-rw-r--r--src/System.Private.Interop/src/System.Private.Interop.csproj1
-rw-r--r--src/System.Private.Interop/src/TypeForwarders.cs3
-rw-r--r--src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/DebugFuncEval.cs11
21 files changed, 644 insertions, 27 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericLookupResult.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericLookupResult.cs
index 0fd1c94b0..2b0b548a1 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericLookupResult.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericLookupResult.cs
@@ -21,6 +21,45 @@ namespace ILCompiler.DependencyAnalysis
ConditionalIndirect, // The slot may be a direct pointer or an indirection cell, depending on the last digit
}
+ // Represents a generic lookup within a canonical method body.
+ // TODO: unify with NativeFormat.FixupSignatureKind
+ public enum LookupResultType
+ {
+ Invalid,
+ EEType, // a type
+ UnwrapNullable, // a type (The type T described by a type spec that is generic over Nullable<T>)
+ NonGcStatic, // the non-gc statics of a type
+ GcStatic, // the gc statics of a type
+ Method, // a method
+ InterfaceDispatchCell, // the dispatch cell for calling an interface method
+ MethodDictionary, // a dictionary for calling a generic method
+ UnboxingStub, // the unboxing stub for a method
+ ArrayType, // an array of type
+ DefaultCtor, // default ctor of a type
+ TlsIndex, // tls index of a type
+ TlsOffset, // tls offset of a type
+ AllocObject, // the allocator of a type
+ GvmVtableOffset, // vtable offset of a generic virtual method
+ ProfileCounter, // profiling counter cell
+ MethodLdToken, // a ldtoken result for a method
+ FieldLdToken, // a ldtoken result for a field
+ Field, // a field descriptor
+ IsInst, // isinst helper
+ CastClass, // castclass helper
+ AllocArray, // the array allocator of a type
+ CheckArrayElementType, // check the array element type
+ TypeSize, // size of the type
+ FieldOffset, // field offset
+ CallingConvention, // CallingConventionConverterThunk
+ VtableOffset, // Offset of a virtual method into the type's vtable
+ Constrained, // ConstrainedCallDesc
+ }
+
+ public interface IGenericLookupResultTocWriter
+ {
+ void WriteData(GenericLookupResultReferenceType referenceType, LookupResultType slotType, TypeSystemEntity context);
+ }
+
/// <summary>
/// Represents the result of a generic lookup within a canonical method body.
/// The concrete artifact the generic lookup will result in can only be determined after substituting
@@ -56,6 +95,8 @@ namespace ILCompiler.DependencyAnalysis
public abstract NativeLayoutVertexNode TemplateDictionaryNode(NodeFactory factory);
+ public abstract void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer);
+
// Call this api to get non-reloc dependencies that arise from use of a dictionary lookup
public virtual IEnumerable<DependencyNodeCore<NodeFactory>> NonRelocDependenciesFromUsage(NodeFactory factory)
{
@@ -147,6 +188,11 @@ namespace ILCompiler.DependencyAnalysis
}
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.EEType, _type);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_type, ((TypeHandleGenericLookupResult)other)._type);
@@ -206,6 +252,11 @@ namespace ILCompiler.DependencyAnalysis
}
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.UnwrapNullable, _type);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_type, ((UnwrapNullableTypeHandleGenericLookupResult)other)._type);
@@ -254,6 +305,11 @@ namespace ILCompiler.DependencyAnalysis
return factory.NativeLayout.FieldOffsetDictionarySlot(_field);
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.FieldOffset, _field);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_field, ((FieldOffsetGenericLookupResult)other)._field);
@@ -314,6 +370,11 @@ namespace ILCompiler.DependencyAnalysis
};
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.VtableOffset, _method);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_method, ((VTableOffsetGenericLookupResult)other)._method);
@@ -354,6 +415,11 @@ namespace ILCompiler.DependencyAnalysis
return factory.NativeLayout.MethodLdTokenDictionarySlot(_method);
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.MethodLdToken, _method);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_method, ((MethodHandleGenericLookupResult)other)._method);
@@ -394,6 +460,11 @@ namespace ILCompiler.DependencyAnalysis
return factory.NativeLayout.FieldLdTokenDictionarySlot(_field);
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.FieldLdToken, _field);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_field, ((FieldHandleGenericLookupResult)other)._field);
@@ -446,6 +517,11 @@ namespace ILCompiler.DependencyAnalysis
return factory.NativeLayout.MethodDictionaryDictionarySlot(_method);
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.MethodDictionary, _method);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_method, ((MethodDictionaryGenericLookupResult)other)._method);
@@ -493,6 +569,11 @@ namespace ILCompiler.DependencyAnalysis
(_method, unboxing: true, functionPointerTarget: factory.MethodEntrypoint(_method.GetCanonMethodTarget(CanonicalFormKind.Specific)));
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.Method, _method);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
var otherEntry = (MethodEntryGenericLookupResult)other;
@@ -558,6 +639,19 @@ namespace ILCompiler.DependencyAnalysis
}
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ if (factory.Target.Abi == TargetAbi.CoreRT)
+ {
+ // TODO
+ throw new NotImplementedException();
+ }
+ else
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.InterfaceDispatchCell, _method);
+ }
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_method, ((VirtualDispatchGenericLookupResult)other)._method);
@@ -620,6 +714,19 @@ namespace ILCompiler.DependencyAnalysis
}
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ if (factory.Target.Abi == TargetAbi.CoreRT)
+ {
+ // TODO
+ throw new NotImplementedException();
+ }
+ else
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.InterfaceDispatchCell, _method);
+ }
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_method, ((VirtualResolveGenericLookupResult)other)._method);
@@ -666,6 +773,11 @@ namespace ILCompiler.DependencyAnalysis
return GenericLookupResultReferenceType.Indirect;
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.NonGcStatic, _type);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_type, ((TypeNonGCStaticBaseGenericLookupResult)other)._type);
@@ -707,6 +819,12 @@ namespace ILCompiler.DependencyAnalysis
return factory.NativeLayout.NotSupportedDictionarySlot;
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ // TODO
+ throw new NotImplementedException();
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_type, ((TypeThreadStaticBaseIndexGenericLookupResult)other)._type);
@@ -753,6 +871,11 @@ namespace ILCompiler.DependencyAnalysis
return GenericLookupResultReferenceType.Indirect;
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.GcStatic, _type);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_type, ((TypeGCStaticBaseGenericLookupResult)other)._type);
@@ -798,6 +921,11 @@ namespace ILCompiler.DependencyAnalysis
return GenericLookupResultReferenceType.Indirect;
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.AllocObject, _type);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_type, ((ObjectAllocatorGenericLookupResult)other)._type);
@@ -844,6 +972,11 @@ namespace ILCompiler.DependencyAnalysis
return GenericLookupResultReferenceType.Indirect;
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.AllocArray, _type);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_type, ((ArrayAllocatorGenericLookupResult)other)._type);
@@ -889,6 +1022,11 @@ namespace ILCompiler.DependencyAnalysis
return GenericLookupResultReferenceType.Indirect;
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.CastClass, _type);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_type, ((CastClassGenericLookupResult)other)._type);
@@ -934,6 +1072,11 @@ namespace ILCompiler.DependencyAnalysis
return GenericLookupResultReferenceType.Indirect;
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.IsInst, _type);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_type, ((IsInstGenericLookupResult)other)._type);
@@ -978,6 +1121,11 @@ namespace ILCompiler.DependencyAnalysis
return GenericLookupResultReferenceType.Indirect;
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.TlsIndex, _type);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_type, ((ThreadStaticIndexLookupResult)other)._type);
@@ -1023,6 +1171,11 @@ namespace ILCompiler.DependencyAnalysis
return GenericLookupResultReferenceType.Indirect;
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.TlsOffset, _type);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_type, ((ThreadStaticOffsetLookupResult)other)._type);
@@ -1075,6 +1228,11 @@ namespace ILCompiler.DependencyAnalysis
return factory.NativeLayout.DefaultConstructorDictionarySlot(_type);
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.DefaultCtor, _type);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_type, ((DefaultConstructorLookupResult)other)._type);
@@ -1118,6 +1276,12 @@ namespace ILCompiler.DependencyAnalysis
return factory.NativeLayout.CallingConventionConverter(_callingConventionConverter);
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ // TODO
+ throw new NotImplementedException();
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
var otherEntry = (CallingConventionConverterLookupResult)other;
@@ -1176,6 +1340,11 @@ namespace ILCompiler.DependencyAnalysis
return factory.NativeLayout.TypeSizeDictionarySlot(_type);
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ writer.WriteData(LookupResultReferenceType(factory), LookupResultType.TypeSize, _type);
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
return comparer.Compare(_type, ((TypeSizeLookupResult)other)._type);
@@ -1237,6 +1406,12 @@ namespace ILCompiler.DependencyAnalysis
return factory.NativeLayout.ConstrainedMethodUse(_constrainedMethod, _constraintType, _directCall);
}
+ public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer)
+ {
+ // TODO
+ throw new NotImplementedException();
+ }
+
protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer)
{
var otherResult = (ConstrainedMethodUseLookupResult)other;
diff --git a/src/Native/Runtime/Debug.h b/src/Native/Runtime/Debug.h
index 656a8eff2..926e8fc4c 100644
--- a/src/Native/Runtime/Debug.h
+++ b/src/Native/Runtime/Debug.h
@@ -12,7 +12,8 @@ enum DebuggerGcProtectionMessage : uint32_t
enum DebuggerGcProtectionRequestKind : uint16_t
{
- ConservativeReporting = 1,
+ EnsureConservativeReporting = 1,
+ RemoveConservativeReporting = 2,
};
struct GcProtectionMessage
@@ -24,7 +25,8 @@ struct GcProtectionMessage
struct GcProtectionRequest
{
- DebuggerGcProtectionRequestKind type;
+ DebuggerGcProtectionRequestKind kind;
uint16_t size;
+ uint32_t identifier;
uint64_t address;
};
diff --git a/src/Native/Runtime/DebuggerHook.cpp b/src/Native/Runtime/DebuggerHook.cpp
index d4a74db75..26ca90497 100644
--- a/src/Native/Runtime/DebuggerHook.cpp
+++ b/src/Native/Runtime/DebuggerHook.cpp
@@ -18,12 +18,10 @@ GVAL_IMPL_INIT(UInt32, g_numGcProtectionRequests, 0);
{
if (g_numGcProtectionRequests > 0)
{
- // The debugger has some request with respect to GC protection.
+ // The debugger has some requests with respect to GC protection.
// Here we are allocating a buffer to store them
GcProtectionRequest* requests = new (nothrow) GcProtectionRequest[g_numGcProtectionRequests];
- // TODO: We need to figure out how to communicate this broken promise to the debugger
-
// Notifying the debugger the buffer is ready to use
GcProtectionMessage command;
command.commandCode = DebuggerGcProtectionMessage::RequestBufferReady;
@@ -35,7 +33,7 @@ GVAL_IMPL_INIT(UInt32, g_numGcProtectionRequests, 0);
// The debugger has filled the requests array
for (uint32_t i = 0; i < g_numGcProtectionRequests; i++)
{
- if (requests[i].type == DebuggerGcProtectionRequestKind::ConservativeReporting)
+ if (requests[i].kind == DebuggerGcProtectionRequestKind::EnsureConservativeReporting)
{
// If the request requires extra memory, allocate for it
requests[i].address = (uint64_t)new (nothrow) uint8_t[requests[i].size];
@@ -44,6 +42,9 @@ GVAL_IMPL_INIT(UInt32, g_numGcProtectionRequests, 0);
}
}
+ // TODO: Consider an optimization to eliminate this message when they is nothing required from the
+ // debugger side to fill
+
command.commandCode = DebuggerGcProtectionMessage::ConservativeReportingBufferReady;
DebugEventSource::SendCustomEvent((void*)&command, sizeof(command));
@@ -51,22 +52,57 @@ GVAL_IMPL_INIT(UInt32, g_numGcProtectionRequests, 0);
for (uint32_t i = 0; i < g_numGcProtectionRequests; i++)
{
- if (requests[i].type == DebuggerGcProtectionRequestKind::ConservativeReporting)
+ if (requests[i].kind == DebuggerGcProtectionRequestKind::EnsureConservativeReporting)
{
- // TODO: Release them when there should be gone
DebuggerProtectedBufferList* tail = DebuggerHook::s_debuggerProtectedBuffers;
s_debuggerProtectedBuffers = new (std::nothrow) DebuggerProtectedBufferList();
if (s_debuggerProtectedBuffers == nullptr)
{
// TODO: We cannot handle the debugger request to protect a buffer (we have to break our promise)
+ // TODO: We need to figure out how to communicate this broken promise to the debugger
}
else
{
s_debuggerProtectedBuffers->address = requests[i].address;
s_debuggerProtectedBuffers->size = requests[i].size;
+ s_debuggerProtectedBuffers->identifier = requests[i].identifier;
s_debuggerProtectedBuffers->next = tail;
}
}
+ else if (requests[i].kind == DebuggerGcProtectionRequestKind::RemoveConservativeReporting)
+ {
+ DebuggerProtectedBufferList* prev = nullptr;
+ DebuggerProtectedBufferList* curr = DebuggerHook::s_debuggerProtectedBuffers;
+ while (true)
+ {
+ if (curr == nullptr)
+ {
+ // The debugger is trying to remove a conservatively reported buffer that does not exist
+ break;
+ }
+ if (curr->identifier == requests[i].identifier)
+ {
+ DebuggerProtectedBufferList* toDelete = curr;
+ if (prev == nullptr)
+ {
+ // We are trying to remove the head of the linked list
+ DebuggerHook::s_debuggerProtectedBuffers = curr->next;
+ }
+ else
+ {
+ prev->next = curr->next;
+ }
+
+ delete toDelete;
+ break;
+ }
+ else
+ {
+ prev = curr;
+ curr = curr->next;
+ }
+ }
+ }
}
g_numGcProtectionRequests = 0;
diff --git a/src/Native/Runtime/DebuggerHook.h b/src/Native/Runtime/DebuggerHook.h
index fb8d0090c..feb1d3e24 100644
--- a/src/Native/Runtime/DebuggerHook.h
+++ b/src/Native/Runtime/DebuggerHook.h
@@ -21,6 +21,7 @@ struct DebuggerProtectedBufferList
{
UInt64 address;
UInt16 size;
+ UInt32 identifier;
struct DebuggerProtectedBufferList* next;
};
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FileAttributes.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FileAttributes.cs
new file mode 100644
index 000000000..725a25a71
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FileAttributes.cs
@@ -0,0 +1,17 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ internal partial class FileAttributes
+ {
+ internal const int FILE_ATTRIBUTE_NORMAL = 0x00000080;
+ internal const int FILE_ATTRIBUTE_READONLY = 0x00000001;
+ internal const int FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
+ internal const int FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400;
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindClose.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindClose.cs
new file mode 100644
index 000000000..03d8c8b32
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindClose.cs
@@ -0,0 +1,16 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ [DllImport(Libraries.Kernel32, SetLastError = true)]
+ internal extern static bool FindClose(IntPtr hFindFile);
+ }
+}
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs
new file mode 100644
index 000000000..80b1ddd28
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs
@@ -0,0 +1,43 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ /// <summary>
+ /// WARNING: This method does not implicitly handle long paths. Use FindFirstFile.
+ /// </summary>
+ [DllImport(Libraries.Kernel32, EntryPoint = "FindFirstFileExW", SetLastError = true, CharSet = CharSet.Unicode)]
+ private static extern SafeFindHandle FindFirstFileExPrivate(string lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, ref WIN32_FIND_DATA lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, IntPtr lpSearchFilter, int dwAdditionalFlags);
+
+ internal static SafeFindHandle FindFirstFile(string fileName, ref WIN32_FIND_DATA data)
+ {
+ fileName = PathInternal.EnsureExtendedPrefixOverMaxPath(fileName);
+
+ // use FindExInfoBasic since we don't care about short name and it has better perf
+ return FindFirstFileExPrivate(fileName, FINDEX_INFO_LEVELS.FindExInfoBasic, ref data, FINDEX_SEARCH_OPS.FindExSearchNameMatch, IntPtr.Zero, 0);
+ }
+
+ internal enum FINDEX_INFO_LEVELS : uint
+ {
+ FindExInfoStandard = 0x0u,
+ FindExInfoBasic = 0x1u,
+ FindExInfoMaxInfoLevel = 0x2u,
+ }
+
+ internal enum FINDEX_SEARCH_OPS : uint
+ {
+ FindExSearchNameMatch = 0x0u,
+ FindExSearchLimitToDirectories = 0x1u,
+ FindExSearchLimitToDevices = 0x2u,
+ FindExSearchMaxSearchOp = 0x3u,
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs
new file mode 100644
index 000000000..4cce56bd0
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs
@@ -0,0 +1,94 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ /// <summary>
+ /// WARNING: This method does not implicitly handle long paths. Use GetFileAttributesEx.
+ /// </summary>
+ [DllImport(Libraries.Kernel32, EntryPoint = "GetFileAttributesExW", SetLastError = true, CharSet = CharSet.Unicode)]
+ private static extern bool GetFileAttributesExPrivate(string name, GET_FILEEX_INFO_LEVELS fileInfoLevel, ref WIN32_FILE_ATTRIBUTE_DATA lpFileInformation);
+
+ internal static bool GetFileAttributesEx(string name, GET_FILEEX_INFO_LEVELS fileInfoLevel, ref WIN32_FILE_ATTRIBUTE_DATA lpFileInformation)
+ {
+ name = PathInternal.EnsureExtendedPrefixOverMaxPath(name);
+ return GetFileAttributesExPrivate(name, fileInfoLevel, ref lpFileInformation);
+ }
+
+ internal enum GET_FILEEX_INFO_LEVELS : uint
+ {
+ GetFileExInfoStandard = 0x0u,
+ GetFileExMaxInfoLevel = 0x1u,
+ }
+
+ internal struct WIN32_FILE_ATTRIBUTE_DATA
+ {
+ internal int fileAttributes;
+ internal uint ftCreationTimeLow;
+ internal uint ftCreationTimeHigh;
+ internal uint ftLastAccessTimeLow;
+ internal uint ftLastAccessTimeHigh;
+ internal uint ftLastWriteTimeLow;
+ internal uint ftLastWriteTimeHigh;
+ internal uint fileSizeHigh;
+ internal uint fileSizeLow;
+
+ internal void PopulateFrom(ref WIN32_FIND_DATA findData)
+ {
+ // Copy the information to data
+ fileAttributes = (int)findData.dwFileAttributes;
+ ftCreationTimeLow = findData.ftCreationTime.dwLowDateTime;
+ ftCreationTimeHigh = findData.ftCreationTime.dwHighDateTime;
+ ftLastAccessTimeLow = findData.ftLastAccessTime.dwLowDateTime;
+ ftLastAccessTimeHigh = findData.ftLastAccessTime.dwHighDateTime;
+ ftLastWriteTimeLow = findData.ftLastWriteTime.dwLowDateTime;
+ ftLastWriteTimeHigh = findData.ftLastWriteTime.dwHighDateTime;
+ fileSizeHigh = findData.nFileSizeHigh;
+ fileSizeLow = findData.nFileSizeLow;
+ }
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ [BestFitMapping(false)]
+ internal unsafe struct WIN32_FIND_DATA
+ {
+ internal uint dwFileAttributes;
+ internal FILE_TIME ftCreationTime;
+ internal FILE_TIME ftLastAccessTime;
+ internal FILE_TIME ftLastWriteTime;
+ internal uint nFileSizeHigh;
+ internal uint nFileSizeLow;
+ internal uint dwReserved0;
+ internal uint dwReserved1;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
+ internal string cFileName;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
+ internal string cAlternateFileName;
+ }
+
+ internal struct FILE_TIME
+ {
+ internal uint dwLowDateTime;
+ internal uint dwHighDateTime;
+
+ internal FILE_TIME(long fileTime)
+ {
+ dwLowDateTime = (uint)fileTime;
+ dwHighDateTime = (uint)(fileTime >> 32);
+ }
+
+ internal long ToTicks()
+ {
+ return ((long)dwHighDateTime << 32) + dwLowDateTime;
+ }
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
index 981d35811..ae98a97c7 100644
--- a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
+++ b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
@@ -472,11 +472,15 @@
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.CloseHandle.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.CreateFile.cs" Condition="'$(IsProjectNLibrary)' != 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.CreateFile2.cs" Condition="'$(IsProjectNLibrary)' == 'true'" />
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FileAttributes.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FILE_INFO_BY_HANDLE_CLASS.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FileTypes.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FindClose.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FindFirstFileEx.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FlushFileBuffers.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FormatMessage.cs"/>
- <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetCPInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetCPInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetFileAttributesEx.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetFileInformationByHandleEx.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetFileType_SafeHandle.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetFullPathNameW.cs"/>
diff --git a/src/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs b/src/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs
new file mode 100644
index 000000000..1c30841da
--- /dev/null
+++ b/src/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs
@@ -0,0 +1,32 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*============================================================
+**
+**
+**
+** A wrapper for find handles
+**
+**
+===========================================================*/
+
+using System;
+using System.Security;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using Microsoft.Win32;
+
+namespace Microsoft.Win32.SafeHandles
+{
+ internal sealed class SafeFindHandle : SafeHandleZeroOrMinusOneIsInvalid
+ {
+ internal SafeFindHandle() : base(true) { }
+
+ override protected bool ReleaseHandle()
+ {
+ return Interop.Kernel32.FindClose(handle);
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj
index c080ce9d6..72a1063b9 100644
--- a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj
+++ b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj
@@ -214,6 +214,9 @@
<Compile Include="System\InvokeUtils.cs" />
<Compile Include="System\IO\BinaryReader.cs" />
<Compile Include="System\IO\BinaryWriter.cs" />
+ <Compile Include="System\IO\File.cs" />
+ <Compile Include="System\IO\File.Windows.cs" Condition="'$(TargetsWindows)'=='true'" />
+ <Compile Include="System\IO\File.Unix.cs" Condition="'$(TargetsUnix)'=='true'" />
<Compile Include="System\IO\FileLoadException.CoreRT.cs" />
<Compile Include="System\IO\IOException.cs" />
<Compile Include="System\IO\MemoryStream.cs" />
@@ -298,6 +301,7 @@
<Compile Include="System\Runtime\GcSettings.cs" />
<Compile Include="System\Runtime\TypeLoaderExports.cs" />
<Compile Include="System\Runtime\InitializeFinalizerThread.cs" />
+ <Compile Include="System\Runtime\InteropServices\BestFitMappingAttribute.cs" />
<Compile Include="System\Runtime\InteropServices\DllImportAttribute.cs" />
<Compile Include="System\Runtime\InteropServices\GCHandle.cs" />
<Compile Include="System\Runtime\InteropServices\GCHandleType.cs" />
@@ -479,6 +483,7 @@
</ItemGroup>
<ItemGroup Condition="'$(TargetsWindows)'=='true'">
<Compile Include="Internal\Runtime\Augments\RuntimeThread.Windows.cs" />
+ <Compile Include="Microsoft\Win32\SafeHandles\SafeFindHandle.cs" />
<Compile Include="Microsoft\Win32\SafeHandles\SafeThreadPoolIOHandle.cs" />
<Compile Condition="'$(EnableWinRT)' == 'true'" Include="System\TimeZoneInfo.WinRT.cs" />
<Compile Condition="'$(EnableWinRT)' != 'true'" Include="System\TimeZoneInfo.Win32.cs" />
diff --git a/src/System.Private.CoreLib/src/System/IO/File.Unix.cs b/src/System.Private.CoreLib/src/System/IO/File.Unix.cs
new file mode 100644
index 000000000..3cf5bf836
--- /dev/null
+++ b/src/System.Private.CoreLib/src/System/IO/File.Unix.cs
@@ -0,0 +1,14 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.IO
+{
+ internal static partial class File
+ {
+ internal static bool InternalExists(String path)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/src/System/IO/File.Windows.cs b/src/System.Private.CoreLib/src/System/IO/File.Windows.cs
new file mode 100644
index 000000000..4bd8e9426
--- /dev/null
+++ b/src/System.Private.CoreLib/src/System/IO/File.Windows.cs
@@ -0,0 +1,136 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32;
+using Microsoft.Win32.SafeHandles;
+using System.Runtime.InteropServices;
+
+namespace System.IO
+{
+ internal static partial class File
+ {
+ internal static bool InternalExists(String path)
+ {
+ Interop.Kernel32.WIN32_FILE_ATTRIBUTE_DATA data = new Interop.Kernel32.WIN32_FILE_ATTRIBUTE_DATA();
+ int errorCode = FillAttributeInfo(path, ref data, false, true);
+
+ return (errorCode == 0) && (data.fileAttributes != -1)
+ && ((data.fileAttributes & Interop.Kernel32.FileAttributes.FILE_ATTRIBUTE_DIRECTORY) == 0);
+ }
+
+ // Returns 0 on success, otherwise a Win32 error code. Note that
+ // classes should use -1 as the uninitialized state for dataInitialized.
+ internal static int FillAttributeInfo(String path, ref Interop.Kernel32.WIN32_FILE_ATTRIBUTE_DATA data, bool tryagain, bool returnErrorOnNotFound)
+ {
+ int errorCode = 0;
+ if (tryagain) // someone has a handle to the file open, or other error
+ {
+ Interop.Kernel32.WIN32_FIND_DATA findData;
+ findData = new Interop.Kernel32.WIN32_FIND_DATA();
+
+ // Remove trailing slash since this can cause grief to FindFirstFile. You will get an invalid argument error
+ String tempPath = path.TrimEnd(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar });
+
+ // For floppy drives, normally the OS will pop up a dialog saying
+ // there is no disk in drive A:, please insert one. We don't want that.
+ // SetThreadErrorMode will let us disable this, but we should set the error
+ // mode back, since this may have wide-ranging effects.
+ uint oldMode;
+ bool setThreadErrorModeSuccess = Interop.Kernel32.SetThreadErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS, out oldMode);
+ try
+ {
+ bool error = false;
+ SafeFindHandle handle = Interop.Kernel32.FindFirstFile(tempPath, ref findData);
+ try
+ {
+ if (handle.IsInvalid)
+ {
+ error = true;
+ errorCode = Marshal.GetLastWin32Error();
+
+ if (errorCode == Interop.Errors.ERROR_FILE_NOT_FOUND ||
+ errorCode == Interop.Errors.ERROR_PATH_NOT_FOUND ||
+ errorCode == Interop.Errors.ERROR_NOT_READY) // floppy device not ready
+ {
+ if (!returnErrorOnNotFound)
+ {
+ // Return default value for backward compatibility
+ errorCode = 0;
+ data.fileAttributes = -1;
+ }
+ }
+ return errorCode;
+ }
+ }
+ finally
+ {
+ // Close the Win32 handle
+ try
+ {
+ handle.Dispose();
+ }
+ catch
+ {
+ // if we're already returning an error, don't throw another one.
+ if (!error)
+ {
+ throw Win32Marshal.GetExceptionForLastWin32Error();
+ }
+ }
+ }
+ }
+ finally
+ {
+ if (setThreadErrorModeSuccess)
+ Interop.Kernel32.SetThreadErrorMode(oldMode, out oldMode);
+ }
+
+ // Copy the information to data
+ data.PopulateFrom(ref findData);
+ }
+ else
+ {
+ // For floppy drives, normally the OS will pop up a dialog saying
+ // there is no disk in drive A:, please insert one. We don't want that.
+ // SetThreadErrorMode will let us disable this, but we should set the error
+ // mode back, since this may have wide-ranging effects.
+ bool success = false;
+ uint oldMode;
+ bool setThreadErrorModeSuccess = Interop.Kernel32.SetThreadErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS, out oldMode);
+ try
+ {
+ success = Interop.Kernel32.GetFileAttributesEx(path, Interop.Kernel32.GET_FILEEX_INFO_LEVELS.GetFileExInfoStandard, ref data);
+ }
+ finally
+ {
+ if (setThreadErrorModeSuccess)
+ Interop.Kernel32.SetThreadErrorMode(oldMode, out oldMode);
+ }
+
+ if (!success)
+ {
+ errorCode = Marshal.GetLastWin32Error();
+ if (errorCode != Interop.Errors.ERROR_FILE_NOT_FOUND &&
+ errorCode != Interop.Errors.ERROR_PATH_NOT_FOUND &&
+ errorCode != Interop.Errors.ERROR_NOT_READY) // floppy device not ready
+ {
+ // In case someone latched onto the file. Take the perf hit only for failure
+ return FillAttributeInfo(path, ref data, true, returnErrorOnNotFound);
+ }
+ else
+ {
+ if (!returnErrorOnNotFound)
+ {
+ // Return default value for backward compatibility
+ errorCode = 0;
+ data.fileAttributes = -1;
+ }
+ }
+ }
+ }
+
+ return errorCode;
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/src/System/IO/File.cs b/src/System.Private.CoreLib/src/System/IO/File.cs
new file mode 100644
index 000000000..30513c894
--- /dev/null
+++ b/src/System.Private.CoreLib/src/System/IO/File.cs
@@ -0,0 +1,47 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics;
+using System.Security;
+
+namespace System.IO
+{
+ internal static partial class File
+ {
+ // Tests if a file exists. The result is true if the file
+ // given by the specified path exists; otherwise, the result is
+ // false. Note that if path describes a directory,
+ // Exists will return true.
+ public static bool Exists(String path)
+ {
+ try
+ {
+ if (path == null)
+ return false;
+ if (path.Length == 0)
+ return false;
+
+ path = Path.GetFullPath(path);
+
+ // After normalizing, check whether path ends in directory separator.
+ // Otherwise, FillAttributeInfo removes it and we may return a false positive.
+ // GetFullPath should never return null
+ Debug.Assert(path != null, "File.Exists: GetFullPath returned null");
+ if (path.Length > 0 && PathInternal.IsDirectorySeparator(path[path.Length - 1]))
+ {
+ return false;
+ }
+
+ return InternalExists(path);
+ }
+ catch (ArgumentException) { }
+ catch (NotSupportedException) { } // Security can throw this on ":"
+ catch (SecurityException) { }
+ catch (IOException) { }
+ catch (UnauthorizedAccessException) { }
+
+ return false;
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/src/System/Resources/FileBasedResourceGroveler.cs b/src/System.Private.CoreLib/src/System/Resources/FileBasedResourceGroveler.cs
index fb48cec1c..07353f4b6 100644
--- a/src/System.Private.CoreLib/src/System/Resources/FileBasedResourceGroveler.cs
+++ b/src/System.Private.CoreLib/src/System/Resources/FileBasedResourceGroveler.cs
@@ -82,9 +82,6 @@ namespace System.Resources
private String FindResourceFile(CultureInfo culture, String fileName)
{
- throw new NotImplementedException();
- // todo remove the throw and ifdef when File and FileStream are in CoreLib
-#if FILE_TYPES_IN_CORELIB
Debug.Assert(culture != null, "culture shouldn't be null; check caller");
Debug.Assert(fileName != null, "fileName shouldn't be null; check caller");
@@ -104,7 +101,6 @@ namespace System.Resources
return fileName;
return null; // give up.
-#endif // FILE_TYPES_IN_CORELIB
}
// Constructs a new ResourceSet for a given file name. The logic in
diff --git a/src/System.Private.CoreLib/src/System/Resources/ResourceReader.cs b/src/System.Private.CoreLib/src/System/Resources/ResourceReader.cs
index db078c714..7bf3e3d2c 100644
--- a/src/System.Private.CoreLib/src/System/Resources/ResourceReader.cs
+++ b/src/System.Private.CoreLib/src/System/Resources/ResourceReader.cs
@@ -108,9 +108,6 @@ namespace System.Resources
public ResourceReader(String fileName)
{
- throw new NotImplementedException();
-#if FILE_TYPES_IN_CORELIB
- // todo remove the throw and ifdef when File and FileStream are in CoreLib
_resCache = new Dictionary<String, ResourceLocator>(FastResourceComparer.Default);
_store = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.RandomAccess), Encoding.UTF8);
@@ -123,7 +120,6 @@ namespace System.Resources
_store.Dispose(); // If we threw an exception, close the file.
throw;
}
-#endif // FILE_TYPES_IN_CORELIB
}
public ResourceReader(Stream stream)
diff --git a/src/System.Private.Interop/src/System/Runtime/InteropServices/BestFitMappingAttribute.cs b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/BestFitMappingAttribute.cs
index e73e64998..a880c62e6 100644
--- a/src/System.Private.Interop/src/System/Runtime/InteropServices/BestFitMappingAttribute.cs
+++ b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/BestFitMappingAttribute.cs
@@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
-
namespace System.Runtime.InteropServices
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)]
@@ -19,4 +17,4 @@ namespace System.Runtime.InteropServices
public bool BestFitMapping { get { return _bestFitMapping; } }
public bool ThrowOnUnmappableChar;
}
-}
+} \ No newline at end of file
diff --git a/src/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs
index d2a9f0c1c..330580c99 100644
--- a/src/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs
+++ b/src/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs
@@ -297,6 +297,10 @@ namespace System.Runtime
// calls to runtime for allocation
//
[MethodImpl(MethodImplOptions.InternalCall)]
+ [RuntimeImport(RuntimeLibrary, "RhBoxAny")]
+ public static extern unsafe object RhBoxAny(IntPtr pData, IntPtr pEEType);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
[RuntimeImport(RuntimeLibrary, "RhNewObject")]
internal static extern object RhNewObject(EETypePtr pEEType);
diff --git a/src/System.Private.Interop/src/System.Private.Interop.csproj b/src/System.Private.Interop/src/System.Private.Interop.csproj
index 607c33957..431cc60e2 100644
--- a/src/System.Private.Interop/src/System.Private.Interop.csproj
+++ b/src/System.Private.Interop/src/System.Private.Interop.csproj
@@ -87,7 +87,6 @@
<ItemGroup>
<Compile Include="System\Runtime\InteropServices\AllowReversePInvokeCallsAttribute.cs" />
<Compile Include="System\Runtime\InteropServices\ArrayWithOffset.cs" />
- <Compile Include="System\Runtime\InteropServices\BestFitMappingAttribute.cs" />
<Compile Include="System\Runtime\InteropServices\BStrWrapper.cs" />
<Compile Include="System\Runtime\InteropServices\ClassInterfaceAttribute.cs" />
<Compile Include="System\Runtime\InteropServices\ClassInterfaceType.cs" />
diff --git a/src/System.Private.Interop/src/TypeForwarders.cs b/src/System.Private.Interop/src/TypeForwarders.cs
index b9e6dd0da..badf60477 100644
--- a/src/System.Private.Interop/src/TypeForwarders.cs
+++ b/src/System.Private.Interop/src/TypeForwarders.cs
@@ -10,4 +10,5 @@
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.InteropServices.InAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.DllNotFoundException))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.EntryPointNotFoundException))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.InteropServices.MarshalDirectiveException))] \ No newline at end of file
+[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.InteropServices.MarshalDirectiveException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.InteropServices.BestFitMappingAttribute))] \ No newline at end of file
diff --git a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/DebugFuncEval.cs b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/DebugFuncEval.cs
index 401617c8b..1e6790327 100644
--- a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/DebugFuncEval.cs
+++ b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/DebugFuncEval.cs
@@ -45,13 +45,14 @@ namespace Internal.Runtime.TypeLoader
// Invoke the target method
Internal.Runtime.CallInterceptor.CallInterceptor.MakeDynamicCall(targetAddress, dynamicCallSignature, arguments);
- // TODO: We should be able to handle arbitrary return type
- object returnValue = arguments.GetVar<int>(0);
- GCHandle returnValueHandle = GCHandle.Alloc(returnValue);
-
- // Signal to the debugger the func eval completes
unsafe
{
+ // Box the return
+ IntPtr input = arguments.GetAddressOfVarData(0);
+ object returnValue = RuntimeImports.RhBoxAny(input, (IntPtr)param.types[0].ToEETypePtr());
+ GCHandle returnValueHandle = GCHandle.Alloc(returnValue);
+
+ // Signal to the debugger the func eval completes
FuncEvalCompleteCommand* funcEvalCompleteCommand = stackalloc FuncEvalCompleteCommand[1];
funcEvalCompleteCommand->commandCode = 0;
funcEvalCompleteCommand->returnAddress = (long)GCHandle.ToIntPtr(returnValueHandle);