Added spec:commit task to commit changes to spec/ruby sources.
[rbx.git] / shotgun / lib / symbol.c
blob249d26ede134f4d7a770fa6323e0ce6efdb33715
1 #include "shotgun/lib/shotgun.h"
2 #include "shotgun/lib/tuple.h"
3 #include "shotgun/lib/hash.h"
4 #include "shotgun/lib/string.h"
5 #include "shotgun/lib/symbol.h"
7 #define StartSize 256
8 #define Increments 32
12 * The case that prompted code the symbol table to check the key value.
13 * str: __uint_fast64_t
14 * hash: 112644932
16 * str: TkIF_MOD
17 * hash: 112644932
18 */
20 OBJECT symtbl_new(STATE) {
21 OBJECT tbl;
22 tbl = symtbl_allocate(state);
23 symtbl_set_symbols(tbl, tuple_new(state, StartSize));
24 symtbl_set_strings(tbl, hash_new_sized(state, StartSize));
25 return tbl;
28 OBJECT symtbl_lookup_cstr(STATE, OBJECT self, const char *str) {
29 return symtbl_lookup_str_with_size(state, self, str, strlen(str));
32 OBJECT symtbl_lookup_str_with_size(STATE, OBJECT self,
33 const char *str, int size) {
34 unsigned int hash;
35 OBJECT strs, idx, syms, ent;
37 hash = string_hash_str_with_size(state, str, size);
38 strs = symtbl_get_strings(self);
39 syms = symtbl_get_symbols(self);
41 ent = hash_find_entry(state, strs, hash);
43 /* If it wasn't present, use the longer, more correct version. */
44 if(NIL_P(ent) || ent == Qundef) {
45 return symtbl_lookup(state, self, string_new2(state, str, size));
46 } else {
47 OBJECT key = tuple_at(state, ent, 1);
48 char *cur = rbx_string_as_cstr(state, key);
50 /* Check that this is actually the right string. */
51 if(size != N2I(string_get_bytes(key)) || strncmp(cur, str, size)) {
52 return symtbl_lookup(state, self, string_new2(state, str, size));
55 idx = tuple_at(state, ent, 2);
58 return symbol_from_index(state, N2I(idx));
61 OBJECT symtbl_lookup(STATE, OBJECT self, OBJECT string) {
62 unsigned int hash, sz;
63 OBJECT idx, strs, syms, ns, obj;
65 hash = string_hash_int(state, string);
66 strs = symtbl_get_strings(self);
67 syms = symtbl_get_symbols(self);
70 idx = Qnil;
72 if(!hash_lookup2(state, string_equal_p, strs, string, hash, &idx)) {
73 idx = hash_get_entries(strs);
74 sz = tuple_fields(state, syms);
75 if(N2I(idx) == sz) {
76 ns = tuple_new(state, sz + Increments);
77 object_copy_fields_from(state, syms, ns, 0, sz);
78 symtbl_set_symbols(self, ns);
79 syms = ns;
82 tuple_put(state, syms, N2I(idx), string);
83 hash_assign(state, string_equal_p, strs, string, hash, idx);
86 obj = symbol_from_index(state, N2I(idx));
87 return obj;
90 OBJECT symbol_to_string(STATE, OBJECT self) {
91 return symtbl_find_string(state, state->global->symbols, self);
94 OBJECT symtbl_find_string(STATE, OBJECT self, OBJECT sym) {
95 size_t idx;
96 OBJECT str;
98 idx = symbol_to_index(state, sym);
99 str = tuple_at(state, symtbl_get_symbols(self), idx);
100 return str;