3 // Copyright (c) Microsoft Corporation. All rights reserved.
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
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
53 public TypedReference
GetNextArg()
55 TypedReference result
= new TypedReference ();
56 // reference to TypedReference is banned, so have to pass result as pointer
59 FCallGetNextArg (&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
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.
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
96 InternalGetNextArg(&result
, rth
.GetRuntimeType());
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.
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.