oj 2.0.14 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of oj might be problematic. Click here for more details.

@@ -0,0 +1,64 @@
1
+ /* err.h
2
+ * Copyright (c) 2011, Peter Ohler
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are met:
7
+ *
8
+ * - Redistributions of source code must retain the above copyright notice, this
9
+ * list of conditions and the following disclaimer.
10
+ *
11
+ * - Redistributions in binary form must reproduce the above copyright notice,
12
+ * this list of conditions and the following disclaimer in the documentation
13
+ * and/or other materials provided with the distribution.
14
+ *
15
+ * - Neither the name of Peter Ohler nor the names of its contributors may be
16
+ * used to endorse or promote products derived from this software without
17
+ * specific prior written permission.
18
+ *
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ */
30
+
31
+ #ifndef __OJ_ERR_H__
32
+ #define __OJ_ERR_H__
33
+
34
+ #include "ruby.h"
35
+
36
+ #define set_error(err, eclas, msg, json, current) _oj_err_set_with_location(err, eclas, msg, json, current, __FILE__, __LINE__)
37
+
38
+ typedef struct _Err {
39
+ VALUE clas;
40
+ char msg[128];
41
+ } *Err;
42
+
43
+ extern VALUE oj_parse_error_class;
44
+
45
+ extern void oj_err_set(Err e, VALUE clas, const char *format, ...);
46
+ extern void _oj_err_set_with_location(Err err, VALUE eclas, const char *msg, const char *json, const char *current, const char* file, int line);
47
+ extern void oj_err_raise(Err e);
48
+ // TBD remove
49
+ #define raise_error(msg, json, current) _oj_raise_error(msg, json, current, __FILE__, __LINE__)
50
+ extern void _oj_raise_error(const char *msg, const char *json, const char *current, const char* file, int line);
51
+
52
+
53
+ inline static void
54
+ err_init(Err e) {
55
+ e->clas = Qnil;
56
+ *e->msg = '\0';
57
+ }
58
+
59
+ inline static int
60
+ err_has(Err e) {
61
+ return (Qnil != e->clas);
62
+ }
63
+
64
+ #endif /* __OJ_ERR_H__ */
@@ -28,6 +28,7 @@ dflags = {
28
28
  'HAS_IVAR_HELPERS' => ('ruby' == type && !is_windows && (('1' == version[0] && '9' == version[1]) || '2' <= version[0])) ? 1 : 0,
29
29
  'HAS_EXCEPTION_MAGIC' => ('ruby' == type && !is_windows && ('1' == version[0] && '9' == version[1])) ? 0 : 1,
30
30
  'HAS_PROC_WITH_BLOCK' => ('ruby' == type && (('1' == version[0] && '9' == version[1]) || '2' <= version[0])) ? 1 : 0,
31
+ 'HAS_GC_GUARD' => ('jruby' != type && 'rubinius' != type) ? 1 : 0,
31
32
  'HAS_TOP_LEVEL_ST_H' => ('ree' == type || ('ruby' == type && '1' == version[0] && '8' == version[1])) ? 1 : 0,
32
33
  'IS_WINDOWS' => is_windows ? 1 : 0,
33
34
  'SAFE_CACHE' => is_windows ? 0 : 1,
@@ -0,0 +1,149 @@
1
+ /* hash.c
2
+ * Copyright (c) 2011, Peter Ohler
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are met:
7
+ *
8
+ * - Redistributions of source code must retain the above copyright notice, this
9
+ * list of conditions and the following disclaimer.
10
+ *
11
+ * - Redistributions in binary form must reproduce the above copyright notice,
12
+ * this list of conditions and the following disclaimer in the documentation
13
+ * and/or other materials provided with the distribution.
14
+ *
15
+ * - Neither the name of Peter Ohler nor the names of its contributors may be
16
+ * used to endorse or promote products derived from this software without
17
+ * specific prior written permission.
18
+ *
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ */
30
+
31
+ #include "hash.h"
32
+
33
+ #define HASH_MASK 0x000003FF
34
+ #define HASH_SLOT_CNT 1024
35
+
36
+ typedef struct _KeyVal {
37
+ struct _KeyVal *next;
38
+ const char *key;
39
+ size_t len;
40
+ VALUE val;
41
+ } *KeyVal;
42
+
43
+ struct _Hash {
44
+ struct _KeyVal slots[HASH_SLOT_CNT];
45
+ };
46
+
47
+ struct _Hash class_hash;
48
+ struct _Hash intern_hash;
49
+
50
+ // almost the Murmur hash algorithm
51
+ #define M 0x5bd1e995
52
+ #define C1 0xCC9E2D51
53
+ #define C2 0x1B873593
54
+ #define N 0xE6546B64
55
+
56
+ static uint32_t
57
+ hash_calc(const uint8_t *key, size_t len) {
58
+ uint32_t k;
59
+ uint32_t *kp = (uint32_t*)key;
60
+ uint32_t *end = kp + (len / 4);
61
+ uint32_t h = (uint32_t)len;
62
+
63
+ for (; kp < end; kp++) {
64
+ k = M * *kp;
65
+ k ^= k >> 24;
66
+ h *= M;
67
+ h ^= k * M;
68
+ }
69
+ len = len - (len / 4 * 4);
70
+ if (1 < len) {
71
+ h ^= *(uint16_t*)kp << 8;
72
+ len -= 2;
73
+ key = (uint8_t*)(((uint16_t*)kp) + 1);
74
+ } else {
75
+ key = (uint8_t*)kp;
76
+ }
77
+ if (0 < len) {
78
+ h ^= key[0];
79
+ }
80
+ h *= M;
81
+ h ^= h >> 13;
82
+ h *= M;
83
+ h ^= h >> 15;
84
+
85
+ return h;
86
+ }
87
+
88
+ void
89
+ oj_hash_init() {
90
+ memset(class_hash.slots, 0, sizeof(class_hash.slots));
91
+ memset(intern_hash.slots, 0, sizeof(intern_hash.slots));
92
+ }
93
+
94
+ // if slotp is 0 then just lookup
95
+ static VALUE
96
+ hash_get(Hash hash, const char *key, size_t len, VALUE **slotp, VALUE def_value) {
97
+ uint32_t h = hash_calc((const uint8_t*)key, len) & HASH_MASK;
98
+ KeyVal bucket = hash->slots + h;
99
+
100
+ if (0 != bucket->key) {
101
+ KeyVal b;
102
+
103
+ for (b = bucket; 0 != b; b = b->next) {
104
+ if (len == b->len && 0 == strncmp(b->key, key, len)) {
105
+ *slotp = &b->val;
106
+ return b->val;
107
+ }
108
+ bucket = b;
109
+ }
110
+ }
111
+ if (0 != slotp) {
112
+ if (0 != bucket->key) {
113
+ KeyVal b = ALLOC(struct _KeyVal);
114
+
115
+ b->next = 0;
116
+ bucket->next = b;
117
+
118
+ }
119
+ bucket->key = strndup(key, len);
120
+ bucket->len = len;
121
+ bucket->val = def_value;
122
+ *slotp = &bucket->val;
123
+ }
124
+ return def_value;
125
+ }
126
+
127
+ void
128
+ oj_hash_print() {
129
+ int i;
130
+ KeyVal b;
131
+
132
+ for (i = 0; i < HASH_SLOT_CNT; i++) {
133
+ printf("%4d:", i);
134
+ for (b = class_hash.slots + i; 0 != b && 0 != b->key; b = b->next) {
135
+ printf(" %s", b->key);
136
+ }
137
+ printf("\n");
138
+ }
139
+ }
140
+
141
+ VALUE
142
+ oj_class_hash_get(const char *key, size_t len, VALUE **slotp) {
143
+ return hash_get(&class_hash, key, len, slotp, Qnil);
144
+ }
145
+
146
+ ID
147
+ oj_attr_hash_get(const char *key, size_t len, ID **slotp) {
148
+ return (ID)hash_get(&intern_hash, key, len, (VALUE**)slotp, 0);
149
+ }
@@ -1,4 +1,4 @@
1
- /* cache.h
1
+ /* hash.h
2
2
  * Copyright (c) 2011, Peter Ohler
3
3
  * All rights reserved.
4
4
  *
@@ -28,19 +28,18 @@
28
28
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
29
  */
30
30
 
31
- #ifndef __OJ_CACHE_H__
32
- #define __OJ_CACHE_H__
33
-
34
- #define RSTRING_NOT_MODIFIED
31
+ #ifndef __OJ_HASH_H__
32
+ #define __OJ_HASH_H__
35
33
 
36
34
  #include "ruby.h"
37
35
 
38
- typedef struct _Cache *Cache;
36
+ typedef struct _Hash *Hash;
39
37
 
40
- extern void oj_cache_new(Cache *cache);
38
+ extern void oj_hash_init();
41
39
 
42
- extern VALUE oj_cache_get(Cache cache, const char *key, VALUE **slot);
40
+ extern VALUE oj_class_hash_get(const char *key, size_t len, VALUE **slotp);
41
+ extern ID oj_attr_hash_get(const char *key, size_t len, ID **slotp);
43
42
 
44
- extern void oj_cache_print(Cache cache);
43
+ extern void oj_hash_print();
45
44
 
46
- #endif /* __OJ_CACHE_H__ */
45
+ #endif /* __OJ_HASH_H__ */
@@ -0,0 +1,501 @@
1
+ /* hash_test.c
2
+ * Copyright (c) 2011, Peter Ohler
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are met:
7
+ *
8
+ * - Redistributions of source code must retain the above copyright notice, this
9
+ * list of conditions and the following disclaimer.
10
+ *
11
+ * - Redistributions in binary form must reproduce the above copyright notice,
12
+ * this list of conditions and the following disclaimer in the documentation
13
+ * and/or other materials provided with the distribution.
14
+ *
15
+ * - Neither the name of Peter Ohler nor the names of its contributors may be
16
+ * used to endorse or promote products derived from this software without
17
+ * specific prior written permission.
18
+ *
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ */
30
+
31
+ #include <sys/time.h>
32
+ #include <time.h>
33
+ #include "hash.h"
34
+
35
+ typedef struct _StrLen {
36
+ const char *str;
37
+ size_t len;
38
+ } *StrLen;
39
+
40
+ static struct _StrLen data[] = {
41
+ { "Gem::Version", 12 },
42
+ { "TracePoint", 10 },
43
+ { "Complex::compatible", 19 },
44
+ { "Complex", 7 },
45
+ { "Rational::compatible", 20 },
46
+ { "Rational", 8 },
47
+ { "FiberError", 10 },
48
+ { "Fiber", 5 },
49
+ { "ThreadError", 11 },
50
+ { "Mutex", 5 },
51
+ { "ThreadGroup", 11 },
52
+ { "RubyVM::InstructionSequence", 27 },
53
+ { "Thread::Backtrace::Location", 27 },
54
+ { "Thread::Backtrace", 17 },
55
+ { "Thread", 6 },
56
+ { "RubyVM::Env", 11 },
57
+ { "RubyVM", 6 },
58
+ { "Enumerator::Yielder", 19 },
59
+ { "Enumerator::Generator", 21 },
60
+ { "StopIteration", 13 },
61
+ { "Enumerator::Lazy", 16 },
62
+ { "Enumerator", 10 },
63
+ { "ObjectSpace::WeakMap", 20 },
64
+ { "Math::DomainError", 17 },
65
+ { "Binding", 7 },
66
+ { "UnboundMethod", 13 },
67
+ { "Method", 6 },
68
+ { "SystemStackError", 16 },
69
+ { "LocalJumpError", 14 },
70
+ { "Proc", 4 },
71
+ { "Struct::Tms", 11 },
72
+ { "Process::Status", 15 },
73
+ { "Random", 6 },
74
+ { "Time", 4 },
75
+ { "Dir", 3 },
76
+ { "File::Stat", 10 },
77
+ { "File", 4 },
78
+ { "ARGF.class", 10 },
79
+ { "IO", 2 },
80
+ { "EOFError", 8 },
81
+ { "IOError", 7 },
82
+ { "Range", 5 },
83
+ { "Encoding::Converter", 19 },
84
+ { "Encoding::ConverterNotFoundError", 32 },
85
+ { "Encoding::InvalidByteSequenceError", 34 },
86
+ { "Encoding::UndefinedConversionError", 34 },
87
+ { "MatchData", 9 },
88
+ { "Regexp", 6 },
89
+ { "RegexpError", 11 },
90
+ { "Struct", 6 },
91
+ { "Hash", 4 },
92
+ { "Array", 5 },
93
+ { "Errno::ERPCMISMATCH", 19 },
94
+ { "Errno::EPROGUNAVAIL", 19 },
95
+ { "Errno::EPROGMISMATCH", 20 },
96
+ { "Errno::EPROCUNAVAIL", 19 },
97
+ { "Errno::EPROCLIM", 15 },
98
+ { "Errno::ENOTSUP", 14 },
99
+ { "Errno::ENOATTR", 14 },
100
+ { "Errno::ENEEDAUTH", 16 },
101
+ { "Errno::EFTYPE", 13 },
102
+ { "Errno::EBADRPC", 14 },
103
+ { "Errno::EAUTH", 12 },
104
+ { "Errno::EOWNERDEAD", 17 },
105
+ { "Errno::ENOTRECOVERABLE", 22 },
106
+ { "Errno::ECANCELED", 16 },
107
+ { "Errno::EDQUOT", 13 },
108
+ { "Errno::ESTALE", 13 },
109
+ { "Errno::EINPROGRESS", 18 },
110
+ { "Errno::EALREADY", 15 },
111
+ { "Errno::EHOSTUNREACH", 19 },
112
+ { "Errno::EHOSTDOWN", 16 },
113
+ { "Errno::ECONNREFUSED", 19 },
114
+ { "Errno::ETIMEDOUT", 16 },
115
+ { "Errno::ETOOMANYREFS", 19 },
116
+ { "Errno::ESHUTDOWN", 16 },
117
+ { "Errno::ENOTCONN", 15 },
118
+ { "Errno::EISCONN", 14 },
119
+ { "Errno::ENOBUFS", 14 },
120
+ { "Errno::ECONNRESET", 17 },
121
+ { "Errno::ECONNABORTED", 19 },
122
+ { "Errno::ENETRESET", 16 },
123
+ { "Errno::ENETUNREACH", 18 },
124
+ { "Errno::ENETDOWN", 15 },
125
+ { "Errno::EADDRNOTAVAIL", 20 },
126
+ { "Errno::EADDRINUSE", 17 },
127
+ { "Errno::EAFNOSUPPORT", 19 },
128
+ { "Errno::EPFNOSUPPORT", 19 },
129
+ { "Errno::EOPNOTSUPP", 17 },
130
+ { "Errno::ESOCKTNOSUPPORT", 22 },
131
+ { "Errno::EPROTONOSUPPORT", 22 },
132
+ { "Errno::ENOPROTOOPT", 18 },
133
+ { "Errno::EPROTOTYPE", 17 },
134
+ { "Errno::EMSGSIZE", 15 },
135
+ { "Errno::EDESTADDRREQ", 19 },
136
+ { "Errno::ENOTSOCK", 15 },
137
+ { "Errno::EUSERS", 13 },
138
+ { "Errno::EILSEQ", 13 },
139
+ { "Errno::EOVERFLOW", 16 },
140
+ { "Errno::EBADMSG", 14 },
141
+ { "Errno::EMULTIHOP", 16 },
142
+ { "Errno::EPROTO", 13 },
143
+ { "Errno::ENOLINK", 14 },
144
+ { "Errno::EREMOTE", 14 },
145
+ { "Errno::ENOSR", 12 },
146
+ { "Errno::ETIME", 12 },
147
+ { "Errno::ENODATA", 14 },
148
+ { "Errno::ENOSTR", 13 },
149
+ { "Errno::EIDRM", 12 },
150
+ { "Errno::ENOMSG", 13 },
151
+ { "Errno::ELOOP", 12 },
152
+ { "Errno::ENOTEMPTY", 16 },
153
+ { "Errno::ENOSYS", 13 },
154
+ { "Errno::ENOLCK", 13 },
155
+ { "Errno::ENAMETOOLONG", 19 },
156
+ { "Errno::EDEADLK", 14 },
157
+ { "Errno::ERANGE", 13 },
158
+ { "Errno::EDOM", 11 },
159
+ { "Errno::EPIPE", 12 },
160
+ { "Errno::EMLINK", 13 },
161
+ { "Errno::EROFS", 12 },
162
+ { "Errno::ESPIPE", 13 },
163
+ { "Errno::ENOSPC", 13 },
164
+ { "Errno::EFBIG", 12 },
165
+ { "Errno::ETXTBSY", 14 },
166
+ { "Errno::ENOTTY", 13 },
167
+ { "Errno::EMFILE", 13 },
168
+ { "Errno::ENFILE", 13 },
169
+ { "Errno::EINVAL", 13 },
170
+ { "Errno::EISDIR", 13 },
171
+ { "Errno::ENOTDIR", 14 },
172
+ { "Errno::ENODEV", 13 },
173
+ { "Errno::EXDEV", 12 },
174
+ { "Errno::EEXIST", 13 },
175
+ { "Errno::EBUSY", 12 },
176
+ { "Errno::ENOTBLK", 14 },
177
+ { "Errno::EFAULT", 13 },
178
+ { "Errno::EACCES", 13 },
179
+ { "Errno::ENOMEM", 13 },
180
+ { "Errno::EAGAIN", 13 },
181
+ { "Errno::ECHILD", 13 },
182
+ { "Errno::EBADF", 12 },
183
+ { "Errno::ENOEXEC", 14 },
184
+ { "Errno::E2BIG", 12 },
185
+ { "Errno::ENXIO", 12 },
186
+ { "Errno::EIO", 10 },
187
+ { "Errno::EINTR", 12 },
188
+ { "Errno::ESRCH", 12 },
189
+ { "Errno::ENOENT", 13 },
190
+ { "Errno::EPERM", 12 },
191
+ { "Errno::NOERROR", 14 },
192
+ { "Bignum", 6 },
193
+ { "Float", 5 },
194
+ { "Fixnum", 6 },
195
+ { "Integer", 7 },
196
+ { "Numeric", 7 },
197
+ { "FloatDomainError", 16 },
198
+ { "ZeroDivisionError", 17 },
199
+ { "SystemCallError", 15 },
200
+ { "Encoding::CompatibilityError", 28 },
201
+ { "EncodingError", 13 },
202
+ { "NoMemoryError", 13 },
203
+ { "SecurityError", 13 },
204
+ { "RuntimeError", 12 },
205
+ { "NoMethodError", 13 },
206
+ { "NameError::message", 18 },
207
+ { "NameError", 9 },
208
+ { "NotImplementedError", 19 },
209
+ { "LoadError", 9 },
210
+ { "SyntaxError", 11 },
211
+ { "ScriptError", 11 },
212
+ { "RangeError", 10 },
213
+ { "KeyError", 8 },
214
+ { "IndexError", 10 },
215
+ { "ArgumentError", 13 },
216
+ { "TypeError", 9 },
217
+ { "StandardError", 13 },
218
+ { "Interrupt", 9 },
219
+ { "SignalException", 15 },
220
+ { "#<Class:0x007fb0510c8790>", 25 },
221
+ { "SystemExit", 10 },
222
+ { "Exception", 9 },
223
+ { "Symbol", 6 },
224
+ { "String", 6 },
225
+ { "Encoding", 8 },
226
+ { "FalseClass", 10 },
227
+ { "TrueClass", 9 },
228
+ { "Data", 4 },
229
+ { "NilClass", 8 },
230
+ { "Class", 5 },
231
+ { "Module", 6 },
232
+ { "Object", 6 },
233
+ { "BasicObject", 11 },
234
+ { "Gem::Requirement::BadRequirementError", 37 },
235
+ { "Gem::Requirement", 16 },
236
+ { "Gem::SourceFetchProblem", 23 },
237
+ { "Gem::PlatformMismatch", 21 },
238
+ { "Gem::ErrorReason", 16 },
239
+ { "Gem::LoadError", 14 },
240
+ { "Gem::RemoteSourceException", 26 },
241
+ { "Gem::RemoteInstallationSkipped", 30 },
242
+ { "Gem::RemoteInstallationCancelled", 32 },
243
+ { "Gem::RemoteError", 16 },
244
+ { "Gem::OperationNotSupportedError", 31 },
245
+ { "Gem::InvalidSpecificationException", 34 },
246
+ { "Gem::InstallError", 17 },
247
+ { "Gem::Specification", 18 },
248
+ { "Date", 4 },
249
+ { "Gem::Platform", 13 },
250
+ { "Gem::SpecificGemNotFoundException", 33 },
251
+ { "Gem::GemNotFoundException", 25 },
252
+ { "Gem::FormatException", 20 },
253
+ { "Gem::FilePermissionError", 24 },
254
+ { "Gem::EndOfYAMLException", 23 },
255
+ { "Gem::DocumentError", 18 },
256
+ { "Gem::GemNotInHomeException", 26 },
257
+ { "Gem::DependencyRemovalException", 31 },
258
+ { "Gem::DependencyError", 20 },
259
+ { "Gem::CommandLineError", 21 },
260
+ { "Gem::Exception", 14 },
261
+ { "IRB::SLex", 9 },
262
+ { "IRB::Notifier::NoMsgNotifier", 28 },
263
+ { "IRB::Notifier::LeveledNotifier", 30 },
264
+ { "IRB::Notifier::CompositeNotifier", 32 },
265
+ { "IRB::Notifier::AbstractNotifier", 31 },
266
+ { "IRB::Notifier::ErrUnrecognizedLevel", 35 },
267
+ { "IRB::Notifier::ErrUndefinedNotifier", 35 },
268
+ { "IRB::StdioOutputMethod", 22 },
269
+ { "IRB::OutputMethod::NotImplementedError", 38 },
270
+ { "IRB::OutputMethod", 17 },
271
+ { "IRB::IllegalRCGenerator", 23 },
272
+ { "IRB::UndefinedPromptMode", 24 },
273
+ { "IRB::CantChangeBinding", 22 },
274
+ { "IRB::CantShiftToMultiIrbMode", 28 },
275
+ { "IRB::NoSuchJob", 14 },
276
+ { "IRB::IrbSwitchedToCurrentThread", 31 },
277
+ { "IRB::IrbAlreadyDead", 19 },
278
+ { "IRB::IllegalParameter", 21 },
279
+ { "IRB::CantReturnToNormalMode", 27 },
280
+ { "IRB::NotImplementedError", 24 },
281
+ { "IRB::UnrecognizedSwitch", 23 },
282
+ { "IRB::Irb", 8 },
283
+ { "IRB::Abort", 10 },
284
+ { "IRB::Locale", 11 },
285
+ { "IRB::SLex::ErrNodeNothing", 25 },
286
+ { "IRB::SLex::ErrNodeAlreadyExists", 31 },
287
+ { "RubyLex", 7 },
288
+ { "IRB::SLex::Node", 15 },
289
+ { "Gem::SystemExitException", 24 },
290
+ { "Gem::VerificationError", 22 },
291
+ { "RubyToken::TkError", 18 },
292
+ { "RubyToken::TkUnknownChar", 24 },
293
+ { "RubyToken::TkOPASGN", 19 },
294
+ { "RubyToken::TkOp", 15 },
295
+ { "RubyToken::TkVal", 16 },
296
+ { "RubyToken::TkId", 15 },
297
+ { "RubyToken::TkNode", 17 },
298
+ { "RubyToken::Token", 16 },
299
+ { "RubyToken::TkUNDEF", 18 },
300
+ { "RubyToken::TkDEF", 16 },
301
+ { "RubyToken::TkMODULE", 19 },
302
+ { "RubyToken::TkCLASS", 18 },
303
+ { "RubyToken::TkWHILE", 18 },
304
+ { "RubyToken::TkWHEN", 17 },
305
+ { "RubyToken::TkCASE", 17 },
306
+ { "RubyToken::TkELSE", 17 },
307
+ { "RubyToken::TkELSIF", 18 },
308
+ { "RubyToken::TkTHEN", 17 },
309
+ { "RubyToken::TkUNLESS", 19 },
310
+ { "RubyToken::TkIF", 15 },
311
+ { "RubyToken::TkEND", 16 },
312
+ { "RubyToken::TkENSURE", 19 },
313
+ { "RubyToken::TkRESCUE", 19 },
314
+ { "RubyToken::TkBEGIN", 18 },
315
+ { "RubyToken::TkDO", 15 },
316
+ { "RubyToken::TkIN", 15 },
317
+ { "RubyToken::TkRETRY", 18 },
318
+ { "RubyToken::TkREDO", 17 },
319
+ { "RubyToken::TkNEXT", 17 },
320
+ { "RubyToken::TkBREAK", 18 },
321
+ { "RubyToken::TkFOR", 16 },
322
+ { "RubyToken::TkUNTIL", 18 },
323
+ { "RubyToken::TkTRUE", 17 },
324
+ { "RubyToken::TkNIL", 16 },
325
+ { "RubyToken::TkSELF", 17 },
326
+ { "RubyToken::TkSUPER", 18 },
327
+ { "RubyToken::TkYIELD", 18 },
328
+ { "RubyToken::TkRETURN", 19 },
329
+ { "RubyToken::TkAND", 16 },
330
+ { "RubyToken::TkFALSE", 18 },
331
+ { "RubyToken::TkUNLESS_MOD", 23 },
332
+ { "RubyToken::TkIF_MOD", 19 },
333
+ { "RubyToken::TkNOT", 16 },
334
+ { "RubyToken::TkOR", 15 },
335
+ { "RubyToken::TkALIAS", 18 },
336
+ { "RubyToken::TkUNTIL_MOD", 22 },
337
+ { "RubyToken::TkWHILE_MOD", 22 },
338
+ { "RubyToken::TkGVAR", 17 },
339
+ { "RubyToken::TkFID", 16 },
340
+ { "RubyToken::TkIDENTIFIER", 23 },
341
+ { "RubyToken::Tk__FILE__", 21 },
342
+ { "RubyToken::Tk__LINE__", 21 },
343
+ { "RubyToken::TklEND", 17 },
344
+ { "RubyToken::TklBEGIN", 19 },
345
+ { "RubyToken::TkDEFINED", 20 },
346
+ { "RubyToken::TkDREGEXP", 20 },
347
+ { "RubyToken::TkDXSTRING", 21 },
348
+ { "RubyToken::TkDSTRING", 20 },
349
+ { "RubyToken::TkSYMBOL", 19 },
350
+ { "RubyToken::TkREGEXP", 19 },
351
+ { "RubyToken::TkXSTRING", 20 },
352
+ { "RubyToken::TkSTRING", 19 },
353
+ { "RubyToken::TkFLOAT", 18 },
354
+ { "RubyToken::TkINTEGER", 20 },
355
+ { "RubyToken::TkCONSTANT", 21 },
356
+ { "RubyToken::TkIVAR", 17 },
357
+ { "RubyToken::TkCVAR", 17 },
358
+ { "RubyToken::TkNEQ", 16 },
359
+ { "RubyToken::TkEQQ", 16 },
360
+ { "RubyToken::TkEQ", 15 },
361
+ { "RubyToken::TkCMP", 16 },
362
+ { "RubyToken::TkPOW", 16 },
363
+ { "RubyToken::TkUMINUS", 19 },
364
+ { "RubyToken::TkUPLUS", 18 },
365
+ { "Exception2MessageMapper::ErrNotRegisteredException", 50 },
366
+ { "RubyToken::TkBACK_REF", 21 },
367
+ { "RubyToken::TkNTH_REF", 20 },
368
+ { "RubyToken::TkLSHFT", 18 },
369
+ { "RubyToken::TkASET", 17 },
370
+ { "RubyToken::TkAREF", 17 },
371
+ { "RubyToken::TkDOT3", 17 },
372
+ { "RubyToken::TkDOT2", 17 },
373
+ { "RubyToken::TkNMATCH", 19 },
374
+ { "RubyToken::TkMATCH", 18 },
375
+ { "RubyToken::TkOROP", 17 },
376
+ { "RubyToken::TkANDOP", 18 },
377
+ { "RubyToken::TkLEQ", 16 },
378
+ { "RubyToken::TkGEQ", 16 },
379
+ { "RubyToken::TkAMPER", 18 },
380
+ { "RubyToken::TkSTAR", 17 },
381
+ { "RubyToken::TkfLBRACE", 20 },
382
+ { "RubyToken::TkfLBRACK", 20 },
383
+ { "RubyToken::TkfLPAREN", 20 },
384
+ { "RubyToken::TkCOLON", 18 },
385
+ { "RubyToken::TkQUESTION", 21 },
386
+ { "RubyToken::TkASSOC", 18 },
387
+ { "RubyToken::TkCOLON3", 19 },
388
+ { "RubyToken::TkCOLON2", 19 },
389
+ { "RubyToken::TkRSHFT", 18 },
390
+ { "RubyToken::TkBITAND", 19 },
391
+ { "RubyToken::TkBITXOR", 19 },
392
+ { "RubyToken::TkBITOR", 18 },
393
+ { "RubyToken::TkMOD", 16 },
394
+ { "RubyToken::TkDIV", 16 },
395
+ { "RubyToken::TkMULT", 17 },
396
+ { "RubyToken::TkMINUS", 18 },
397
+ { "RubyToken::TkPLUS", 17 },
398
+ { "RubyToken::TkLT", 15 },
399
+ { "RubyToken::TkGT", 15 },
400
+ { "RubyToken::TkSYMBEG", 19 },
401
+ { "IRB::DefaultEncodings", 21 },
402
+ { "RubyToken::TkRPAREN", 19 },
403
+ { "RubyToken::TkLBRACE", 19 },
404
+ { "RubyToken::TkLBRACK", 19 },
405
+ { "RubyToken::TkLPAREN", 19 },
406
+ { "RubyToken::TkDOT", 16 },
407
+ { "RubyToken::TkASSIGN", 19 },
408
+ { "RubyToken::TkBACKQUOTE", 22 },
409
+ { "RubyToken::TkNOTOP", 18 },
410
+ { "RubyToken::TkBITNOT", 19 },
411
+ { "RubyToken::TkDOLLAR", 19 },
412
+ { "RubyToken::TkAT", 15 },
413
+ { "RubyToken::TkBACKSLASH", 22 },
414
+ { "RubyToken::TkEND_OF_SCRIPT", 26 },
415
+ { "RubyToken::TkNL", 15 },
416
+ { "RubyToken::TkSPACE", 18 },
417
+ { "RubyToken::TkRD_COMMENT", 23 },
418
+ { "RubyToken::TkCOMMENT", 20 },
419
+ { "RubyToken::TkSEMICOLON", 22 },
420
+ { "RubyToken::TkCOMMA", 18 },
421
+ { "RubyToken::TkRBRACE", 19 },
422
+ { "RubyToken::TkRBRACK", 19 },
423
+ { "RubyLex::TerminateLineInput", 27 },
424
+ { "RubyLex::SyntaxError", 20 },
425
+ { "RubyLex::TkReading2TokenDuplicateError", 38 },
426
+ { "RubyLex::TkSymbol2TokenNoKey", 28 },
427
+ { "RubyLex::TkReading2TokenNoKey", 29 },
428
+ { "RubyLex::AlreadyDefinedToken", 28 },
429
+ { "IRB::FileInputMethod", 20 },
430
+ { "IRB::StdioInputMethod", 21 },
431
+ { "IRB::InputMethod", 16 },
432
+ { "IRB::ReadlineInputMethod", 24 },
433
+ { "IRB::Context", 12 },
434
+ { "IRB::Inspector", 14 },
435
+ { "IRB::WorkSpace", 14 },
436
+ { 0, 0 }
437
+ };
438
+
439
+ static uint64_t
440
+ micro_time() {
441
+ struct timeval tv;
442
+ struct timezone tz;
443
+
444
+ gettimeofday(&tv, &tz);
445
+
446
+ return (uint64_t)tv.tv_sec * 1000000ULL + (uint64_t)tv.tv_usec;
447
+ }
448
+
449
+ static void
450
+ perf() {
451
+ StrLen d;
452
+ VALUE v;
453
+ VALUE *slot = 0;
454
+ uint64_t dt, start;
455
+ int i, iter = 1000000;
456
+
457
+ oj_hash_init();
458
+ start = micro_time();
459
+ for (i = iter; 0 < i; i--) {
460
+ for (d = data; 0 != d->str; d++) {
461
+ v = oj_class_hash_get(d->str, d->len, &slot);
462
+ if (Qundef == v) {
463
+ if (0 != slot) {
464
+ v = ID2SYM(rb_intern(d->str));
465
+ *slot = v;
466
+ }
467
+ }
468
+ }
469
+ }
470
+ dt = micro_time() - start;
471
+ printf("%d iterations took %lld msecs\n", iter, dt / 1000);
472
+ }
473
+
474
+ void
475
+ oj_hash_test() {
476
+ StrLen d;
477
+ VALUE v;
478
+ VALUE *slot = 0;;
479
+
480
+ oj_hash_init();
481
+ for (d = data; 0 != d->str; d++) {
482
+ /*printf("*** hash_get on %s\n", *d);*/
483
+ v = oj_class_hash_get(d->str, d->len, &slot);
484
+ if (Qundef == v) {
485
+ if (0 == slot) {
486
+ /*printf("*** failed to get a slot for %s\n", *d); */
487
+ } else {
488
+ /*printf("*** added '%s' to hash\n", *d); */
489
+ v = ID2SYM(rb_intern(d->str));
490
+ *slot = v;
491
+ }
492
+ } else {
493
+ VALUE rs = rb_funcall2(v, rb_intern("to_s"), 0, 0);
494
+
495
+ printf("*** get on '%s' returned '%s' (%s)\n", d->str, StringValuePtr(rs), rb_class2name(rb_obj_class(v)));
496
+ }
497
+ /*oj_hash_print(c);*/
498
+ }
499
+ oj_hash_print();
500
+ perf();
501
+ }