Usermode/libc++ - Exception handling in progress (build broken)
authorJohn Hodge <[email protected]>
Sun, 18 May 2014 15:51:17 +0000 (23:51 +0800)
committerJohn Hodge <[email protected]>
Sun, 18 May 2014 15:51:17 +0000 (23:51 +0800)
Usermode/Libraries/Makefile.cfg
Usermode/Libraries/libc++.so_src/Makefile
Usermode/Libraries/libc++.so_src/cxxabi.cc
Usermode/Libraries/libc++.so_src/exception_handling.cc [new file with mode: 0644]
Usermode/Libraries/libc++.so_src/exceptions.cc [new file with mode: 0644]
Usermode/Libraries/libc++.so_src/include_exp/allocator
Usermode/Libraries/libc++.so_src/include_exp/exception
Usermode/Libraries/libc++.so_src/include_exp/stdexcept
Usermode/Libraries/libc++.so_src/include_exp/string
Usermode/Libraries/libc++.so_src/string.cc [new file with mode: 0644]

index 5920059..16f423d 100644 (file)
@@ -33,6 +33,7 @@ else
  LDFLAGS  := -I/Acess/Libs/ld-acess.so -lld-acess `$(CC) -print-libgcc-file-name`
 endif
 LDFLAGS += -g -nostdlib -shared -eSoMain -x --no-undefined -L$(OUTPUTDIR)Libs/
+CXXFLAGS += -std=gnu++11
 
 -include $(_libsdir)../common_settings.mk
 
index 6cec94f..0e62c53 100644 (file)
@@ -10,6 +10,8 @@ ASFLAGS  +=
 LDFLAGS  += -Map map.txt -lc\r
 \r
 OBJ  = misc.o new.o guard.o cxxabi.o typeinfo.o\r
+OBJ += string.o\r
+OBJ += exceptions.o exception_handling.o\r
 DEPFILES := $(OBJ:%.o=%.d)\r
 BIN = libc++.so\r
 ifeq ($(ARCHDIR),native)\r
index adda291..84cedf2 100644 (file)
@@ -4,6 +4,10 @@
  *
  * cxxabi.cc
  * - C++ ABI Namespace
+ * 
+ * NOTE: GCC follows the Itaniumâ„¢ C++ ABI on all platforms
+ * http://mentorembedded.github.io/cxx-abi/abi.html
+ * http://libcxxabi.llvm.org/spec.html
  */
 #include <cxxabi.h>
 
