1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#ifndef __CALLCONVBUILDER_H__
#define __CALLCONVBUILDER_H__
#include "corinfo.h"
// Attempts to parse the provided calling convention names to construct a
// calling convention with known modifiers.
//
// The Add* functions return false if the type is known but cannot be applied.
// Otherwise, they return true.
class CallConvBuilder final
{
public:
enum CallConvModifiers
{
CALL_CONV_MOD_NONE = 0,
CALL_CONV_MOD_SUPPRESSGCTRANSITION = 0x1,
CALL_CONV_MOD_MEMBERFUNCTION = 0x2
};
struct State
{
CorInfoCallConvExtension CallConvBase;
CallConvModifiers CallConvModifiers;
};
private:
State _state;
public:
// The initial "unset" base calling convention.
static const CorInfoCallConvExtension UnsetValue;
CallConvBuilder();
// Add a fully qualified type name to the calling convention computation.
bool AddFullyQualifiedTypeName(
_In_ size_t typeLength,
_In_z_ LPCSTR typeName);
// Add a simple type name to the calling convention computation.
bool AddTypeName(
_In_ size_t typeLength,
_In_z_ LPCSTR typeName);
// Get the currently computed calling convention value.
CorInfoCallConvExtension GetCurrentCallConv() const;
// Check if the modifier is set on the computed calling convention.
bool IsCurrentCallConvModSet(_In_ CallConvModifiers mod) const;
};
namespace CallConv
{
static CorInfoCallConvExtension GetDefaultUnmanagedCallingConvention()
{
#ifdef TARGET_UNIX
return CorInfoCallConvExtension::C;
#else // TARGET_UNIX
return CorInfoCallConvExtension::Stdcall;
#endif // !TARGET_UNIX
}
//-------------------------------------------------------------------------
// Gets the unmanaged calling convention by reading any modopts.
//
// Returns:
// S_OK - No errors
// COR_E_BADIMAGEFORMAT - Signature had an invalid format
// COR_E_INVALIDPROGRAM - Program is considered invalid (more
// than one calling convention specified)
//-------------------------------------------------------------------------
HRESULT TryGetUnmanagedCallingConventionFromModOpt(
_In_ CORINFO_MODULE_HANDLE pModule,
_In_ PCCOR_SIGNATURE pSig,
_In_ ULONG cSig,
_Inout_ CallConvBuilder *builder,
_Out_ UINT *errorResID);
//-------------------------------------------------------------------------
// Gets the calling convention from the UnmanagedCallConv attribute
//
// Returns:
// S_OK - No errors
// S_FALSE - UnmanagedCallConv or UnmanagedCallConv.CallConvs not specified
// COR_E_INVALIDPROGRAM - Program is considered invalid (more
// than one calling convention specified)
//-------------------------------------------------------------------------
HRESULT TryGetCallingConventionFromUnmanagedCallConv(
_In_ MethodDesc* pMD,
_Inout_ CallConvBuilder* builder,
_Out_opt_ UINT* errorResID);
//-------------------------------------------------------------------------
// Gets the unmanaged calling convention from the UnmanagedCallersOnly attribute.
//
// Returns:
// true - No errors
// false - Not specified or invalid (more than one calling convention specified)
//-------------------------------------------------------------------------
bool TryGetCallingConventionFromUnmanagedCallersOnly(_In_ MethodDesc* pMD, _Out_ CorInfoCallConvExtension* callConv);
}
#endif // __CALLCONVBUILDER_H__
|