Browse Source

Replace CL_REQUIRE/CL_PROVIDE(cl_symbol) with portable code.

The order of initialization of non-local objects in different compilation units
is not specified in C++. Hence special care should be taken to avoid static
initialization order fiasco. CLN solved the problem with some evil (GCC
specific, and even GCC-version-specific) hack. Replace it with a technique
similar to one used in STL to initialize std::cout and friends.
master
Alexei Sheplyakov 16 years ago
parent
commit
67afbefaff
  1. 2
      include/cln/symbol.h
  2. 46
      src/base/symbol/cl_symbol.cc

2
include/cln/symbol.h

@ -47,8 +47,6 @@ inline bool equal (const cl_symbol& s1, const cl_symbol& s2)
// Hash code.
extern unsigned long hashcode (const cl_symbol& s);
CL_REQUIRE(cl_symbol)
} // namespace cln
#endif /* _CL_SYMBOL_H */

46
src/base/symbol/cl_symbol.cc

@ -3,8 +3,6 @@
// General includes.
#include "cl_sysdep.h"
CL_PROVIDE(cl_symbol)
// Specification.
#include "cln/symbol.h"
@ -40,10 +38,6 @@ static void cl_hashtable_from_string_to_symbol_destructor (cl_heap* pointer)
#endif
}
cl_class cl_class_hashtable_from_string_to_symbol = {
cl_hashtable_from_string_to_symbol_destructor,
0
};
struct cl_ht_from_string_to_symbol : public cl_gcpointer {
// Constructors.
@ -64,6 +58,10 @@ struct cl_ht_from_string_to_symbol : public cl_gcpointer {
cl_ht_from_string_to_symbol::cl_ht_from_string_to_symbol ()
{
static const cl_class cl_class_hashtable_from_string_to_symbol = {
cl_hashtable_from_string_to_symbol_destructor,
0
};
var cl_heap_hashtable_from_string_to_symbol* ht = new cl_heap_hashtable_from_string_to_symbol ();
ht->refcount = 1;
ht->type = &cl_class_hashtable_from_string_to_symbol;
@ -81,11 +79,44 @@ void cl_ht_from_string_to_symbol::put (const cl_string& s) const
}
// The global symbol table.
static cl_ht_from_string_to_symbol symbol_table;
class global_symbol_table
{
static int count;
static cl_ht_from_string_to_symbol* symbol_table;
public:
inline cl_symbol* get(const cl_string& s)
{
return symbol_table->get(s);
}
inline void put(const cl_string& s)
{
symbol_table->put(s);
}
global_symbol_table();
~global_symbol_table();
};
int global_symbol_table::count = 0;
cl_ht_from_string_to_symbol* global_symbol_table::symbol_table;
global_symbol_table::global_symbol_table()
{
if (count++ == 0)
symbol_table = new cl_ht_from_string_to_symbol();
}
global_symbol_table::~global_symbol_table()
{
if (--count == 0)
delete symbol_table;
}
// Create or lookup a symbol from its name.
cl_symbol::cl_symbol (const cl_string& s)
{
static global_symbol_table symbol_table;
var cl_symbol * sym_in_table;
sym_in_table = symbol_table.get(s);
if (!sym_in_table) {
@ -101,4 +132,3 @@ cl_symbol::cl_symbol (const cl_string& s)
} // namespace cln
CL_PROVIDE_END(cl_symbol)
Loading…
Cancel
Save