diff --git a/Usermode/Libraries/libc++.so_src/exception_handling.cc b/Usermode/Libraries/libc++.so_src/exception_handling.cc
new file mode 100644 (file)
index 0000000..2303980
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ */
+#include <typeinfo>
+#include <cstdint>
+
+typedef void *(unexpected_handler)(void);
+typedef void *(terminate_handler)(void);
+
+struct _Unwind_Context;
+
+typedef enum {
+       _URC_NO_REASON = 0,
+       _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
+       _URC_FATAL_PHASE2_ERROR = 2,
+       _URC_FATAL_PHASE1_ERROR = 3,
+       _URC_NORMAL_STOP = 4,
+       _URC_END_OF_STACK = 5,
+       _URC_HANDLER_FOUND = 6,
+       _URC_INSTALL_CONTEXT = 7,
+       _URC_CONTINUE_UNWIND = 8
+} _Unwind_Reason_Code;
+
+typedef void   (*_Unwind_Exception_Cleanup_Fn)(_Unwind_Reason_Code reason, struct _Unwind_Exception *exc);
+
+struct _Unwind_Exception
+{
+       uint64_t        exception_class;
+       _Unwind_Exception_Cleanup_Fn    exception_cleanup;
+       uint64_t        private_1;
+       uint64_t        private_2;
+};
+
+struct __cxa_exception
+{
+       std::type_info* exceptionType;
+       void (*exceptionDestructor)(void *);
+       unexpected_handler      unexpectedHandler;
+       terminate_handler       terminateHandler;
+       __cxa_exception*        nextException;
+       
+       int     handlerCount;
+       
+       int     handlerSwitchValue;
+       const char*     actionRecord;
+       const char*     languageSpecificData;
+       void*   catchTemp;
+       void*   adjustedPtr;
+       
+       _Unwind_Exception       unwindHeader;
+};
+
+ int   uncaught_exception_count;
+__cxa_exception        *uncaught_exception_top;
+
+extern "C" void __cxa_call_unexpected(void *)
+{
+       // An unexpected exception was thrown from a function that lists its possible exceptions
+       for(;;);
+}
+
+extern "C" void *__cxa_begin_catch(void *exceptionObject)
+{
+       struct __cxa_exception  *except = static_cast<__cxa_exception*>( exceptionObject );
+       except --;
+       
+       except->handlerCount ++;
+       
+       except->nextException = uncaught_exception_top;
+       uncaught_exception_top = except;
+       
+       uncaught_exception_count --;
+       
+       return except;
+}
+
+extern "C" void __cxa_end_catch()
+{
+       struct __cxa_exception  *except = uncaught_exception_top;
+       except->handlerCount --;
+       uncaught_exception_top = except->nextException;
+       
+       if( except->handlerCount == 0 ) {
+               //__cxa_free_exception(except+1);
+       }
+}
+
diff --git a/Usermode/Libraries/libc++.so_src/exceptions.cc b/Usermode/Libraries/libc++.so_src/exceptions.cc
new file mode 100644 (file)
index 0000000..2b66dce
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Acess2 C++ Library
+ * - By John Hodge (thePowersGang)
+ *
+ * exceptions.cc
+ * - ::std::exception and friends
+ */
+#include <string>
+#include <exception>
+#include <stdexcept>
+
+// === CODE ===
+::std::exception::exception() throw():
+       m_what_str("-empty-")
+{
+}
+::std::exception::exception(const exception& other) throw():
+       m_what_str(other.m_what_str)
+{
+}
+::std::exception::exception(const string& str) throw():
+       m_what_str(str)
+{
+}
+::std::exception& ::std::exception::operator=(const exception& other) throw()
+{
+       m_what_str = other.m_what_str;
+       return *this;
+}
+::std::exception::~exception() throw()
+{
+}
+const char* ::std::exception::what() const throw()
+{
+       return m_what_str.c_str();
+}
+
+::std::logic_error::logic_error(const ::std::string& what_str):
+       exception(what_str)
+{
+}
+
+::std::out_of_range::out_of_range(const ::std::string& what_str):
+       logic_error(what_str)
+{
+}
index 0bb12ea..d9faae9 100644 (file)
@@ -31,7 +31,7 @@ public:
        
        allocator() throw() {
        }
-       allocator(const allocator& alloc) throw() {
+       allocator(const allocator& alloc __attribute__((unused))) throw() {
        }
        template <class U>
        allocator(const allocator<U>& alloc) throw() {
@@ -46,9 +46,11 @@ public:
                return &x;
        }
        pointer allocate(size_type n, const void* hint=0) {
-               ::operator new (n * sizeof(value_type));
+               hint = hint;
+               return static_cast<pointer>( ::operator new (n * sizeof(value_type)) );
        }
        void deallocate(pointer p, size_type n) {
+               n=n;
                ::operator delete(p);
        }
 };
index 6edf82b..0beb016 100644 (file)
 
 #define noexcept       throw()
 
+#include "string"
+
 namespace std {
 
 class exception
 {
+       string  m_what_str;
 public:
        exception() noexcept;
        exception(const exception& e) noexcept;
        exception& operator= (const exception& e) noexcept;
        virtual ~exception() noexcept;
        virtual const char* what() const noexcept;
+protected:
+       exception(const string& what_str) noexcept;
 };
 
 };     // namespace std
index f9e3e3e..aea1afd 100644 (file)
@@ -16,14 +16,14 @@ class logic_error:
        public exception
 {
 public:
-       explicit logic_error(const basic_string<char>& what_arg);
+       explicit logic_error(const string& what_arg);
 };
 
 class runtime_error:
        public exception
 {
 public:
-       explicit runtime_error(const basic_string<char>& what_arg);
+       explicit runtime_error(const string& what_arg);
 };
 
 class out_of_range:
@@ -33,7 +33,7 @@ public:
        explicit out_of_range(const string& what_arg);
 };
 
-}      // namespace std
+};     // namespace std
 
 #endif
 
index 7326217..a32c9e9 100644 (file)
@@ -61,18 +61,9 @@ struct char_traits<wchar_t>
        }
 };
 
-template < class charT, class traits=char_traits<charT>, class Alloc=allocator<charT> >
-class basic_string;
-
-typedef basic_string<char>     string;
+extern void _throw_out_of_range(const char *message);
 
