summaryrefslogtreecommitdiff
path: root/src/inc/eexcp.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/inc/eexcp.h')
-rw-r--r--src/inc/eexcp.h156
1 files changed, 156 insertions, 0 deletions
diff --git a/src/inc/eexcp.h b/src/inc/eexcp.h
new file mode 100644
index 0000000000..b91522b4d8
--- /dev/null
+++ b/src/inc/eexcp.h
@@ -0,0 +1,156 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// ==++==
+//
+
+//
+//
+
+//
+// ==--==
+
+
+#ifndef __eexcp_h__
+#define __eexcp_h__
+
+#include "corhlpr.h"
+#include "daccess.h"
+
+struct EE_ILEXCEPTION_CLAUSE;
+typedef DPTR(EE_ILEXCEPTION_CLAUSE) PTR_EE_ILEXCEPTION_CLAUSE;
+
+// The exception handling sub-system needs to keep track of EH clause that is handling given exception.
+// PTR_EXCEPTION_CLAUSE_TOKEN is opaque pointer that uniquely identifies
+// exception handling clause. It abstracts away encoding differences of EH clauses between JIT and NGen.
+typedef PTR_VOID PTR_EXCEPTION_CLAUSE_TOKEN;
+
+struct EE_ILEXCEPTION_CLAUSE {
+ //Flags is not marked as volatile since it is always accessed
+ // from within a critical section
+ CorExceptionFlag Flags;
+ DWORD TryStartPC;
+ DWORD TryEndPC;
+ DWORD HandlerStartPC;
+ DWORD HandlerEndPC;
+ union {
+ void* TypeHandle;
+ mdToken ClassToken;
+ DWORD FilterOffset;
+ };
+};
+
+struct EE_ILEXCEPTION;
+typedef DPTR(EE_ILEXCEPTION) PTR_EE_ILEXCEPTION;
+
+struct EE_ILEXCEPTION : public COR_ILMETHOD_SECT_FAT
+{
+ EE_ILEXCEPTION_CLAUSE Clauses[1]; // actually variable size
+
+ void Init(unsigned ehCount)
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ SetKind(CorILMethod_Sect_FatFormat);
+ SetDataSize((unsigned)sizeof(EE_ILEXCEPTION_CLAUSE) * ehCount);
+ }
+
+ unsigned EHCount() const
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ return GetDataSize() / (DWORD) sizeof(EE_ILEXCEPTION_CLAUSE);
+ }
+
+ static unsigned Size(unsigned ehCount)
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ _ASSERTE(ehCount > 0);
+
+ return (offsetof(EE_ILEXCEPTION, Clauses) + sizeof(EE_ILEXCEPTION_CLAUSE) * ehCount);
+ }
+ EE_ILEXCEPTION_CLAUSE *EHClause(unsigned i)
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+ return &(PTR_EE_ILEXCEPTION_CLAUSE(PTR_HOST_MEMBER_TADDR(EE_ILEXCEPTION,this,Clauses))[i]);
+ }
+};
+
+#define COR_ILEXCEPTION_CLAUSE_CACHED_CLASS 0x10000000
+
+inline BOOL HasCachedTypeHandle(EE_ILEXCEPTION_CLAUSE *EHClause)
+{
+ _ASSERTE(sizeof(EHClause->Flags) == sizeof(DWORD));
+ return (EHClause->Flags & COR_ILEXCEPTION_CLAUSE_CACHED_CLASS);
+}
+
+inline void SetHasCachedTypeHandle(EE_ILEXCEPTION_CLAUSE *EHClause)
+{
+ _ASSERTE(! HasCachedTypeHandle(EHClause));
+ EHClause->Flags = (CorExceptionFlag)(EHClause->Flags | COR_ILEXCEPTION_CLAUSE_CACHED_CLASS);
+}
+
+inline BOOL IsFinally(EE_ILEXCEPTION_CLAUSE *EHClause)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ return (EHClause->Flags & COR_ILEXCEPTION_CLAUSE_FINALLY);
+}
+
+inline BOOL IsFault(EE_ILEXCEPTION_CLAUSE *EHClause)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ return (EHClause->Flags & COR_ILEXCEPTION_CLAUSE_FAULT);
+}
+
+inline BOOL IsFaultOrFinally(EE_ILEXCEPTION_CLAUSE *EHClause)
+{
+ return IsFault(EHClause) || IsFinally(EHClause);
+}
+
+inline BOOL IsFilterHandler(EE_ILEXCEPTION_CLAUSE *EHClause)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ return EHClause->Flags & COR_ILEXCEPTION_CLAUSE_FILTER;
+}
+
+inline BOOL IsTypedHandler(EE_ILEXCEPTION_CLAUSE *EHClause)
+{
+ return ! (IsFilterHandler(EHClause) || IsFaultOrFinally(EHClause));
+}
+
+inline BOOL IsDuplicateClause(EE_ILEXCEPTION_CLAUSE* pEHClause)
+{
+ return pEHClause->Flags & COR_ILEXCEPTION_CLAUSE_DUPLICATED;
+}
+
+#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
+// Finally is the only EH construct that can be part of the execution as being fall-through.
+//
+// "Cloned" finally is a contruct that represents a finally block that is used as
+// fall through for normal try-block execution. Such a "cloned" finally will:
+//
+// 1) Have its try-clause's Start and End PC the same as its handler's start PC (i.e. will have
+// zero length try block), AND
+// 2) Is marked duplicate
+//
+// Because of their fall-through nature, JIT guarantees that only finally constructs can be cloned,
+// and not catch or fault (since they cannot be fallen through but are invoked as funclets).
+//
+// The cloned finally construct is also used to mark "call to finally" thunks that are not within
+// the EH region protected by the finally, and also not within the enclosing region. This is done
+// to prevent ThreadAbortException from creating an infinite loop of calling the same finally.
+inline BOOL IsClonedFinally(EE_ILEXCEPTION_CLAUSE* pEHClause)
+{
+ return ((pEHClause->TryStartPC == pEHClause->TryEndPC) &&
+ (pEHClause->TryStartPC == pEHClause->HandlerStartPC) &&
+ IsFinally(pEHClause) && IsDuplicateClause(pEHClause));
+}
+#endif // defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
+
+#endif // __eexcp_h__
+