Merge branch 'handle-stdout'
[SXSI/xpathcomp.git] / src / common_stub.cpp
1 #include <unordered_map>
2 #include <string>
3
4 #include "common_stub.hpp"
5
6 extern "C" {
7 #include <sys/time.h>
8 #include <sys/resource.h>
9 #include <malloc.h>
10
11 }
12
13 using std::string;
14 using std::pair;
15 using std::unordered_map;
16 using std::make_pair;
17
18 typedef unordered_map<string, pair<struct custom_operations*, size_t>> type_map_t;
19 static type_map_t * type_map = 0;
20 static value * cpp_exception = 0;
21
22 static void init_error()
23 {
24   caml_failwith("C++: initialization error");
25 }
26
27 static void init_exception()
28 {
29   cpp_exception = caml_named_value("CPlusPlusError");
30   if (cpp_exception == 0)
31     init_error();
32 }
33
34 static void init_type_map()
35 {
36   if (type_map == 0)
37     type_map = new type_map_t();
38   if (type_map == 0)
39     init_error();
40 }
41
42 void register_custom_(char* name,
43                       size_t size,
44                       void (*finalize)(value v))
45 {
46   if (type_map == 0) init_error();
47   struct custom_operations * ops =
48     (struct custom_operations*) calloc(1, sizeof(struct custom_operations));
49   ops->identifier = name;
50   ops->finalize = finalize;
51   ops->compare = custom_compare_default;
52   ops->hash = custom_hash_default;
53   ops->serialize = custom_serialize_default;
54   ops->deserialize = custom_deserialize_default;
55   type_map->insert(make_pair(string(name), make_pair(ops, size)));
56 }
57
58 value alloc_custom_(char* name)
59 {
60   CAMLparam0();
61   CAMLlocal1(result);
62   if (type_map == 0) init_error();
63   string key = string(name);
64   type_map_t::iterator it = type_map->find(key);
65   if (it == type_map->end())
66     result = Val_unit;
67   else
68     result = caml_alloc_custom(it->second.first, it->second.second, 1, 1);
69
70   CAMLreturn(result);
71 }
72
73
74 ML_BINDING value sxsi_cpp_init(value unit)
75 {
76   struct rlimit rlim;
77   init_exception();
78   init_type_map();
79
80   /* Set the stack space to unlimited */
81   getrlimit(RLIMIT_STACK, &rlim);
82   if (rlim.rlim_max == RLIM_INFINITY && rlim.rlim_cur != RLIM_INFINITY) {
83     rlim.rlim_cur = RLIM_INFINITY;
84     setrlimit(RLIMIT_STACK, &rlim);
85   };
86   //  mallopt(M_MMAP_THRESHOLD, 0);
87
88   return Val_unit;
89 }
90
91 void sxsi_raise_msg(const char * msg)
92 {
93   if (cpp_exception == 0) init_error();
94   caml_raise_with_string(*cpp_exception, msg);
95 }