I've started dipping my toes in the libcxxabi project by implementing a few
simple methods. Patch attached, please review!

This isn't heavily tested, I'm mostly just trying to make sure I have the
style down. Please let me know if we should be using different file names
(hard to follow a pattern where there isn't one), of if the private methods
in cxa_guard actually belong in an anonymous namespace, etc.

Nick
Index: test/test_guard.cpp
===================================================================
--- test/test_guard.cpp	(revision 0)
+++ test/test_guard.cpp	(revision 0)
@@ -0,0 +1,59 @@
+//===----------------------------- test_guard.cpp -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "cxxabi.h"
+
+#include <cassert>
+
+namespace test1 {
+    static int run_count = 0;
+    int increment() {
+        ++run_count;
+        return 0;
+    }
+    void helper() {
+        static int a = increment();
+    }
+    void test() {
+        static int a = increment();
+        assert(run_count == 1);
+        static int b = increment();
+        assert(run_count == 2);
+        helper();
+        assert(run_count == 3);
+        helper();
+        assert(run_count == 3);
+    }
+}
+
+namespace test2 {
+    static int run_count = 0;
+    int increment() {
+        ++run_count;
+        throw 0;
+    }
+    void helper() {
+        try {
+            static int a = increment();
+            assert(0);
+        } catch (...) {}
+    }
+    void test() {
+        helper();
+        assert(run_count == 1);
+        helper();
+        assert(run_count == 2);
+    }
+}
+
+int main()
+{
+    test1::test();
+    test2::test();
+}
Index: include/cxxabi.h
===================================================================
--- include/cxxabi.h	(revision 131719)
+++ include/cxxabi.h	(working copy)
@@ -55,6 +55,9 @@
 // 3.2.6 Pure Virtual Function API
 extern void __cxa_pure_virtual(void);
 
+// 3.2.7 Deleted Virtual Function API
+extern void __cxa_deleted_virtual(void);
+
 // 3.3.2 One-time Construction API
 extern int  __cxa_guard_acquire(uint64_t*);
 extern void __cxa_guard_release(uint64_t*);
Index: src/cxa_virtual.cpp
===================================================================
--- src/cxa_virtual.cpp	(revision 0)
+++ src/cxa_virtual.cpp	(revision 0)
@@ -0,0 +1,33 @@
+//===-------------------------- cxa_virtual.cpp ---------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "cxxabi.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+namespace __cxxabiv1
+{
+
+extern "C"
+{
+
+void __cxa_pure_virtual(void) {
+    fputs("Pure virtual function called!\n", stderr);
+    abort();
+}
+
+void __cxa_deleted_virtual(void) {
+    fputs("Deleted virtual function called!\n", stderr);
+    abort();
+}
+
+}  // extern "C"
+
+}  // abi
Index: src/cxa_guard.cpp
===================================================================
--- src/cxa_guard.cpp	(revision 0)
+++ src/cxa_guard.cpp	(revision 0)
@@ -0,0 +1,68 @@
+//===---------------------------- cxa_guard.cpp ---------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "cxxabi.h"
+
+#include <stdio.h>
+
+namespace __cxxabiv1
+{
+
+namespace __libcxxabi
+{
+
+#pragma GCC visibility push(hidden)
+
+uint8_t compare_and_swap(volatile uint8_t* ptr,
+                         uint8_t new_value, uint8_t old_value) {
+    return __sync_val_compare_and_swap(ptr, old_value, new_value);
+}
+
+void memory_fence() {
+    __sync_synchronize();
+}
+
+#pragma GCC visibility pop
+#pragma GCC visibility push(default)
+
+}
+
+extern "C"
+{
+
+int __cxa_guard_acquire(uint64_t* guard_object) {
+    uint8_t* initialized = (uint8_t*)guard_object;
+    uint8_t* lock = (uint8_t*)guard_object + 1;
+
+    // Spin until we acquire the lock.
+    while (__libcxxabi::compare_and_swap(lock, 1, 0))
+        __libcxxabi::memory_fence();
+
+    return *initialized == 0;
+}
+
+void __cxa_guard_release(uint64_t* guard_object) {
+    uint8_t* initialized = (uint8_t*)guard_object;
+    uint8_t* lock = (uint8_t*)guard_object + 1;
+    *initialized = 1;
+    *lock = 0;
+    __libcxxabi::memory_fence();
+}
+
+void __cxa_guard_abort(uint64_t* guard_object) {
+    uint8_t* initialized = (uint8_t*)guard_object;
+    uint8_t* lock = (uint8_t*)guard_object + 1;
+    *initialized = 0;
+    *lock = 0;
+    __libcxxabi::memory_fence();
+}
+
+}  // extern "C"
+
+}  // abi
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to