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