|  | // Copyright 2015 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "base/mac/call_with_eh_frame.h" | 
|  |  | 
|  | #include <unwind.h> | 
|  |  | 
|  | #include "build/build_config.h" | 
|  | #include "starboard/types.h" | 
|  |  | 
|  | namespace base { | 
|  | namespace mac { | 
|  |  | 
|  | #if defined(OS_IOS) | 
|  | // No iOS assembly implementation exists, so just call the block directly. | 
|  | void CallWithEHFrame(void (^block)(void)) { | 
|  | block(); | 
|  | } | 
|  | #else  // OS_MACOSX | 
|  | extern "C" _Unwind_Reason_Code __gxx_personality_v0(int, | 
|  | _Unwind_Action, | 
|  | uint64_t, | 
|  | struct _Unwind_Exception*, | 
|  | struct _Unwind_Context*); | 
|  |  | 
|  | _Unwind_Reason_Code CxxPersonalityRoutine( | 
|  | int version, | 
|  | _Unwind_Action actions, | 
|  | uint64_t exception_class, | 
|  | struct _Unwind_Exception* exception_object, | 
|  | struct _Unwind_Context* context) { | 
|  | // Unwinding is a two-phase process: phase one searches for an exception | 
|  | // handler, and phase two performs cleanup. For phase one, this custom | 
|  | // personality will terminate the search. For phase two, this should delegate | 
|  | // back to the standard personality routine. | 
|  |  | 
|  | if ((actions & _UA_SEARCH_PHASE) != 0) { | 
|  | // Tell libunwind that this is the end of the stack. When it encounters the | 
|  | // CallWithEHFrame, it will stop searching for an exception handler. The | 
|  | // result is that no exception handler has been found higher on the stack, | 
|  | // and any that are lower on the stack (e.g. in CFRunLoopRunSpecific), will | 
|  | // now be skipped. Since this is reporting the end of the stack, and no | 
|  | // exception handler will have been found, std::terminate() will be called. | 
|  | return _URC_END_OF_STACK; | 
|  | } | 
|  |  | 
|  | return __gxx_personality_v0(version, actions, exception_class, | 
|  | exception_object, context); | 
|  | } | 
|  | #endif  // defined(OS_IOS) | 
|  |  | 
|  | }  // namespace mac | 
|  | }  // namespace base |