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
31class 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 const 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_
116