Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / mscorlib / system / argiterator.cs
blob56b67d05cb7d39f8328193c0cd6fbd74ff8183ca
1 // ==++==
2 //
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 //
5 // ==--==
6 namespace System {
8 using System;
9 using System.Runtime.InteropServices;
10 using System.Runtime.CompilerServices;
11 using System.Runtime.Versioning;
12 using System.Diagnostics.Contracts;
14 // This class will not be marked serializable
15 // Note: This type must have the same layout as the CLR's VARARGS type in CLRVarArgs.h.
16 // It also contains an inline SigPointer data structure - must keep those fields in sync.
17 [StructLayout(LayoutKind.Sequential)]
18 public struct ArgIterator
20 [System.Security.SecurityCritical] // auto-generated
21 [ResourceExposure(ResourceScope.None)]
22 [MethodImplAttribute(MethodImplOptions.InternalCall)]
23 private extern ArgIterator(IntPtr arglist);
25 // create an arg iterator that points at the first argument that
26 // is not statically declared (that is the first ... arg)
27 // 'arglist' is the value returned by the ARGLIST instruction
28 [System.Security.SecuritySafeCritical] // auto-generated
29 public ArgIterator(RuntimeArgumentHandle arglist) : this(arglist.Value)
33 [System.Security.SecurityCritical] // auto-generated
34 [ResourceExposure(ResourceScope.None)]
35 [MethodImplAttribute(MethodImplOptions.InternalCall)]
36 private unsafe extern ArgIterator(IntPtr arglist, void *ptr);
38 // create an arg iterator that points just past 'firstArg'.
39 // 'arglist' is the value returned by the ARGLIST instruction
40 // This is much like the C va_start macro
42 [System.Security.SecurityCritical] // auto-generated
43 [CLSCompliant(false)]
45 public unsafe ArgIterator(RuntimeArgumentHandle arglist, void* ptr) : this(arglist.Value, ptr)
49 // Fetch an argument as a typed referece, advance the iterator.
50 // Throws an exception if past end of argument list
51 [System.Security.SecuritySafeCritical] // auto-generated
52 [CLSCompliant(false)]
53 public TypedReference GetNextArg()
55 TypedReference result = new TypedReference ();
56 // reference to TypedReference is banned, so have to pass result as pointer
57 unsafe
59 FCallGetNextArg (&result);
61 return result;
64 [System.Security.SecurityCritical] // auto-generated
65 [ResourceExposure(ResourceScope.None)]
66 [MethodImplAttribute(MethodImplOptions.InternalCall)]
67 // reference to TypedReference is banned, so have to pass result as void pointer
68 private unsafe extern void FCallGetNextArg(void * result);
70 // Alternate version of GetNextArg() intended primarily for IJW code
71 // generated by VC's "va_arg()" construct.
72 [System.Security.SecuritySafeCritical] // auto-generated
73 [CLSCompliant(false)]
74 public TypedReference GetNextArg(RuntimeTypeHandle rth)
76 if (sigPtr != IntPtr.Zero)
78 // This is an ordinary ArgIterator capable of determining
79 // types from a signature. Just do a regular GetNextArg.
80 return GetNextArg();
82 else
84 // Prevent abuse of this API with a default ArgIterator (it
85 // doesn't require permission to create a zero-inited value
86 // type). Check that ArgPtr isn't zero or this API will allow a
87 // malicious caller to increment the pointer to an arbitrary
88 // location in memory and read the contents.
89 if (ArgPtr == IntPtr.Zero)
90 throw new ArgumentNullException();
92 TypedReference result = new TypedReference ();
93 // reference to TypedReference is banned, so have to pass result as pointer
94 unsafe
96 InternalGetNextArg(&result, rth.GetRuntimeType());
98 return result;
103 [System.Security.SecurityCritical] // auto-generated
104 [ResourceExposure(ResourceScope.None)]
105 [MethodImplAttribute(MethodImplOptions.InternalCall)]
106 // reference to TypedReference is banned, so have to pass result as void pointer
107 private unsafe extern void InternalGetNextArg(void * result, RuntimeType rt);
109 // This method should invalidate the iterator (va_end). It is not supported yet.
110 public void End()
114 // How many arguments are left in the list
115 [System.Security.SecuritySafeCritical] // auto-generated
116 [ResourceExposure(ResourceScope.None)]
117 [MethodImplAttribute(MethodImplOptions.InternalCall)]
118 public extern int GetRemainingCount();
120 // Gets the type of the current arg, does NOT advance the iterator
121 [System.Security.SecurityCritical] // auto-generated
122 [ResourceExposure(ResourceScope.None)]
123 [MethodImplAttribute(MethodImplOptions.InternalCall)]
124 private extern unsafe void* _GetNextArgType();
126 [System.Security.SecuritySafeCritical] // auto-generated
127 public unsafe RuntimeTypeHandle GetNextArgType()
129 return new RuntimeTypeHandle(Type.GetTypeFromHandleUnsafe((IntPtr)_GetNextArgType()));
132 public override int GetHashCode()
134 return ValueType.GetHashCodeOfPtr(ArgCookie);
137 // Inherited from object
138 public override bool Equals(Object o)
140 throw new NotSupportedException(Environment.GetResourceString("NotSupported_NYI"));
143 private IntPtr ArgCookie; // Cookie from the EE.
145 // The SigPointer structure consists of the following members. (Note: this is an inline native SigPointer data type)
146 private IntPtr sigPtr; // Pointer to remaining signature.
147 private IntPtr sigPtrLen; // Remaining length of the pointer
149 // Note, sigPtrLen is actually a DWORD, but on 64bit systems this structure becomes
150 // 8-byte aligned, which requires us to pad it.
152 private IntPtr ArgPtr; // Pointer to remaining args.
153 private int RemainingArgs; // # of remaining args.