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
15HRESULT 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//
129HRESULT
130SigParser::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).
171HRESULT 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