+ if (!kIsWindows) {
+ return reinterpret_cast<std::uintptr_t>(&e);
+ } else {
+ // On Windows, as of MSVC2017, all thrown exceptions are copied to the stack
+ // first. Thus, we cannot depend on exception references associated with an
+ // exception_ptr to be live for the duration of the exception_ptr. We need
+ // to directly access the heap allocated memory inside the exception_ptr.
+ //
+ // std::exception_ptr is an opaque reinterpret_cast of
+ // std::shared_ptr<__ExceptionPtr>
+ // __ExceptionPtr is a non-virtual class with two members, a union and a
+ // bool. The union contains the now-undocumented EHExceptionRecord, which
+ // contains a struct which contains a void* which points to the heap
+ // allocated exception.
+ // We derive the offset to pExceptionObject via manual means.
+ FOLLY_PACK_PUSH
+ struct Win32ExceptionPtr {
+ char offset[40];
+ void* exceptionObject;
+ } FOLLY_PACK_ATTR;
+ FOLLY_PACK_POP
+
+ auto* win32ExceptionPtr =
+ reinterpret_cast<std::shared_ptr<Win32ExceptionPtr> const*>(
+ &ptr)->get();
+ return reinterpret_cast<std::uintptr_t>(win32ExceptionPtr->exceptionObject);
+ }