Merge pull request #14619 from briansull/emitter-cleanup
[platform/upstream/coreclr.git] / src / vm / eecontract.h
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 // EEContract.h
7 //
8
9 // ! I am the owner for issues in the contract *infrastructure*, not for every 
10 // ! CONTRACT_VIOLATION dialog that comes up. If you interrupt my work for a routine
11 // ! CONTRACT_VIOLATION, you will become the new owner of this file.
12 // ---------------------------------------------------------------------------
13
14
15 #ifndef EECONTRACT_H_
16 #define EECONTRACT_H_
17
18 #include "contract.h"
19 #include "stackprobe.h"
20
21 // --------------------------------------------------------------------------------
22 // EECONTRACT is an extension of the lower level CONTRACT macros to include some
23 // EE specific stuff like GC mode checking.  See check.h for more info on CONTRACT.
24 // --------------------------------------------------------------------------------
25
26 #undef GC_TRIGGERS
27 #undef GC_NOTRIGGER
28
29 #ifdef ENABLE_CONTRACTS_IMPL
30
31 class EEContract : public BaseContract
32 {
33   private:
34     Thread *m_pThread; // Current thread pointer
35     // Have to override this function in any derived class to indicate that a valid destructor is defined for this class
36     virtual void DestructorDefinedThatCallsRestore(){}
37
38   public:
39     __declspec(nothrow) ~EEContract()
40     {
41         Restore();
42     }
43
44     void Disable();
45     void DoChecks(UINT testmask, __in_z const char *szFunction, __in_z char *szFile, int lineNum);
46 };
47
48
49
50 #define MODE_COOPERATIVE     do { STATIC_CONTRACT_MODE_COOPERATIVE; REQUEST_TEST(Contract::MODE_Coop,     Contract::MODE_Disabled); } while(0)
51 #define MODE_PREEMPTIVE      do { STATIC_CONTRACT_MODE_PREEMPTIVE; REQUEST_TEST(Contract::MODE_Preempt,  Contract::MODE_Disabled); } while(0)
52 #define MODE_ANY             do { STATIC_CONTRACT_MODE_ANY; REQUEST_TEST(Contract::MODE_Disabled, Contract::MODE_Disabled); } while(0)
53
54 #define GC_TRIGGERS          do { STATIC_CONTRACT_GC_TRIGGERS; REQUEST_TEST(Contract::GC_Triggers,   Contract::GC_Disabled); } while(0)
55 #define GC_NOTRIGGER         do { STATIC_CONTRACT_GC_NOTRIGGER; REQUEST_TEST(Contract::GC_NoTrigger,  Contract::GC_Disabled); } while(0)
56
57 // Notice there's no static contract component to this.  It's
58 // perfectly reasonable to find EE_THREAD_REQUIRED inside the scope of
59 // EE_THREAD_NOT_REQUIRED (e.g., an EE_THREAD_NOT_REQUIRED scope can have two
60 // possible code paths--one with an EE Thread and one without).  So we can't do
61 // any meaningful testing statically.  It's all gotta be done at runtime.
62 #define EE_THREAD_NOT_REQUIRED  \
63                              do { REQUEST_TEST(Contract::EE_THREAD_Not_Required, Contract::EE_THREAD_Disabled); } while(0)
64
65 #define EE_THREAD_REQUIRED   do { REQUEST_TEST(Contract::EE_THREAD_Required, Contract::EE_THREAD_Disabled); } while(0)
66
67 #define HOST_NOCALLS         do { STATIC_CONTRACT_HOST_NOCALLS; REQUEST_TEST(Contract::HOST_NoCalls, Contract::HOST_Disabled); } while(0)
68 #define HOST_CALLS           do {  STATIC_CONTRACT_HOST_CALLS; REQUEST_TEST(Contract::HOST_Calls, Contract::HOST_Disabled); } while(0)
69
70 #else   // ENABLE_CONTRACTS_IMPL
71
72 #define MODE_COOPERATIVE
73 #define MODE_PREEMPTIVE
74 #define MODE_ANY
75 #define GC_TRIGGERS
76 #define GC_NOTRIGGER
77 #define HOST_NOCALLS
78 #define HOST_CALLS
79 #define EE_THREAD_NOT_REQUIRED
80 #define EE_THREAD_REQUIRED
81
82
83 #endif  // ENABLE_CONTRACTS_IMPL
84
85 // Replace the CONTRACT macro with the EE version
86 #undef CONTRACT
87 #define CONTRACT(_returntype)  CUSTOM_CONTRACT(EEContract, _returntype)
88
89 #undef CONTRACT_VOID
90 #define CONTRACT_VOID  CUSTOM_CONTRACT_VOID(EEContract)
91
92 #undef CONTRACTL
93 #define CONTRACTL  CUSTOM_CONTRACTL(EEContract)
94
95 #undef LIMITED_METHOD_CONTRACT
96 #define LIMITED_METHOD_CONTRACT CUSTOM_LIMITED_METHOD_CONTRACT(EEContract)
97
98 #undef WRAPPER_NO_CONTRACT
99 #define WRAPPER_NO_CONTRACT CUSTOM_WRAPPER_NO_CONTRACT(EEContract)
100
101 //
102 // The default contract is the recommended contract for ordinary EE code.
103 // The ordinary EE code can throw or trigger GC any time, does not operate
104 // on raw object refs, etc.
105 //
106
107 #undef STANDARD_VM_CHECK
108 #define STANDARD_VM_CHECK           \
109     THROWS;                     \
110     GC_TRIGGERS;                \
111     MODE_PREEMPTIVE;            \
112     SO_INTOLERANT;              \
113     INJECT_FAULT(COMPlusThrowOM();); \
114
115 #endif  // EECONTRACT_H_