~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to system/lib/libcxxabi/src/stdexcept.cpp

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//===------------------------ stdexcept.cpp -------------------------------===//
 
2
//
 
3
//                     The LLVM Compiler Infrastructure
 
4
//
 
5
// This file is dual licensed under the MIT and the University of Illinois Open
 
6
// Source Licenses. See LICENSE.TXT for details.
 
7
//
 
8
//===----------------------------------------------------------------------===//
 
9
 
 
10
#include "stdexcept"
 
11
#include "new"
 
12
#include <cstdlib>
 
13
#include <cstring>
 
14
#include <cstdint>
 
15
#include <cstddef>
 
16
 
 
17
#if __APPLE__
 
18
#include <dlfcn.h>
 
19
#include <mach-o/dyld.h>
 
20
#endif
 
21
 
 
22
// Note:  optimize for size
 
23
 
 
24
#pragma GCC visibility push(hidden)
 
25
 
 
26
namespace
 
27
{
 
28
 
 
29
class __libcpp_nmstr
 
30
{
 
31
private:
 
32
    const char* str_;
 
33
 
 
34
    typedef int count_t;
 
35
 
 
36
    struct _Rep_base
 
37
    {
 
38
        std::size_t len;
 
39
        std::size_t cap;
 
40
        count_t     count;
 
41
    };
 
42
 
 
43
    static const std::ptrdiff_t offset = static_cast<std::ptrdiff_t>(sizeof(_Rep_base));
 
44
 
 
45
    count_t& count() const _NOEXCEPT {return ((_Rep_base*)(str_ - offset))->count;}
 
46
 
 
47
#if __APPLE__
 
48
    static
 
49
    const void*
 
50
    compute_gcc_empty_string_storage() _LIBCPP_CANTTHROW
 
51
    {
 
52
        void* handle = dlopen("/usr/lib/libstdc++.6.dylib", RTLD_NOLOAD);
 
53
        if (handle == 0)
 
54
            return 0;
 
55
        return (const char*)dlsym(handle, "_ZNSs4_Rep20_S_empty_rep_storageE") + offset;
 
56
    }
 
57
    
 
58
    static
 
59
    const void*
 
60
    get_gcc_empty_string_storage() _LIBCPP_CANTTHROW
 
61
    {
 
62
        static const void* p = compute_gcc_empty_string_storage();
 
63
        return p;
 
64
    }
 
65
#endif
 
66
 
 
67
public:
 
68
    explicit __libcpp_nmstr(const char* msg);
 
69
    __libcpp_nmstr(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW;
 
70
    __libcpp_nmstr& operator=(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW;
 
71
    ~__libcpp_nmstr() _LIBCPP_CANTTHROW;
 
72
    const char* c_str() const _NOEXCEPT {return str_;}
 
73
};
 
74
 
 
75
__libcpp_nmstr::__libcpp_nmstr(const char* msg)
 
76
{
 
77
    std::size_t len = strlen(msg);
 
78
    str_ = static_cast<const char*>(::operator new(len + 1 + offset));
 
79
    _Rep_base* c = (_Rep_base*)str_;
 
80
    c->len = c->cap = len;
 
81
    str_ += offset;
 
82
    count() = 0;
 
83
    std::strcpy(const_cast<char*>(c_str()), msg);
 
84
}
 
85
 
 
86
inline
 
87
__libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s)
 
88
    : str_(s.str_)
 
89
{
 
90
#if __APPLE__
 
91
    if (str_ != get_gcc_empty_string_storage())
 
92
#endif
 
93
        __sync_add_and_fetch(&count(), 1);
 
94
}
 
95
 
 
96
__libcpp_nmstr&
 
97
__libcpp_nmstr::operator=(const __libcpp_nmstr& s)
 
98
{
 
99
    const char* p = str_;
 
100
    str_ = s.str_;
 
101
#if __APPLE__
 
102
    if (str_ != get_gcc_empty_string_storage())
 
103
#endif
 
104
        __sync_add_and_fetch(&count(), 1);
 
105
#if __APPLE__
 
106
    if (p != get_gcc_empty_string_storage())
 
107
#endif
 
108
        if (__sync_add_and_fetch((count_t*)(p-sizeof(count_t)), count_t(-1)) < 0)
 
109
        {
 
110
            ::operator delete(const_cast<char*>(p-offset));
 
111
        }
 
112
    return *this;
 
113
}
 
114
 
 
115
inline
 
116
__libcpp_nmstr::~__libcpp_nmstr()
 
117
{
 
118
#if __APPLE__
 
119
    if (str_ != get_gcc_empty_string_storage())
 
120
#endif
 
121
        if (__sync_add_and_fetch(&count(), count_t(-1)) < 0)
 
122
        {
 
123
            ::operator delete(const_cast<char*>(str_ - offset));
 
124
        }
 
125
}
 
126
 
 
127
}
 
128
 
 
129
#pragma GCC visibility pop
 
130
 
 
131
namespace std  // purposefully not using versioning namespace
 
132
{
 
133
 
 
134
logic_error::~logic_error() _NOEXCEPT
 
135
{
 
136
    __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
 
137
    s.~__libcpp_nmstr();
 
138
}
 
139
 
 
140
const char*
 
141
logic_error::what() const _NOEXCEPT
 
142
{
 
143
    __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
 
144
    return s.c_str();
 
145
}
 
146
 
 
147
runtime_error::~runtime_error() _NOEXCEPT
 
148
{
 
149
    __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
 
150
    s.~__libcpp_nmstr();
 
151
}
 
152
 
 
153
const char*
 
154
runtime_error::what() const _NOEXCEPT
 
155
{
 
156
    __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
 
157
    return s.c_str();
 
158
}
 
159
 
 
160
domain_error::~domain_error() _NOEXCEPT {}
 
161
invalid_argument::~invalid_argument() _NOEXCEPT {}
 
162
length_error::~length_error() _NOEXCEPT {}
 
163
out_of_range::~out_of_range() _NOEXCEPT {}
 
164
 
 
165
range_error::~range_error() _NOEXCEPT {}
 
166
overflow_error::~overflow_error() _NOEXCEPT {}
 
167
underflow_error::~underflow_error() _NOEXCEPT {}
 
168
 
 
169
}  // std