-};     // namespace std
-
-#include <stdexcept>
-
-namespace std {
-
-template < class charT, class traits, class Alloc >
+template < class charT, class traits=char_traits<charT>, class Alloc=allocator<charT> >
 class basic_string
 {
 public:
@@ -83,16 +74,40 @@ public:
        typedef typename allocator_type::const_reference        const_reference;
        typedef size_t  size_type;
 
+private:
+       struct dynamic_info
+       {
+               allocator_type  m_allocator;
+                int    m_ref_count = 1;
+               size_type       m_capacity = 0;
+               size_type       m_size = 0;
+               typename allocator_type::pointer m_data = 0;
+               dynamic_info(const allocator_type& alloc):
+                       m_allocator(alloc)
+               {
+               }
+               dynamic_info(const dynamic_info& other):
+                       m_allocator(other.m_allocator),
+                       m_ref_count(1),
+                       m_capacity(other.m_capacity),
+                       m_size(other.m_size)
+               {
+                       m_data = m_allocator.allocate(m_capacity);
+                       for( size_type i = 0; i < m_size; i ++ )
+                               m_data[i] = other.m_data[i];
+               }
+       };
+
+public:
        basic_string(const allocator_type& alloc = allocator_type()):
                m_allocator(alloc),
-               m_capacity(0),
-               m_length(0),
-               m_data(0)
+               m_content(0)
        {
        }
-       basic_string(const basic_string& str):
-               basic_string(str, allocator_type())
+       basic_string(const basic_string& str) throw():
+               basic_string(allocator_type())
        {
+               *this = str;
        }
        basic_string(const basic_string& str, const allocator_type& alloc):
                basic_string(str, 0, str.length(), alloc)
@@ -107,8 +122,8 @@ public:
                                len = str.length() - pos;
                        reserve(len);
                        for( size_type i = 0; i < len; i ++ )
-                               m_data[i] = str.m_data[pos+i];
-                       m_length = len;
+                               m_content->m_data[i] = str.m_content->m_data[pos+i];
+                       m_content->m_size = len;
                }
        }
        basic_string(const charT *s, const allocator_type& alloc = allocator_type()):
@@ -122,8 +137,8 @@ public:
                {
                        reserve(n);
                        for( size_type i = 0; i < n; i ++ )
-                               m_data[i] = s[i];
-                       m_length = n;
+                               m_content->m_data[i] = s[i];
+                       m_content->m_size = n;
                }
        }
        basic_string(size_type n, charT c, const allocator_type& alloc = allocator_type()):
@@ -133,16 +148,29 @@ public:
                {
                        reserve(n);
                        for( size_type i = 0; i < n; i ++ )
-                               m_data[i] = c;
-                       m_length = n;
+                               m_content->m_data[i] = c;
+                       m_content->m_size = n;
                }
        }
