1 | // Licensed to the .NET Foundation under one or more agreements. |
---|---|
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | // |
5 | // sigparser.cpp |
6 | // |
7 | |
8 | // |
9 | // Signature parsing code |
10 | // |
11 | #include "stdafx.h" |
12 | #include "sigparser.h" |
13 | #include "contract.h" |
14 | |
15 | HRESULT SigParser::SkipExactlyOne() |
16 | { |
17 | CONTRACTL |
18 | { |
19 | INSTANCE_CHECK; |
20 | NOTHROW; |
21 | GC_NOTRIGGER; |
22 | FORBID_FAULT; |
23 | SUPPORTS_DAC; |
24 | } |
25 | CONTRACTL_END |
26 | |
27 | CorElementType typ; |
28 | HRESULT hr = GetElemType(&typ); |
29 | |
30 | IfFailRet(hr); |
31 | |
32 | if (!CorIsPrimitiveType(typ)) |
33 | { |
34 | switch ((DWORD)typ) |
35 | { |
36 | default: |
37 | // _ASSERT(!"Illegal or unimplement type in COM+ sig."); |
38 | return META_E_BAD_SIGNATURE; |
39 | break; |
40 | case ELEMENT_TYPE_VAR: |
41 | case ELEMENT_TYPE_MVAR: |
42 | IfFailRet(GetData(NULL)); // Skip variable number |
43 | break; |
44 | case ELEMENT_TYPE_VAR_ZAPSIG: |
45 | IfFailRet(GetData(NULL)); // Skip RID |
46 | break; |
47 | case ELEMENT_TYPE_OBJECT: |
48 | case ELEMENT_TYPE_STRING: |
49 | case ELEMENT_TYPE_TYPEDBYREF: |
50 | case ELEMENT_TYPE_CANON_ZAPSIG: |
51 | break; |
52 | |
53 | case ELEMENT_TYPE_BYREF: //fallthru |
54 | case ELEMENT_TYPE_PTR: |
55 | case ELEMENT_TYPE_PINNED: |
56 | case ELEMENT_TYPE_SZARRAY: |
57 | case ELEMENT_TYPE_NATIVE_ARRAY_TEMPLATE_ZAPSIG: |
58 | case ELEMENT_TYPE_NATIVE_VALUETYPE_ZAPSIG: |
59 | IfFailRet(SkipExactlyOne()); // Skip referenced type |
60 | break; |
61 | |
62 | case ELEMENT_TYPE_VALUETYPE: //fallthru |
63 | case ELEMENT_TYPE_CLASS: |
64 | IfFailRet(GetToken(NULL)); // Skip RID |
65 | break; |
66 | |
67 | case ELEMENT_TYPE_MODULE_ZAPSIG: |
68 | IfFailRet(GetData(NULL)); // Skip index |
69 | IfFailRet(SkipExactlyOne()); // Skip type |
70 | break; |
71 | |
72 | case ELEMENT_TYPE_FNPTR: |
73 | IfFailRet(SkipSignature()); |
74 | break; |
75 | |
76 | case ELEMENT_TYPE_ARRAY: |
77 | { |
78 | IfFailRet(SkipExactlyOne()); // Skip element type |
79 | ULONG rank; |
80 | IfFailRet(GetData(&rank)); // Get rank |
81 | if (rank) |
82 | { |
83 | ULONG nsizes; |
84 | IfFailRet(GetData(&nsizes)); // Get # of sizes |
85 | while (nsizes--) |
86 | { |
87 | IfFailRet(GetData(NULL)); // Skip size |
88 | } |
89 | |
90 | ULONG nlbounds; |
91 | IfFailRet(GetData(&nlbounds)); // Get # of lower bounds |
92 | while (nlbounds--) |
93 | { |
94 | IfFailRet(GetData(NULL)); // Skip lower bounds |
95 | } |
96 | } |
97 | |
98 | } |
99 | break; |
100 | |
101 | case ELEMENT_TYPE_SENTINEL: |
102 | // Should be unreachable since GetElem strips it |
103 | break; |
104 | |
105 | case ELEMENT_TYPE_INTERNAL: |
106 | IfFailRet(GetPointer(NULL)); |
107 | break; |
108 | |
109 | case ELEMENT_TYPE_GENERICINST: |
110 | IfFailRet(SkipExactlyOne()); // Skip generic type |
111 | ULONG argCnt; |
112 | IfFailRet(GetData(&argCnt)); // Get number of parameters |
113 | while (argCnt--) |
114 | { |
115 | IfFailRet(SkipExactlyOne()); // Skip the parameters |
116 | } |
117 | break; |
118 | |
119 | } |
120 | } |
121 | |
122 | return hr; |
123 | } |
124 | |
125 | //--------------------------------------------------------------------------------------- |
126 | // |
127 | // Skip only a method header signature - not the sigs of the args to the method. |
128 | // |
129 | HRESULT |
130 | SigParser::SkipMethodHeaderSignature( |
131 | ULONG * pcArgs) |
132 | { |
133 | CONTRACTL |
134 | { |
135 | INSTANCE_CHECK; |
136 | NOTHROW; |
137 | GC_NOTRIGGER; |
138 | FORBID_FAULT; |
139 | SUPPORTS_DAC; |
140 | } |
141 | CONTRACTL_END |
142 | |
143 | HRESULT hr = S_OK; |
144 | |
145 | // Skip calling convention |
146 | ULONG uCallConv; |
147 | IfFailRet(GetCallingConvInfo(&uCallConv)); |
148 | |
149 | if ((uCallConv == IMAGE_CEE_CS_CALLCONV_FIELD) || |
150 | (uCallConv == IMAGE_CEE_CS_CALLCONV_LOCAL_SIG)) |
151 | { |
152 | return META_E_BAD_SIGNATURE; |
153 | } |
154 | |
155 | // Skip type parameter count |
156 | if (uCallConv & IMAGE_CEE_CS_CALLCONV_GENERIC) |
157 | IfFailRet(GetData(NULL)); |
158 | |
159 | // Get arg count; |
160 | IfFailRet(GetData(pcArgs)); |
161 | |
162 | // Skip return type; |
163 | IfFailRet(SkipExactlyOne()); |
164 | |
165 | return hr; |
166 | } // SigParser::SkipMethodHeaderSignature |
167 | |
168 | //--------------------------------------------------------------------------------------- |
169 | // |
170 | // Skip a sub signature (as immediately follows an ELEMENT_TYPE_FNPTR). |
171 | HRESULT SigParser::SkipSignature() |
172 | { |
173 | CONTRACTL |
174 | { |
175 | INSTANCE_CHECK; |
176 | NOTHROW; |
177 | GC_NOTRIGGER; |
178 | FORBID_FAULT; |
179 | SUPPORTS_DAC; |
180 | } |
181 | CONTRACTL_END |
182 | |
183 | HRESULT hr = S_OK; |
184 | |
185 | ULONG cArgs; |
186 | |
187 | IfFailRet(SkipMethodHeaderSignature(&cArgs)); |
188 | |
189 | // Skip args. |
190 | while (cArgs) { |
191 | IfFailRet(SkipExactlyOne()); |
192 | cArgs--; |
193 | } |
194 | |
195 | return hr; |
196 | } |
197 |