Merge pull request #5389 from parjong/fix/issue_5357
[platform/upstream/coreclr.git] / src / vm / mscorlib.cpp
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
6
7 // 
8 // This file defines tables for references between VM and mscorlib.
9 //
10 // When compiling crossgen, this file is compiled with the FEATURE_XXX define settings matching the target.
11 // It allows us to strip features (e.g. refection only load) from crossgen without stripping them from the target.
12 //
13
14 #ifdef CROSSGEN_MSCORLIB
15 // Use minimal set of headers for crossgen
16 #include "windows.h"
17 #include "corinfo.h"
18 #else
19 #include "common.h"
20 #include "ecall.h"
21 #endif // CROSSGEN_MSCORLIB
22
23 #ifndef CROSSGEN_COMPILE
24 //
25 // Headers for all ECall entrypoints
26 //
27 #include "arraynative.h"
28 #include "stringnative.h"
29 #include "stringbuffer.h"
30 #include "securityimperative.h"
31 #include "securitystackwalk.h"
32 #include "objectnative.h"
33 #include "comdelegate.h"
34 #include "customattribute.h"
35 #include "comdynamic.h"
36 #include "commethodrental.h"
37 #ifndef FEATURE_LEGACYSURFACEAREA
38 #include "nlsinfo.h"
39 #endif 
40 #include "calendardata.h"
41 #include "commodule.h"
42 #include "marshalnative.h"
43 #include "system.h"
44 #include "comutilnative.h"
45 #include "comsynchronizable.h"
46 #include "floatdouble.h"
47 #include "floatsingle.h"
48 #include "decimal.h"
49 #include "currency.h"
50 #include "comdatetime.h"
51 #include "comisolatedstorage.h"
52 #include "securityconfig.h"
53 #include "number.h"
54 #include "compatibilityswitch.h"
55 #ifdef FEATURE_REMOTING
56 #include "remotingnative.h"
57 #include "message.h"
58 #include "stackbuildersink.h"
59 #endif
60 #include "debugdebugger.h"
61 #include "assemblyname.hpp"
62 #include "assemblynative.hpp"
63 #include "rwlock.h"
64 #include "comthreadpool.h"
65 #include "comwaithandle.h"
66 #include "nativeoverlapped.h"
67
68 #include "proftoeeinterfaceimpl.h"
69
70 #include "appdomainnative.hpp"
71 #include "arrayhelpers.h"
72 #include "runtimehandles.h"
73 #include "reflectioninvocation.h"
74 #include "managedmdimport.hpp"
75 #include "synchronizationcontextnative.h"
76 #include "newcompressedstack.h"
77 #include "commemoryfailpoint.h"
78 #include "typestring.h"
79 #include "comdependenthandle.h"
80 #include "weakreferencenative.h"
81 #include "varargsnative.h"
82
83 #ifndef FEATURE_CORECLR
84 #include "confighelper.h"
85 #include "console.h"
86 #endif
87
88 #ifdef MDA_SUPPORTED 
89 #include "mdaassistants.h"
90 #endif
91
92 #ifdef FEATURE_CRYPTO
93 #include "cryptography.h"
94 #endif // FEATURE_CRYPTO
95
96 #ifndef FEATURE_CORECLR
97 #include "securityprincipal.h"
98 #endif // !FEATURE_CORECLR
99
100 #ifdef FEATURE_X509
101 #include "x509certificate.h"
102 #endif // FEATURE_X509
103
104 #include "coverage.h"
105
106 #ifdef FEATURE_COMINTEROP
107 #include "variant.h"
108 #ifdef FEATURE_COMINTEROP_TLB_SUPPORT
109 #include "comtypelibconverter.h"
110 #endif
111 #include "oavariant.h"
112 #include "registration.h"
113 #include "mngstdinterfaces.h"
114 #include "extensibleclassfactory.h"
115 #endif // FEATURE_COMINTEROP
116
117 #include "stubhelpers.h"
118 #include "ilmarshalers.h"
119
120 #include "hostexecutioncontext.h"
121
122 #ifdef FEATURE_MULTICOREJIT
123 #include "multicorejit.h"
124 #endif
125
126 #ifdef FEATURE_COMINTEROP
127 #include "clrprivtypecachereflectiononlywinrt.h"
128 #endif
129
130 #ifdef FEATURE_COMINTEROP
131 #include "windowsruntimebufferhelper.h"
132 #endif
133
134 #if defined(FEATURE_EVENTSOURCE_XPLAT)
135 #include "nativeeventsource.h"
136 #endif //defined(FEATURE_EVENTSOURCE_XPLAT)
137
138 #endif // CROSSGEN_MSCORLIB
139
140
141 #ifdef CROSSGEN_MSCORLIB
142
143 ///////////////////////////////////////////////////////////////////////////////
144 //
145 // Duplicate definitions of constants and datastructures required to define the tables
146 //
147
148 #define NumItems(s) (sizeof(s) / sizeof(s[0]))
149
150 #define GetEEFuncEntryPoint(pfn) 0x1001
151
152 enum {
153     FCFuncFlag_EndOfArray   = 0x01,
154     FCFuncFlag_HasSignature = 0x02,
155     FCFuncFlag_Unreferenced = 0x04, // Suppress unused fcall check
156     FCFuncFlag_QCall        = 0x08, // QCall - mscorlib.dll to mscorwks.dll transition implemented as PInvoke
157 };
158
159 struct ECClass
160 {
161     LPCSTR      m_szClassName;
162     LPCSTR      m_szNameSpace;
163     const LPVOID *  m_pECFunc;
164 };
165
166 struct HardCodedMetaSig
167 {
168     const BYTE* m_pMetaSig; // metasig prefixed with INT8 length:
169                             // length > 0 - resolved, lenght < 0 - has unresolved type references
170 };
171
172 enum BinderClassID
173 {
174 #define TYPEINFO(e,ns,c,s,g,ia,ip,if,im,gv)   CLASS__ ## e,
175 #include "cortypeinfo.h"
176 #undef TYPEINFO
177
178 #define DEFINE_CLASS(i,n,s)         CLASS__ ## i,
179 #include "mscorlib.h"
180
181     CLASS__MSCORLIB_COUNT,
182
183     CLASS__VOID     = CLASS__ELEMENT_TYPE_VOID,
184     CLASS__BOOLEAN  = CLASS__ELEMENT_TYPE_BOOLEAN,
185     CLASS__CHAR     = CLASS__ELEMENT_TYPE_CHAR,
186     CLASS__BYTE     = CLASS__ELEMENT_TYPE_U1,
187     CLASS__SBYTE    = CLASS__ELEMENT_TYPE_I1,
188     CLASS__INT16    = CLASS__ELEMENT_TYPE_I2,
189     CLASS__UINT16   = CLASS__ELEMENT_TYPE_U2,
190     CLASS__INT32    = CLASS__ELEMENT_TYPE_I4,
191     CLASS__UINT32   = CLASS__ELEMENT_TYPE_U4,
192     CLASS__INT64    = CLASS__ELEMENT_TYPE_I8,
193     CLASS__UINT64   = CLASS__ELEMENT_TYPE_U8,
194     CLASS__SINGLE   = CLASS__ELEMENT_TYPE_R4,
195     CLASS__DOUBLE   = CLASS__ELEMENT_TYPE_R8,
196     CLASS__STRING   = CLASS__ELEMENT_TYPE_STRING,
197     CLASS__TYPED_REFERENCE = CLASS__ELEMENT_TYPE_TYPEDBYREF,
198     CLASS__INTPTR   = CLASS__ELEMENT_TYPE_I,
199     CLASS__UINTPTR  = CLASS__ELEMENT_TYPE_U,
200     CLASS__OBJECT   = CLASS__ELEMENT_TYPE_OBJECT
201 };
202
203 struct MscorlibClassDescription
204 {
205     LPCSTR  nameSpace;
206     LPCSTR  name;
207 };
208
209 struct MscorlibMethodDescription
210 {
211     BinderClassID classID;
212     LPCSTR  name;
213     const HardCodedMetaSig * sig;
214 };
215
216 struct MscorlibFieldDescription
217 {
218     BinderClassID classID;
219     LPCSTR  name;
220 };
221
222 #endif // CROSSGEN_MSCORLIB
223
224
225 #ifdef CROSSGEN_MSCORLIB
226 // When compiling crossgen this namespace creates the second version of the tables than matches the target
227 namespace CrossGenMscorlib {
228 #endif
229
230
231 ///////////////////////////////////////////////////////////////////////////////
232 //
233 // Hardcoded Meta-Sig
234 //
235
236 //
237 // Helper enum with metasig lengths
238 //
239 // iterate over the metasig recursing into the complex types
240 #define DEFINE_METASIG(body)            body,
241 #define METASIG_ATOM(x)                 + 1
242 #define METASIG_RECURSE                 1
243 #define SM(varname, args, retval)       gsigl_SM_ ## varname = 1 + 1 retval args
244 #define IM(varname, args, retval)       gsigl_IM_ ## varname = 1 + 1 retval args
245 #define GM(varname, conv, n, args, retval) gsigl_GM_ ## varname = 1 + 1 + 1 + retval args
246 #define Fld(varname, val)               gsigl_Fld_ ## varname = 1 val
247 enum _gsigl {
248 #include "metasig.h"
249 };
250
251 //
252 // Helper enum with metasig argcount
253 //
254 // iterate over the metasig without recursing into the complex types
255 #define DEFINE_METASIG(body)            body,
256 #define METASIG_ATOM(x)                 + 1
257 #define METASIG_RECURSE                 0
258 #define SM(varname, args, retval)       gsigc_SM_ ## varname = 0 args
259 #define IM(varname, args, retval)       gsigc_IM_ ## varname = 0 args
260 #define GM(varname, conv, n, args, retval) gsigc_GM_ ## varname = 0 args
261 #define Fld(varname, val)               gsigc_Fld_ ## varname = 0
262 enum _gsigc {
263 #include "metasig.h"
264 };
265
266
267 //
268 // The actual array with the hardcoded metasig:
269 //
270 // There are 3 variations of the macros for Fields, Static Methods and Instance Methods.
271 //
272 // Each of them has 2 flavors: one for the fully baked signatures, and the other 
273 // for the signatures with unresolved type references
274 //
275 // The signatures with unresolved type references are marked with negative size, 
276 // and the pointer to them is non-const because of it will be overwritten with
277 // the pointer to the resolved signature at runtime.
278 //
279
280 #define DEFINE_METASIG(body)            body
281 #define DEFINE_METASIG_T(body)          _##body
282 #define METASIG_ATOM(x)                 x,
283 #define METASIG_RECURSE                 1
284
285 // define gsig_ ## varname before gsige_ ## varname to give a hint to the compiler about the desired layout
286
287 #define SM(varname, args, retval) extern const BYTE gsige_SM_ ## varname[];     \
288     const HardCodedMetaSig gsig_SM_ ## varname = { gsige_SM_ ## varname };      \
289     const BYTE gsige_SM_ ## varname[] = { gsigl_SM_ ## varname,                 \
290         IMAGE_CEE_CS_CALLCONV_DEFAULT, gsigc_SM_ ## varname, retval args };
291
292 #define IM(varname, args, retval) extern const BYTE gsige_IM_ ## varname[];     \
293     const HardCodedMetaSig gsig_IM_ ## varname = { gsige_IM_ ## varname };      \
294     const BYTE gsige_IM_ ## varname[] = { gsigl_IM_ ## varname,                 \
295         IMAGE_CEE_CS_CALLCONV_HASTHIS, gsigc_IM_ ## varname, retval args };
296
297 #define GM(varname, conv, n, args, retval) extern const BYTE gsige_GM_ ## varname[];    \
298     const HardCodedMetaSig gsig_GM_ ## varname = { gsige_GM_ ## varname };              \
299     const BYTE gsige_GM_ ## varname[] = { gsigl_GM_ ## varname,                         \
300         conv | IMAGE_CEE_CS_CALLCONV_GENERIC, n, gsigc_GM_ ## varname, retval args };
301
302 #define Fld(varname, val) extern const BYTE gsige_Fld_ ## varname[];            \
303     const HardCodedMetaSig gsig_Fld_ ## varname = { gsige_Fld_ ## varname };    \
304     const BYTE gsige_Fld_ ## varname[] = { gsigl_Fld_ ## varname,               \
305         IMAGE_CEE_CS_CALLCONV_FIELD, val };
306
307 #define _SM(varname, args, retval) extern const BYTE gsige_SM_ ## varname[];    \
308     HardCodedMetaSig gsig_SM_ ## varname = { gsige_SM_ ## varname };            \
309     const BYTE gsige_SM_ ## varname[] = { (BYTE) -gsigl_SM_ ## varname,         \
310         IMAGE_CEE_CS_CALLCONV_DEFAULT, gsigc_SM_ ## varname, retval args };
311
312 #define _IM(varname, args, retval) extern const BYTE gsige_IM_ ## varname[];    \
313     HardCodedMetaSig gsig_IM_ ## varname = { gsige_IM_ ## varname };            \
314     const BYTE gsige_IM_ ## varname[] = { (BYTE) -gsigl_IM_ ## varname,         \
315         IMAGE_CEE_CS_CALLCONV_HASTHIS, gsigc_IM_ ## varname, retval args };
316
317 #define _Fld(varname, val) extern const BYTE gsige_Fld_ ## varname[];           \
318     HardCodedMetaSig gsig_Fld_ ## varname = { gsige_Fld_ ## varname };          \
319     const BYTE gsige_Fld_ ## varname[] = { (BYTE) -gsigl_Fld_ ## varname,       \
320         IMAGE_CEE_CS_CALLCONV_FIELD, val };
321
322 #include "metasig.h"
323
324 #undef _SM
325 #undef _IM
326 #undef _Fld
327
328
329
330 #ifdef _DEBUG
331
332 //
333 // Make sure DEFINE_METASIG is used for signatures that do not reference other types
334 //
335 // counts number of type references in the signature and C_ASSERTs that 
336 // it is zero. An assertion failure results in error C2118: negative subscript.
337 #define DEFINE_METASIG(body)            body
338 #define DEFINE_METASIG_T(body)
339 #define METASIG_BODY(varname, types)    C_ASSERT(types 0 == 0);
340 #define METASIG_ATOM(x)                 0+
341 #define METASIG_RECURSE                 1
342 #define C(x)                            1+
343 #define g(x)                            1+
344 #include "metasig.h"
345
346 //
347 // Make sure DEFINE_METASIG_T is used only for signatures that reference 
348 // other types.
349 //
350 // counts number of type references in the signature and C_ASSERTs that 
351 // it is non zero. An assertion failure results in error C2118: negative subscript.
352 #define DEFINE_METASIG(body)
353 #define DEFINE_METASIG_T(body)          body
354 #define METASIG_BODY(varname, types)    C_ASSERT(types 0 != 0);
355 #define METASIG_ATOM(x)                 0+
356 #define METASIG_RECURSE                 1
357 #define C(x)                            1+
358 #define g(x)                            1+
359 #include "metasig.h"
360
361 #endif
362
363
364
365
366
367 ///////////////////////////////////////////////////////////////////////////////
368 //
369 // Mscorlib binder
370 //
371
372 // Extern definitions so that binder.cpp can see these tables
373 extern const MscorlibClassDescription c_rgMscorlibClassDescriptions[];
374 extern const USHORT c_nMscorlibClassDescriptions;
375
376 extern const MscorlibMethodDescription c_rgMscorlibMethodDescriptions[];
377 extern const USHORT c_nMscorlibMethodDescriptions;
378
379 extern const MscorlibFieldDescription c_rgMscorlibFieldDescriptions[];
380 extern const USHORT c_nMscorlibFieldDescriptions;
381
382 const MscorlibClassDescription c_rgMscorlibClassDescriptions[] =
383 {
384     #define TYPEINFO(e,ns,c,s,g,ia,ip,if,im,gv)   { ns, c },
385     #include "cortypeinfo.h"
386     #undef TYPEINFO
387     
388     #define DEFINE_CLASS(i,n,s)        { g_ ## n ## NS, # s },
389     #include "namespace.h"
390     #include "mscorlib.h"
391     
392     // Include all exception types here that are defined in mscorlib.  Omit exceptions defined elsewhere.
393     #define DEFINE_EXCEPTION(ns, reKind, bHRformessage, ...) { ns , # reKind },
394     #define DEFINE_EXCEPTION_HR_WINRT_ONLY(ns, reKind, ...)
395     #define DEFINE_EXCEPTION_IN_OTHER_FX_ASSEMBLY(ns, reKind, assemblySimpleName, publicKeyToken, bHRformessage, ...)
396     #include "rexcep.h"
397 };
398 const USHORT c_nMscorlibClassDescriptions = NumItems(c_rgMscorlibClassDescriptions);
399
400 #define gsig_NoSig (*(HardCodedMetaSig *)NULL)
401
402 const MscorlibMethodDescription c_rgMscorlibMethodDescriptions[] =
403 {
404     #define DEFINE_METHOD(c,i,s,g)          { CLASS__ ## c , # s, & gsig_ ## g },
405     #include "mscorlib.h"
406 };
407 const USHORT c_nMscorlibMethodDescriptions = NumItems(c_rgMscorlibMethodDescriptions) + 1;
408
409 const MscorlibFieldDescription c_rgMscorlibFieldDescriptions[] =
410 {
411     #define DEFINE_FIELD(c,i,s)           { CLASS__ ## c , # s },
412     #include "mscorlib.h"
413 };
414 const USHORT c_nMscorlibFieldDescriptions = NumItems(c_rgMscorlibFieldDescriptions) + 1;
415
416
417
418
419
420 ///////////////////////////////////////////////////////////////////////////////
421 //
422 // ECalls
423 //
424
425 // When compiling crossgen, we only need the target version of the ecall tables
426 #if !defined(CROSSGEN_COMPILE) || defined(CROSSGEN_MSCORLIB)
427
428 #ifdef CROSSGEN_COMPILE
429
430 #define QCFuncElement(name,impl) \
431     FCFuncFlag_QCall + FCFuncFlags(CORINFO_INTRINSIC_Illegal, ECall::InvalidDynamicFCallId), NULL, (LPVOID)name,
432
433 #define FCFuncFlags(intrinsicID, dynamicID) \
434     (BYTE*)( (((BYTE)intrinsicID) << 16) )
435
436 #else
437
438 #define QCFuncElement(name,impl) \
439     FCFuncFlag_QCall + FCFuncFlags(CORINFO_INTRINSIC_Illegal, ECall::InvalidDynamicFCallId), (LPVOID)(impl), (LPVOID)name,
440
441 #define FCFuncFlags(intrinsicID, dynamicID) \
442     (BYTE*)( (((BYTE)intrinsicID) << 16) + (((BYTE)dynamicID) << 24) )
443
444 #endif
445
446 #define FCFuncElement(name, impl) FCFuncFlags(CORINFO_INTRINSIC_Illegal, ECall::InvalidDynamicFCallId), \
447     (LPVOID)GetEEFuncEntryPoint(impl), (LPVOID)name,
448
449 #define FCFuncElementSig(name,sig,impl) \
450     FCFuncFlag_HasSignature + FCFuncElement(name, impl) (LPVOID)sig,
451
452 #define FCIntrinsic(name,impl,intrinsicID) FCFuncFlags(intrinsicID, ECall::InvalidDynamicFCallId), \
453     (LPVOID)GetEEFuncEntryPoint(impl), (LPVOID)name,
454
455 #define FCIntrinsicSig(name,sig,impl,intrinsicID) \
456     FCFuncFlag_HasSignature + FCIntrinsic(name,impl,intrinsicID) (LPVOID)sig,
457
458 #define FCDynamic(name,intrinsicID,dynamicID) FCFuncFlags(intrinsicID, dynamicID), \
459     NULL, (LPVOID)name,
460
461 #define FCDynamicSig(name,sig,intrinsicID,dynamicID) \
462     FCFuncFlag_HasSignature + FCDynamic(name,intrinsicID,dynamicID) (LPVOID)sig,
463
464 #define FCUnreferenced FCFuncFlag_Unreferenced +
465
466 #define FCFuncStart(name) static const LPVOID name[] = {
467 #define FCFuncEnd() FCFuncFlag_EndOfArray + FCFuncFlags(CORINFO_INTRINSIC_Illegal, ECall::InvalidDynamicFCallId) };
468
469 #include "ecalllist.h"
470
471
472 // Extern definitions so that ecall.cpp can see these tables
473 extern const ECClass c_rgECClasses[];
474 extern const int c_nECClasses;
475
476 const ECClass c_rgECClasses[] =
477 {
478 #define FCClassElement(name,namespace,funcs) {name, namespace, funcs},
479 #include "ecalllist.h"
480 };  // c_rgECClasses[]
481
482 const int c_nECClasses = NumItems(c_rgECClasses);
483
484 #endif // !CROSSGEN_COMPILE && CROSSGEN_MSCORLIB
485
486
487 #ifdef CROSSGEN_MSCORLIB
488 }; // namespace CrossGenMscorlib
489 #endif