+       ~basic_string()
+       {
+               release_content();
+       }
+       basic_string& operator=(const basic_string& str) throw() {
+               return assign(str);
+       }
+       basic_string& operator=(const charT* s) {
+               return assign(s);
+       }
+       basic_string& operator=(charT c) {
+               return assign(c);
+       }
        
        // iterators
        
        // capacity
        size_type size() const {
-               return m_size;
+               return m_content ? m_content->m_size : 0;
        }
        size_type length() const {
                return size();
@@ -152,29 +180,31 @@ public:
        }
        void resize(size_type size, charT c = 0) {
                reserve(size);
-               if( m_size < size ) {
-                       for( size_type ofs = m_size; ofs < size; ofs ++ )
-                               m_data[ofs] = c;
+               if( m_content->m_size < size ) {
+                       for( size_type ofs = m_content->m_size; ofs < size; ofs ++ )
+                               m_content->m_data[ofs] = c;
                }
-               m_size = size;
-               m_data[m_size] = 0;
+               m_content->m_size = size;
+               m_content->m_data[size] = 0;
        }
        size_type capacity() const {
-               return m_capacity;
+               return m_content ? m_content->m_capacity : 0;
        }
        void reserve(size_type size) {
+               own_content();
                size = (size+1 + 31) & ~31;
-               if( size > m_capacity ) {
+               if( size > m_content->m_capacity ) {
                        auto new_area = m_allocator.allocate(size);
-                       for( size_type i = 0; i < m_length; i ++ )
-                               new_area[i] = m_data[i];
-                       m_allocator.deallocate(m_data, m_capacity);
-                       m_data = new_area;
-                       m_capacity = size;
+                       for( size_type i = 0; i < m_content->m_size; i ++ )
+                               new_area[i] = m_content->m_data[i];
+                       m_allocator.deallocate(m_content->m_data, m_content->m_capacity);
+                       m_content->m_data = new_area;
+                       m_content->m_capacity = size;
                }
        }
        void clear() {
-               m_size = 0;
+               own_content();
+               m_content->m_size = 0;
        }
        bool empty() const {
                return length() == 0;
@@ -182,37 +212,100 @@ public:
        
        // Access
        reference operator[] (size_type pos) {
-               return m_data[pos];
+               own_content();
+               return m_content->m_data[pos];
        }
        const_reference operator[] (size_type pos) const {
-               return m_data[pos];
+               return (m_content ? m_content->m_data[pos] : *(const charT*)0);
        }
        reference at(size_type pos) {
-               if(pos >= m_size)       throw ::std::out_of_range("basic_string - at");
-               return m_data[pos];
+               own_content();
+               if(pos >= m_content->m_size)
+                       _throw_out_of_range("basic_string - at");
+               return m_content->m_data[pos];
        }
        const_reference at(size_type pos) const {
-               if(pos >= m_size)       throw ::std::out_of_range("basic_string - at");
-               return m_data[pos];
+               if(!m_content || pos >= m_content.m_size)
+                       _throw_out_of_range("basic_string - at");
+               return m_content->m_data[pos];
        }
        
        // Modifiers
-       basic_string& operator +=(const basic_string& str);
-       basic_string& operator +=(const charT* s);
-       basic_string& operator +=(charT c);
+       basic_string& operator +=(const basic_string& str) {
+               return append(str);
+       }
+       basic_string& operator +=(const charT* s) {
+               return append(s);
+       }
+       basic_string& operator +=(charT c) {
+               push_back(c);
+               return *this;
+       }
+       basic_string& append(const basic_string& str) {
+               return append(str, 0, npos);
+       }
+       basic_string& append(const basic_string& str, size_type subpos, size_type sublen);
+       basic_string& append(const charT* s) {
+               return append(s, traits::length(s));
+       }
+       basic_string& append(const charT* s, size_type n);
+       basic_string& append(size_type n, charT c);
+       void push_back(charT c);
+       basic_string& assign(const basic_string& str) throw() {
+               // Special case, triggers copy-on-write.
+               release_content();
+               m_content = str.m_content;
+               m_content->m_ref_count ++;
+               return *this;
+       }
+       basic_string& assign(const basic_string& str, size_type subpos, size_type sublen);
+       
+       // String operations
+       const char *c_str() const {
+               // TODO: this is const, but also might need to do processing
+               return (m_content ? m_content->m_data : "");
+       }
+       const char *data() const {
+               return (m_content ? m_content->m_data : NULL);
+       }
        
        static const size_type npos = -1;
 private:
        allocator_type  m_allocator;
-       size_type       m_capacity;
-       size_type       m_size;
-       size_type       m_length;
-       typename allocator_type::pointer m_data;
-};
+       dynamic_info    *m_content;
 
+       void own_content() {
+               if(!m_content)
+               {
+                       m_content = new dynamic_info(m_allocator);
+               }
+               else if( m_content->m_ref_count > 1 )
+               {
+                       dynamic_info *new_cont = new dynamic_info(*m_content);
+                       m_content->m_ref_count --;
+                       m_content = new_cont;
+               }
+               else
+               {
+                       // already owned
+               }
+       }
+       void release_content() {
+               if( m_content )
+               {
+                       m_content->m_ref_count --;
+                       if( m_content->m_ref_count == 0 ) {
+                               m_allocator.deallocate(m_content->m_data, m_content->m_capacity);
+                               delete m_content;
+                       }
+                       m_content = NULL;
+               }
+       }
 };
 
-#include <stdexcept>
+typedef basic_string<char>     string;
+
+};
 
 #endif
 
diff --git a/Usermode/Libraries/libc++.so_src/string.cc b/Usermode/Libraries/libc++.so_src/string.cc
new file mode 100644 (file)
index 0000000..94ca722
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Acess2 C++ Library
+ * - By John Hodge (thePowersGang)
+ *
+ * exceptions.cc
+ * - ::std::exception and friends
+ */
+#include <string>
+#include <stdexcept>
+
+void ::std::_throw_out_of_range(const char *message)
+{
+       throw ::std::out_of_range(message);
+}
+

UCC git Repository :: git.ucc.asn.au