1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#import "base/mac/scoped_nsexception_enabler.h"
6
7#import "base/lazy_instance.h"
8#import "base/threading/thread_local.h"
9
10// To make the |g_exceptionsAllowed| declaration readable.
11using base::LazyInstance;
12using base::ThreadLocalBoolean;
13
14// When C++ exceptions are disabled, the C++ library defines |try| and
15// |catch| so as to allow exception-expecting C++ code to build properly when
16// language support for exceptions is not present.  These macros interfere
17// with the use of |@try| and |@catch| in Objective-C files such as this one.
18// Undefine these macros here, after everything has been #included, since
19// there will be no C++ uses and only Objective-C uses from this point on.
20#undef try
21#undef catch
22
23namespace {
24
25// Whether to allow NSExceptions to be raised on the current thread.
26LazyInstance<ThreadLocalBoolean>::Leaky
27    g_exceptionsAllowed = LAZY_INSTANCE_INITIALIZER;
28
29}  // namespace
30
31namespace base {
32namespace mac {
33
34bool GetNSExceptionsAllowed() {
35  return g_exceptionsAllowed.Get().Get();
36}
37
38void SetNSExceptionsAllowed(bool allowed) {
39  return g_exceptionsAllowed.Get().Set(allowed);
40}
41
42id RunBlockIgnoringExceptions(BlockReturningId block) {
43  id ret = nil;
44  @try {
45    base::mac::ScopedNSExceptionEnabler enable;
46    ret = block();
47  }
48  @catch(id exception) {
49  }
50  return ret;
51}
52
53ScopedNSExceptionEnabler::ScopedNSExceptionEnabler() {
54  was_enabled_ = GetNSExceptionsAllowed();
55  SetNSExceptionsAllowed(true);
56}
57
58ScopedNSExceptionEnabler::~ScopedNSExceptionEnabler() {
59  SetNSExceptionsAllowed(was_enabled_);
60}
61
62}  // namespace mac
63}  // namespace base
64