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/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7XX XX
8XX EEInterface XX
9XX XX
10XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
11XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
12*/
13
14// ONLY FUNCTIONS common to all variants of the JIT (EXE, DLL) should go here)
15// otherwise they belong in the corresponding directory.
16
17#include "jitpch.h"
18
19#ifdef _MSC_VER
20#pragma hdrstop
21#endif
22
23#if defined(DEBUG) || defined(FEATURE_JIT_METHOD_PERF) || defined(FEATURE_SIMD)
24
25#pragma warning(push)
26#pragma warning(disable : 4701) // difficult to get rid of C4701 with 'sig' below
27
28/*****************************************************************************/
29
30/*****************************************************************************
31*
32* Filter wrapper to handle exception filtering.
33* On Unix compilers don't support SEH.
34*/
35
36struct FilterSuperPMIExceptionsParam_eeinterface
37{
38 Compiler* pThis;
39 Compiler::Info* pJitInfo;
40 bool hasThis;
41 size_t siglength;
42 CORINFO_SIG_INFO sig;
43 CORINFO_ARG_LIST_HANDLE argLst;
44 CORINFO_METHOD_HANDLE hnd;
45 const char* returnType;
46 EXCEPTION_POINTERS exceptionPointers;
47};
48
49static LONG FilterSuperPMIExceptions_eeinterface(PEXCEPTION_POINTERS pExceptionPointers, LPVOID lpvParam)
50{
51 FilterSuperPMIExceptionsParam_eeinterface* pSPMIEParam = (FilterSuperPMIExceptionsParam_eeinterface*)lpvParam;
52 pSPMIEParam->exceptionPointers = *pExceptionPointers;
53
54 if (pSPMIEParam->pThis->IsSuperPMIException(pExceptionPointers->ExceptionRecord->ExceptionCode))
55 {
56 return EXCEPTION_EXECUTE_HANDLER;
57 }
58
59 return EXCEPTION_CONTINUE_SEARCH;
60}
61
62const char* Compiler::eeGetMethodFullName(CORINFO_METHOD_HANDLE hnd)
63{
64 const char* className;
65 const char* methodName = eeGetMethodName(hnd, &className);
66 if ((eeGetHelperNum(hnd) != CORINFO_HELP_UNDEF) || eeIsNativeMethod(hnd))
67 {
68 return methodName;
69 }
70
71 FilterSuperPMIExceptionsParam_eeinterface param;
72 param.returnType = nullptr;
73 param.pThis = this;
74 param.hasThis = false;
75 param.siglength = 0;
76 param.hnd = hnd;
77 param.pJitInfo = &info;
78
79 size_t length = 0;
80 unsigned i;
81
82 /* Generating the full signature is a two-pass process. First we have to walk
83 the components in order to assess the total size, then we allocate the buffer
84 and copy the elements into it.
85 */
86
87 /* Right now there is a race-condition in the EE, className can be nullptr */
88
89 /* initialize length with length of className and '.' */
90
91 if (className)
92 {
93 length = strlen(className) + 1;
94 }
95 else
96 {
97 assert(strlen("<NULL>.") == 7);
98 length = 7;
99 }
100
101 /* add length of methodName and opening bracket */
102 length += strlen(methodName) + 1;
103
104 /* figure out the signature */
105
106 PAL_TRY(FilterSuperPMIExceptionsParam_eeinterface*, pParam, &param)
107 {
108 unsigned i;
109 pParam->pThis->eeGetMethodSig(pParam->hnd, &pParam->sig);
110 pParam->argLst = pParam->sig.args;
111
112 for (i = 0; i < pParam->sig.numArgs; i++)
113 {
114 var_types type = pParam->pThis->eeGetArgType(pParam->argLst, &pParam->sig);
115
116 pParam->siglength += strlen(varTypeName(type));
117 pParam->argLst = pParam->pJitInfo->compCompHnd->getArgNext(pParam->argLst);
118 }
119
120 /* add ',' if there is more than one argument */
121
122 if (pParam->sig.numArgs > 1)
123 {
124 pParam->siglength += (pParam->sig.numArgs - 1);
125 }
126
127 if (JITtype2varType(pParam->sig.retType) != TYP_VOID)
128 {
129 pParam->returnType = varTypeName(JITtype2varType(pParam->sig.retType));
130 pParam->siglength += strlen(pParam->returnType) + 1; // don't forget the delimiter ':'
131 }
132
133 // Does it have a 'this' pointer? Don't count explicit this, which has the this pointer type as the first
134 // element of the arg type list
135 if (pParam->sig.hasThis() && !pParam->sig.hasExplicitThis())
136 {
137 assert(strlen(":this") == 5);
138 pParam->siglength += 5;
139 pParam->hasThis = true;
140 }
141 }
142 PAL_EXCEPT_FILTER(FilterSuperPMIExceptions_eeinterface)
143 {
144 param.siglength = 0;
145 }
146 PAL_ENDTRY
147
148 /* add closing bracket and null terminator */
149
150 length += param.siglength + 2;
151
152 char* retName = getAllocator(CMK_DebugOnly).allocate<char>(length);
153
154 /* Now generate the full signature string in the allocated buffer */
155
156 if (className)
157 {
158 strcpy_s(retName, length, className);
159 strcat_s(retName, length, ":");
160 }
161 else
162 {
163 strcpy_s(retName, length, "<NULL>.");
164 }
165
166 strcat_s(retName, length, methodName);
167
168 // append the signature
169 strcat_s(retName, length, "(");
170
171 if (param.siglength > 0)
172 {
173 param.argLst = param.sig.args;
174
175 for (i = 0; i < param.sig.numArgs; i++)
176 {
177 var_types type = eeGetArgType(param.argLst, &param.sig);
178 strcat_s(retName, length, varTypeName(type));
179
180 param.argLst = info.compCompHnd->getArgNext(param.argLst);
181 if (i + 1 < param.sig.numArgs)
182 {
183 strcat_s(retName, length, ",");
184 }
185 }
186 }
187
188 strcat_s(retName, length, ")");
189
190 if (param.returnType != nullptr)
191 {
192 strcat_s(retName, length, ":");
193 strcat_s(retName, length, param.returnType);
194 }
195
196 if (param.hasThis)
197 {
198 strcat_s(retName, length, ":this");
199 }
200
201 assert(strlen(retName) == (length - 1));
202
203 return (retName);
204}
205
206#pragma warning(pop)
207
208#endif // defined(DEBUG) || defined(FEATURE_JIT_METHOD_PERF) || defined(FEATURE_SIMD)
209
210/*****************************************************************************/
211