BVB Source Codes

mars Show clone_current_exception_non_intrusive.cpp Source code

Return Download mars: download clone_current_exception_non_intrusive.cpp Source code - Download mars Source code - Type:.cpp
  1. //Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
  2.  
  3. //Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5.  
  6. //This MSVC-specific cpp file implements non-intrusive cloning of exception objects.
  7. //Based on an exception_ptr implementation by Anthony Williams.
  8.  
  9. #ifdef BOOST_NO_EXCEPTIONS
  10. #error This file requires exception handling to be enabled.
  11. #endif
  12.  
  13. #include <boost/exception/detail/clone_current_exception.hpp>
  14.  
  15. #if defined(BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR) && defined(_MSC_VER) && defined(_M_IX86) && !defined(_M_X64)
  16.  
  17. //Non-intrusive cloning support implemented below, only for MSVC versions mentioned above.
  18. //Thanks Anthony Williams!
  19.  
  20. #include <boost/exception/exception.hpp>
  21. #include <boost/shared_ptr.hpp>
  22. #ifndef BOOST_NO_RTTI
  23. #include <typeinfo>
  24. #endif
  25. #include <windows.h>
  26. #include <malloc.h>
  27.  
  28. namespace
  29.     {
  30.     unsigned const exception_maximum_parameters=15;
  31.     unsigned const exception_noncontinuable=1;
  32.  
  33. #if _MSC_VER==1310
  34.     int const exception_info_offset=0x74;
  35. #elif (_MSC_VER==1400 || _MSC_VER==1500)
  36.     int const exception_info_offset=0x80;
  37. #else
  38.     int const exception_info_offset=-1;
  39. #endif
  40.  
  41.     struct
  42.     exception_record
  43.         {
  44.         unsigned long ExceptionCode;
  45.         unsigned long ExceptionFlags;
  46.         exception_record * ExceptionRecord;
  47.         void * ExceptionAddress;
  48.         unsigned long NumberParameters;
  49.         ULONG_PTR ExceptionInformation[exception_maximum_parameters];
  50.         };
  51.  
  52.     struct
  53.     exception_pointers
  54.         {
  55.         exception_record * ExceptionRecord;
  56.         void * ContextRecord;
  57.         };
  58.  
  59.     unsigned const cpp_exception_code=0xE06D7363;
  60.     unsigned const cpp_exception_magic_flag=0x19930520;
  61.     unsigned const cpp_exception_parameter_count=3;
  62.  
  63.     struct
  64.     dummy_exception_type
  65.         {
  66.         };
  67.  
  68.     typedef int(dummy_exception_type::*normal_copy_constructor_ptr)(void * src);
  69.     typedef int(dummy_exception_type::*copy_constructor_with_virtual_base_ptr)(void * src,void * dst);
  70.     typedef void (dummy_exception_type::*destructor_ptr)();
  71.  
  72.     union
  73.     cpp_copy_constructor
  74.         {
  75.         normal_copy_constructor_ptr normal_copy_constructor;
  76.         copy_constructor_with_virtual_base_ptr copy_constructor_with_virtual_base;
  77.         };
  78.  
  79.     enum
  80.     cpp_type_flags
  81.         {
  82.         class_is_simple_type=1,
  83.         class_has_virtual_base=4
  84.         };
  85.  
  86.     struct
  87.     cpp_type_info
  88.         {
  89.         unsigned flags;
  90. #ifndef BOOST_NO_RTTI
  91.         void const * type_info;
  92. #else
  93.         std::type_info * type_info;
  94. #endif
  95.         int this_offset;
  96.         int vbase_descr;
  97.         int vbase_offset;
  98.         unsigned long size;
  99.         cpp_copy_constructor copy_constructor;
  100.         };
  101.  
  102.     struct
  103.     cpp_type_info_table
  104.         {
  105.         unsigned count;
  106.         const cpp_type_info * info[1];
  107.         };
  108.  
  109.     struct
  110.     cpp_exception_type
  111.         {
  112.         unsigned flags;
  113.         destructor_ptr destructor;
  114.         void(*custom_handler)();
  115.         cpp_type_info_table const * type_info_table;
  116.         };
  117.  
  118.     struct
  119.     exception_object_deleter
  120.         {
  121.         cpp_exception_type const & et_;
  122.  
  123.         exception_object_deleter( cpp_exception_type const & et ):
  124.             et_(et)
  125.             {
  126.             }
  127.  
  128.         void
  129.         operator()( void * obj )
  130.             {
  131.             BOOST_ASSERT(obj!=0);
  132.             dummy_exception_type * dummy_exception_ptr=reinterpret_cast<dummy_exception_type *>(obj);
  133.             (dummy_exception_ptr->*(et_.destructor))();
  134.             free(obj);
  135.             }
  136.         };
  137.  
  138.     cpp_type_info const &
  139.     get_cpp_type_info( cpp_exception_type const & et )
  140.         {
  141.         cpp_type_info const * ti = et.type_info_table->info[0];
  142.         BOOST_ASSERT(ti!=0);
  143.         return *ti;
  144.         }
  145.  
  146.     void
  147.     copy_msvc_exception( void * dst, void * src, cpp_type_info const & ti )
  148.         {
  149.         if( !(ti.flags & class_is_simple_type) && ti.copy_constructor.normal_copy_constructor )
  150.             {
  151.             dummy_exception_type * dummy_exception_ptr = reinterpret_cast<dummy_exception_type *>(dst);
  152.             if( ti.flags & class_has_virtual_base )
  153.                 (dummy_exception_ptr->*(ti.copy_constructor.copy_constructor_with_virtual_base))(src,dst);
  154.             else
  155.                 (dummy_exception_ptr->*(ti.copy_constructor.normal_copy_constructor))(src);
  156.             }
  157.         else
  158.             memmove(dst,src,ti.size);
  159.         }
  160.  
  161.     mars_boost::shared_ptr<void>
  162.     clone_msvc_exception( void * src, cpp_exception_type const & et )
  163.         {
  164.         assert(src!=0);
  165.         cpp_type_info const & ti=get_cpp_type_info(et);
  166.         if( void * dst = malloc(ti.size) )
  167.             {
  168.             try
  169.                 {
  170.                 copy_msvc_exception(dst,src,ti);
  171.                 }
  172.             catch(
  173.             ... )
  174.                 {
  175.                 free(dst);
  176.                 throw;
  177.                 }
  178.             return mars_boost::shared_ptr<void>(dst,exception_object_deleter(et));
  179.             }
  180.         else
  181.             throw std::bad_alloc();
  182.         }
  183.  
  184.     class
  185.     cloned_exception:
  186.         public mars_boost::exception_detail::clone_base
  187.         {
  188.         cloned_exception( cloned_exception const & );
  189.         cloned_exception & operator=( cloned_exception const & );
  190.  
  191.         cpp_exception_type const & et_;
  192.         mars_boost::shared_ptr<void> exc_;
  193.  
  194.         public:
  195.  
  196.         cloned_exception( void * exc, cpp_exception_type const & et ):
  197.             et_(et),
  198.             exc_(clone_msvc_exception(exc,et_))
  199.             {
  200.             }
  201.  
  202.         ~cloned_exception() throw()
  203.             {
  204.             }
  205.  
  206.         mars_boost::exception_detail::clone_base const *
  207.         clone() const
  208.             {
  209.             return new cloned_exception(exc_.get(),et_);
  210.             }
  211.  
  212.         void
  213.         rethrow() const
  214.             {
  215.             cpp_type_info const & ti=get_cpp_type_info(et_);
  216.             void * dst = _alloca(ti.size);
  217.             copy_msvc_exception(dst,exc_.get(),ti);
  218.             ULONG_PTR args[cpp_exception_parameter_count];
  219.             args[0]=cpp_exception_magic_flag;
  220.             args[1]=reinterpret_cast<ULONG_PTR>(dst);
  221.             args[2]=reinterpret_cast<ULONG_PTR>(&et_);
  222.             RaiseException(cpp_exception_code,EXCEPTION_NONCONTINUABLE,cpp_exception_parameter_count,args);
  223.             }
  224.         };
  225.  
  226.     bool
  227.     is_cpp_exception( EXCEPTION_RECORD const * record )
  228.         {
  229.         return record &&
  230.             (record->ExceptionCode==cpp_exception_code) &&
  231.             (record->NumberParameters==cpp_exception_parameter_count) &&
  232.             (record->ExceptionInformation[0]==cpp_exception_magic_flag);
  233.         }
  234.  
  235.     unsigned long
  236.     exception_cloning_filter( int & result, mars_boost::exception_detail::clone_base const * & ptr, void * info_ )
  237.         {
  238.         BOOST_ASSERT(exception_info_offset>=0);
  239.         BOOST_ASSERT(info_!=0);
  240.         EXCEPTION_POINTERS * info=reinterpret_cast<EXCEPTION_POINTERS *>(info_);
  241.         EXCEPTION_RECORD * record=info->ExceptionRecord;
  242.         if( is_cpp_exception(record) )
  243.             {
  244.             if( !record->ExceptionInformation[2] )
  245.                 record = *reinterpret_cast<EXCEPTION_RECORD * *>(reinterpret_cast<char *>(_errno())+exception_info_offset);
  246.             if( is_cpp_exception(record) && record->ExceptionInformation[2] )
  247.                 try
  248.                     {
  249.                     ptr = new cloned_exception(
  250.                             reinterpret_cast<void *>(record->ExceptionInformation[1]),
  251.                             *reinterpret_cast<cpp_exception_type const *>(record->ExceptionInformation[2]));
  252.                     result = mars_boost::exception_detail::clone_current_exception_result::success;
  253.                     }
  254.                 catch(
  255.                 std::bad_alloc & )
  256.                     {
  257.                     result = mars_boost::exception_detail::clone_current_exception_result::bad_alloc;
  258.                     }
  259.                 catch(
  260.                 ... )
  261.                     {
  262.                     result = mars_boost::exception_detail::clone_current_exception_result::bad_exception;
  263.                     }
  264.             }
  265.         return EXCEPTION_EXECUTE_HANDLER;
  266.         }
  267.     }
  268.  
  269. namespace mars_boost {} namespace boost = mars_boost; namespace
  270. mars_boost
  271.     {
  272.     namespace
  273.     exception_detail
  274.         {
  275.         int
  276.         clone_current_exception_non_intrusive( clone_base const * & cloned )
  277.             {
  278.             BOOST_ASSERT(!cloned);
  279.             int result = clone_current_exception_result::not_supported;
  280.             if( exception_info_offset>=0 )
  281.                 {
  282.                  clone_base const * ptr=0;
  283.                 __try
  284.                     {
  285.                     throw;
  286.                     }
  287.                 __except(exception_cloning_filter(result,ptr,GetExceptionInformation()))
  288.                     {
  289.                     }
  290.                 if( result==clone_current_exception_result::success )
  291.                     cloned=ptr;
  292.                 }
  293.             BOOST_ASSERT(result!=clone_current_exception_result::success || cloned);
  294.             return result;
  295.             }
  296.         }
  297.     }
  298.  
  299. #else
  300.  
  301. //On all other compilers, return clone_current_exception_result::not_supported.
  302. //On such platforms, only the intrusive enable_current_exception() cloning will work.
  303.  
  304. #include <boost/config.hpp>
  305.  
  306. namespace mars_boost {} namespace boost = mars_boost; namespace
  307. mars_boost
  308.     {
  309.     namespace
  310.     exception_detail
  311.         {
  312.         int
  313.         clone_current_exception_non_intrusive( clone_base const * & )
  314.             {
  315.             return clone_current_exception_result::not_supported;
  316.             }
  317.         }
  318.     }
  319.  
  320. #endif
  321.  
downloadclone_current_exception_non_intrusive.cpp Source code - Download mars Source code
Related Source Codes/Software:
Hero - Elegant transition library for iOS & tvOS 2017-06-09
deep-photo-styletransfer - Code and data for paper "Deep Photo Style Transfer... 2017-06-09
mastodon - A GNU Social-compatible microblogging server ... 2017-06-09
plyr - A simple HTML5, YouTube and Vimeo player ... 2017-06-08
prepack - Prepack is a partial evaluator for JavaScript. Pre... 2017-06-08
Public-APIs - 2017-06-09
lottie-ios - An iOS library to natively render After Effects ve... 2017-06-09
Awesome-Hacking - A collection of various awesome lists for hackers,... 2017-06-09
algorithms - Minimal examples of data structures and algorithms... 2017-06-10
lectures - Oxford Deep NLP 2017 course 2017-06-10
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top