|
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// RuntimeHelpers
// This class defines a set of static methods that provide support for compilers.
//
// Date: April 2000
//
namespace System.Runtime.CompilerServices {
using System;
using System.Security;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
using System.Security.Permissions;
using System.Threading;
using System.Runtime.Versioning;
using System.Diagnostics.Contracts;
public static class RuntimeHelpers
{
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void InitializeArray(Array array,RuntimeFieldHandle fldHandle);
// GetObjectValue is intended to allow value classes to be manipulated as 'Object'
// but have aliasing behavior of a value class. The intent is that you would use
// this function just before an assignment to a variable of type 'Object'. If the
// value being assigned is a mutable value class, then a shallow copy is returned
// (because value classes have copy semantics), but otherwise the object itself
// is returned.
//
// Note: VB calls this method when they're about to assign to an Object
// or pass it as a parameter. The goal is to make sure that boxed
// value types work identical to unboxed value types - ie, they get
// cloned when you pass them around, and are always passed by value.
// Of course, reference types are not cloned.
//
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern Object GetObjectValue(Object obj);
// RunClassConstructor causes the class constructor for the given type to be triggered
// in the current domain. After this call returns, the class constructor is guaranteed to
// have at least been started by some thread. In the absence of class constructor
// deadlock conditions, the call is further guaranteed to have completed.
//
// This call will generate an exception if the specified class constructor threw an
// exception when it ran.
[System.Security.SecuritySafeCritical]
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _RunClassConstructor(RuntimeType type);
public static void RunClassConstructor(RuntimeTypeHandle type)
{
_RunClassConstructor(type.GetRuntimeType());
}
// RunModuleConstructor causes the module constructor for the given type to be triggered
// in the current domain. After this call returns, the module constructor is guaranteed to
// have at least been started by some thread. In the absence of module constructor
// deadlock conditions, the call is further guaranteed to have completed.
//
// This call will generate an exception if the specified module constructor threw an
// exception when it ran.
[System.Security.SecuritySafeCritical]
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _RunModuleConstructor(System.Reflection.RuntimeModule module);
public static void RunModuleConstructor(ModuleHandle module)
{
_RunModuleConstructor(module.GetRuntimeModule());
}
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static unsafe extern void _PrepareMethod(IRuntimeMethodInfo method, IntPtr* pInstantiation, int cInstantiation);
[System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
internal static extern void _CompileMethod(IRuntimeMethodInfo method);
// Simple (instantiation not required) method.
[System.Security.SecurityCritical] // auto-generated_required
public static void PrepareMethod(RuntimeMethodHandle method)
{
unsafe
{
_PrepareMethod(method.GetMethodInfo(), null, 0);
}
}
// Generic method or method with generic class with specific instantiation.
[System.Security.SecurityCritical] // auto-generated_required
public static void PrepareMethod(RuntimeMethodHandle method, RuntimeTypeHandle[] instantiation)
{
unsafe
{
int length;
IntPtr[] instantiationHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(instantiation, out length);
fixed (IntPtr* pInstantiation = instantiationHandles)
{
_PrepareMethod(method.GetMethodInfo(), pInstantiation, length);
GC.KeepAlive(instantiation);
}
}
}
// This method triggers a given delegate to be prepared. This involves preparing the
// delegate's Invoke method and preparing the target of that Invoke. In the case of
// a multi-cast delegate, we rely on the fact that each individual component was prepared
// prior to the Combine. In other words, this service does not navigate through the
// entire multicasting list.
// If our own reliable event sinks perform the Combine (for example AppDomain.DomainUnload),
// then the result is fully prepared. But if a client calls Combine himself and then
// then adds that combination to e.g. AppDomain.DomainUnload, then the client is responsible
// for his own preparation.
[System.Security.SecurityCritical] // auto-generated_required
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void PrepareDelegate(Delegate d);
// See comment above for PrepareDelegate
//
// PrepareContractedDelegate weakens this a bit by only assuring that we prepare
// delegates which also have a ReliabilityContract. This is useful for services that
// want to provide opt-in reliability, generally some random event sink providing
// always reliable semantics to random event handlers that are likely to have not
// been written with relability in mind is a lost cause anyway.
//
// NOTE: that for the NGen case you can sidestep the required ReliabilityContract
// by using the [PrePrepareMethod] attribute.
[System.Security.SecurityCritical] // auto-generated_required
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void PrepareContractedDelegate(Delegate d);
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern int GetHashCode(Object o);
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public new static extern bool Equals(Object o1, Object o2);
public static int OffsetToStringData
{
// This offset is baked in by string indexer intrinsic, so there is no harm
// in getting it baked in here as well.
[System.Runtime.Versioning.NonVersionable]
get {
// Number of bytes from the address pointed to by a reference to
// a String to the first 16-bit character in the String. Skip
// over the MethodTable pointer, & String
// length. Of course, the String reference points to the memory
// after the sync block, so don't count that.
// This property allows C#'s fixed statement to work on Strings.
// On 64 bit platforms, this should be 12 (8+4) and on 32 bit 8 (4+4).
#if WIN32
return 8;
#else
return 12;
#endif // WIN32
}
}
// This method ensures that there is sufficient stack to execute the average Framework function.
// If there is not enough stack, then it throws System.InsufficientExecutionStackException.
// Note: this method is not part of the CER support, and is not to be confused with ProbeForSufficientStack
// below.
[System.Security.SecuritySafeCritical]
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static extern void EnsureSufficientExecutionStack();
[System.Security.SecurityCritical] // auto-generated_required
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static extern void ProbeForSufficientStack();
// This method is a marker placed immediately before a try clause to mark the corresponding catch and finally blocks as
// constrained. There's no code here other than the probe because most of the work is done at JIT time when we spot a call to this routine.
[System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static void PrepareConstrainedRegions()
{
ProbeForSufficientStack();
}
// When we detect a CER with no calls, we can point the JIT to this non-probing version instead
// as we don't need to probe.
[System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static void PrepareConstrainedRegionsNoOP()
{
}
#if FEATURE_CORECLR
[System.Security.SecurityCritical] // auto-generated
#endif
public delegate void TryCode(Object userData);
#if FEATURE_CORECLR
[System.Security.SecurityCritical] // auto-generated
#endif
public delegate void CleanupCode(Object userData, bool exceptionThrown);
[System.Security.SecurityCritical] // auto-generated_required
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData);
#if FEATURE_CORECLR
[System.Security.SecurityCritical] // auto-generated
#endif
[PrePrepareMethod]
internal static void ExecuteBackoutCodeHelper(Object backoutCode, Object userData, bool exceptionThrown)
{
((CleanupCode)backoutCode)(userData, exceptionThrown);
}
}
}
|