Line | Count | Source (jump to first uncovered line) |
1 | | /* This is a wrapper for parse.y */ |
2 | | |
3 | | #include "internal/ruby_parser.h" |
4 | | |
5 | | #include "node.h" |
6 | | #include "rubyparser.h" |
7 | | #include "internal/error.h" |
8 | | |
9 | | #ifdef UNIVERSAL_PARSER |
10 | | |
11 | | #include "internal.h" |
12 | | #include "internal/array.h" |
13 | | #include "internal/bignum.h" |
14 | | #include "internal/compile.h" |
15 | | #include "internal/complex.h" |
16 | | #include "internal/encoding.h" |
17 | | #include "internal/gc.h" |
18 | | #include "internal/hash.h" |
19 | | #include "internal/io.h" |
20 | | #include "internal/parse.h" |
21 | | #include "internal/rational.h" |
22 | | #include "internal/re.h" |
23 | | #include "internal/string.h" |
24 | | #include "internal/symbol.h" |
25 | | #include "internal/thread.h" |
26 | | |
27 | | #include "ruby/ractor.h" |
28 | | #include "ruby/ruby.h" |
29 | | #include "ruby/util.h" |
30 | | #include "internal.h" |
31 | | #include "vm_core.h" |
32 | | #include "symbol.h" |
33 | | |
34 | | struct ruby_parser { |
35 | | rb_parser_t *parser_params; |
36 | | }; |
37 | | |
38 | | static void |
39 | | parser_mark(void *ptr) |
40 | | { |
41 | | struct ruby_parser *parser = (struct ruby_parser*)ptr; |
42 | | rb_ruby_parser_mark(parser->parser_params); |
43 | | } |
44 | | |
45 | | static void |
46 | | parser_free(void *ptr) |
47 | | { |
48 | | struct ruby_parser *parser = (struct ruby_parser*)ptr; |
49 | | rb_ruby_parser_free(parser->parser_params); |
50 | | } |
51 | | |
52 | | static size_t |
53 | | parser_memsize(const void *ptr) |
54 | | { |
55 | | struct ruby_parser *parser = (struct ruby_parser*)ptr; |
56 | | return rb_ruby_parser_memsize(parser->parser_params); |
57 | | } |
58 | | |
59 | | static const rb_data_type_t ruby_parser_data_type = { |
60 | | "parser", |
61 | | { |
62 | | parser_mark, |
63 | | parser_free, |
64 | | parser_memsize, |
65 | | }, |
66 | | 0, 0, RUBY_TYPED_FREE_IMMEDIATELY |
67 | | }; |
68 | | |
69 | | static int |
70 | | is_ascii_string2(VALUE str) |
71 | | { |
72 | | return is_ascii_string(str); |
73 | | } |
74 | | |
75 | | RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 6, 0) |
76 | | static VALUE |
77 | | syntax_error_append(VALUE exc, VALUE file, int line, int column, |
78 | | void *enc, const char *fmt, va_list args) |
79 | | { |
80 | | return rb_syntax_error_append(exc, file, line, column, (rb_encoding *)enc, fmt, args); |
81 | | } |
82 | | |
83 | | static int |
84 | | local_defined(ID id, const void *p) |
85 | | { |
86 | | return rb_local_defined(id, (const rb_iseq_t *)p); |
87 | | } |
88 | | |
89 | | static int |
90 | | dvar_defined(ID id, const void *p) |
91 | | { |
92 | | return rb_dvar_defined(id, (const rb_iseq_t *)p); |
93 | | } |
94 | | |
95 | | static bool |
96 | | hash_literal_key_p(VALUE k) |
97 | | { |
98 | | switch (OBJ_BUILTIN_TYPE(k)) { |
99 | | case T_NODE: |
100 | | return false; |
101 | | default: |
102 | | return true; |
103 | | } |
104 | | } |
105 | | |
106 | | static int |
107 | | literal_cmp(VALUE val, VALUE lit) |
108 | | { |
109 | | if (val == lit) return 0; |
110 | | if (!hash_literal_key_p(val) || !hash_literal_key_p(lit)) return -1; |
111 | | return rb_iseq_cdhash_cmp(val, lit); |
112 | | } |
113 | | |
114 | | static st_index_t |
115 | | literal_hash(VALUE a) |
116 | | { |
117 | | if (!hash_literal_key_p(a)) return (st_index_t)a; |
118 | | return rb_iseq_cdhash_hash(a); |
119 | | } |
120 | | |
121 | | static int |
122 | | is_usascii_enc(void *enc) |
123 | | { |
124 | | return rb_is_usascii_enc((rb_encoding *)enc); |
125 | | } |
126 | | |
127 | | static int |
128 | | is_local_id2(ID id) |
129 | | { |
130 | | return is_local_id(id); |
131 | | } |
132 | | |
133 | | static int |
134 | | is_attrset_id2(ID id) |
135 | | { |
136 | | return is_attrset_id(id); |
137 | | } |
138 | | |
139 | | static int |
140 | | is_notop_id2(ID id) |
141 | | { |
142 | | return is_notop_id(id); |
143 | | } |
144 | | |
145 | | static VALUE |
146 | | enc_str_new(const char *ptr, long len, void *enc) |
147 | | { |
148 | | return rb_enc_str_new(ptr, len, (rb_encoding *)enc); |
149 | | } |
150 | | |
151 | | static int |
152 | | enc_isalnum(OnigCodePoint c, void *enc) |
153 | | { |
154 | | return rb_enc_isalnum(c, (rb_encoding *)enc); |
155 | | } |
156 | | |
157 | | static int |
158 | | enc_precise_mbclen(const char *p, const char *e, void *enc) |
159 | | { |
160 | | return rb_enc_precise_mbclen(p, e, (rb_encoding *)enc); |
161 | | } |
162 | | |
163 | | static int |
164 | | mbclen_charfound_p(int len) |
165 | | { |
166 | | return MBCLEN_CHARFOUND_P(len); |
167 | | } |
168 | | |
169 | | static int |
170 | | mbclen_charfound_len(int len) |
171 | | { |
172 | | return MBCLEN_CHARFOUND_LEN(len); |
173 | | } |
174 | | |
175 | | static const char * |
176 | | enc_name(void *enc) |
177 | | { |
178 | | return rb_enc_name((rb_encoding *)enc); |
179 | | } |
180 | | |
181 | | static char * |
182 | | enc_prev_char(const char *s, const char *p, const char *e, void *enc) |
183 | | { |
184 | | return rb_enc_prev_char(s, p, e, (rb_encoding *)enc); |
185 | | } |
186 | | |
187 | | static void * |
188 | | enc_get(VALUE obj) |
189 | | { |
190 | | return (void *)rb_enc_get(obj); |
191 | | } |
192 | | |
193 | | static int |
194 | | enc_asciicompat(void *enc) |
195 | | { |
196 | | return rb_enc_asciicompat((rb_encoding *)enc); |
197 | | } |
198 | | |
199 | | static void * |
200 | | utf8_encoding(void) |
201 | | { |
202 | | return (void *)rb_utf8_encoding(); |
203 | | } |
204 | | |
205 | | static VALUE |
206 | | enc_associate(VALUE obj, void *enc) |
207 | | { |
208 | | return rb_enc_associate(obj, (rb_encoding *)enc); |
209 | | } |
210 | | |
211 | | static void * |
212 | | ascii8bit_encoding(void) |
213 | | { |
214 | | return (void *)rb_ascii8bit_encoding(); |
215 | | } |
216 | | |
217 | | static int |
218 | | enc_codelen(int c, void *enc) |
219 | | { |
220 | | return rb_enc_codelen(c, (rb_encoding *)enc); |
221 | | } |
222 | | |
223 | | static VALUE |
224 | | enc_str_buf_cat(VALUE str, const char *ptr, long len, void *enc) |
225 | | { |
226 | | return rb_enc_str_buf_cat(str, ptr, len, (rb_encoding *)enc); |
227 | | } |
228 | | |
229 | | static int |
230 | | enc_mbcput(unsigned int c, void *buf, void *enc) |
231 | | { |
232 | | return rb_enc_mbcput(c, buf, (rb_encoding *)enc); |
233 | | } |
234 | | |
235 | | static void * |
236 | | enc_from_index(int idx) |
237 | | { |
238 | | return (void *)rb_enc_from_index(idx); |
239 | | } |
240 | | |
241 | | static int |
242 | | enc_isspace(OnigCodePoint c, void *enc) |
243 | | { |
244 | | return rb_enc_isspace(c, (rb_encoding *)enc); |
245 | | } |
246 | | |
247 | | static ID |
248 | | intern3(const char *name, long len, void *enc) |
249 | | { |
250 | | return rb_intern3(name, len, (rb_encoding *)enc); |
251 | | } |
252 | | |
253 | | static void * |
254 | | enc_compatible(VALUE str1, VALUE str2) |
255 | | { |
256 | | return (void *)rb_enc_compatible(str1, str2); |
257 | | } |
258 | | |
259 | | static VALUE |
260 | | enc_from_encoding(void *enc) |
261 | | { |
262 | | return rb_enc_from_encoding((rb_encoding *)enc); |
263 | | } |
264 | | |
265 | | static int |
266 | | encoding_get(VALUE obj) |
267 | | { |
268 | | return ENCODING_GET(obj); |
269 | | } |
270 | | |
271 | | static void |
272 | | encoding_set(VALUE obj, int encindex) |
273 | | { |
274 | | ENCODING_SET(obj, encindex); |
275 | | } |
276 | | |
277 | | static int |
278 | | encoding_is_ascii8bit(VALUE obj) |
279 | | { |
280 | | return ENCODING_IS_ASCII8BIT(obj); |
281 | | } |
282 | | |
283 | | static void * |
284 | | usascii_encoding(void) |
285 | | { |
286 | | return (void *)rb_usascii_encoding(); |
287 | | } |
288 | | |
289 | | static int |
290 | | enc_symname_type(const char *name, long len, void *enc, unsigned int allowed_attrset) |
291 | | { |
292 | | return rb_enc_symname_type(name, len, (rb_encoding *)enc, allowed_attrset); |
293 | | } |
294 | | |
295 | | typedef struct { |
296 | | struct parser_params *parser; |
297 | | rb_encoding *enc; |
298 | | NODE *succ_block; |
299 | | const rb_code_location_t *loc; |
300 | | } reg_named_capture_assign_t; |
301 | | |
302 | | static int |
303 | | reg_named_capture_assign_iter(const OnigUChar *name, const OnigUChar *name_end, |
304 | | int back_num, int *back_refs, OnigRegex regex, void *arg0) |
305 | | { |
306 | | reg_named_capture_assign_t *arg = (reg_named_capture_assign_t*)arg0; |
307 | | struct parser_params* p = arg->parser; |
308 | | rb_encoding *enc = arg->enc; |
309 | | const rb_code_location_t *loc = arg->loc; |
310 | | long len = name_end - name; |
311 | | const char *s = (const char *)name; |
312 | | |
313 | | return rb_reg_named_capture_assign_iter_impl(p, s, len, (void *)enc, &arg->succ_block, loc); |
314 | | } |
315 | | |
316 | | static NODE * |
317 | | reg_named_capture_assign(struct parser_params* p, VALUE regexp, const rb_code_location_t *loc) |
318 | | { |
319 | | reg_named_capture_assign_t arg; |
320 | | |
321 | | arg.parser = p; |
322 | | arg.enc = rb_enc_get(regexp); |
323 | | arg.succ_block = 0; |
324 | | arg.loc = loc; |
325 | | onig_foreach_name(RREGEXP_PTR(regexp), reg_named_capture_assign_iter, &arg); |
326 | | |
327 | | if (!arg.succ_block) return 0; |
328 | | return RNODE_BLOCK(arg.succ_block)->nd_next; |
329 | | } |
330 | | |
331 | | static VALUE |
332 | | rbool(VALUE v) |
333 | | { |
334 | | return RBOOL(v); |
335 | | } |
336 | | |
337 | | static int |
338 | | undef_p(VALUE v) |
339 | | { |
340 | | return RB_UNDEF_P(v); |
341 | | } |
342 | | |
343 | | static int |
344 | | rtest(VALUE obj) |
345 | | { |
346 | | return (int)RB_TEST(obj); |
347 | | } |
348 | | |
349 | | static int |
350 | | nil_p(VALUE obj) |
351 | | { |
352 | | return (int)NIL_P(obj); |
353 | | } |
354 | | |
355 | | static VALUE |
356 | | syntax_error_new(void) |
357 | | { |
358 | | return rb_class_new_instance(0, 0, rb_eSyntaxError); |
359 | | } |
360 | | |
361 | | static int |
362 | | obj_frozen(VALUE obj) |
363 | | { |
364 | | return (int)RB_OBJ_FROZEN(obj); |
365 | | } |
366 | | |
367 | | static VALUE |
368 | | obj_write(VALUE old, VALUE *slot, VALUE young) |
369 | | { |
370 | | return RB_OBJ_WRITE(old, slot, young); |
371 | | } |
372 | | |
373 | | static VALUE |
374 | | obj_written(VALUE old, VALUE slot, VALUE young) |
375 | | { |
376 | | return RB_OBJ_WRITTEN(old, slot, young); |
377 | | } |
378 | | |
379 | | static VALUE |
380 | | default_rs(void) |
381 | | { |
382 | | return rb_default_rs; |
383 | | } |
384 | | |
385 | | static void * |
386 | | memmove2(void *dest, const void *src, size_t t, size_t n) |
387 | | { |
388 | | return memmove(dest, src, rbimpl_size_mul_or_raise(t, n)); |
389 | | } |
390 | | |
391 | | static void * |
392 | | nonempty_memcpy(void *dest, const void *src, size_t t, size_t n) |
393 | | { |
394 | | return ruby_nonempty_memcpy(dest, src, rbimpl_size_mul_or_raise(t, n)); |
395 | | } |
396 | | |
397 | | static VALUE |
398 | | ruby_verbose2(void) |
399 | | { |
400 | | return ruby_verbose; |
401 | | } |
402 | | |
403 | | static int * |
404 | | rb_errno_ptr2(void) |
405 | | { |
406 | | return rb_errno_ptr(); |
407 | | } |
408 | | |
409 | | static int |
410 | | type_p(VALUE obj, int t) |
411 | | { |
412 | | return (int)RB_TYPE_P(obj, t); |
413 | | } |
414 | | |
415 | | static int |
416 | | fixnum_p(VALUE obj) |
417 | | { |
418 | | return (int)RB_FIXNUM_P(obj); |
419 | | } |
420 | | |
421 | | static int |
422 | | symbol_p(VALUE obj) |
423 | | { |
424 | | return (int)RB_SYMBOL_P(obj); |
425 | | } |
426 | | |
427 | | static void * |
428 | | zalloc(size_t elemsiz) |
429 | | { |
430 | | return ruby_xcalloc(1, elemsiz); |
431 | | } |
432 | | |
433 | | static void |
434 | | gc_guard(VALUE obj) |
435 | | { |
436 | | RB_GC_GUARD(obj); |
437 | | } |
438 | | |
439 | | static rb_imemo_tmpbuf_t * |
440 | | tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt) |
441 | | { |
442 | | return rb_imemo_tmpbuf_parser_heap(buf, old_heap, cnt); |
443 | | } |
444 | | |
445 | | static VALUE |
446 | | arg_error(void) |
447 | | { |
448 | | return rb_eArgError; |
449 | | } |
450 | | |
451 | | static VALUE |
452 | | ruby_vm_frozen_core(void) |
453 | | { |
454 | | return rb_mRubyVMFrozenCore; |
455 | | } |
456 | | |
457 | | static int |
458 | | special_const_p(VALUE obj) |
459 | | { |
460 | | return (int)RB_SPECIAL_CONST_P(obj); |
461 | | } |
462 | | |
463 | | static int |
464 | | builtin_type(VALUE obj) |
465 | | { |
466 | | return (int)RB_BUILTIN_TYPE(obj); |
467 | | } |
468 | | |
469 | | static rb_ast_t * |
470 | | ast_new(VALUE nb) |
471 | | { |
472 | | rb_ast_t *ast = (rb_ast_t *)rb_imemo_new(imemo_ast, 0, 0, 0, nb); |
473 | | return ast; |
474 | | } |
475 | | |
476 | | static VALUE |
477 | | static_id2sym(ID id) |
478 | | { |
479 | | return (((VALUE)(id)<<RUBY_SPECIAL_SHIFT)|SYMBOL_FLAG); |
480 | | } |
481 | | |
482 | | static long |
483 | | str_coderange_scan_restartable(const char *s, const char *e, void *enc, int *cr) |
484 | | { |
485 | | return rb_str_coderange_scan_restartable(s, e, (rb_encoding *)enc, cr); |
486 | | } |
487 | | |
488 | | VALUE rb_io_gets_internal(VALUE io); |
489 | | extern VALUE rb_eArgError; |
490 | | extern VALUE rb_mRubyVMFrozenCore; |
491 | | VALUE rb_node_case_when_optimizable_literal(const NODE *const node); |
492 | | |
493 | | static const rb_parser_config_t rb_global_parser_config = { |
494 | | .malloc = ruby_xmalloc, |
495 | | .calloc = ruby_xcalloc, |
496 | | .realloc = ruby_xrealloc, |
497 | | .free = ruby_xfree, |
498 | | .alloc_n = ruby_xmalloc2, |
499 | | .alloc = ruby_xmalloc, |
500 | | .realloc_n = ruby_xrealloc2, |
501 | | .zalloc = zalloc, |
502 | | .rb_memmove = memmove2, |
503 | | .nonempty_memcpy = nonempty_memcpy, |
504 | | .xmalloc_mul_add = rb_xmalloc_mul_add, |
505 | | |
506 | | .tmpbuf_parser_heap = tmpbuf_parser_heap, |
507 | | .ast_new = ast_new, |
508 | | |
509 | | .compile_callback = rb_suppress_tracing, |
510 | | .reg_named_capture_assign = reg_named_capture_assign, |
511 | | |
512 | | .obj_freeze = rb_obj_freeze, |
513 | | .obj_hide = rb_obj_hide, |
514 | | .obj_frozen = obj_frozen, |
515 | | .type_p = type_p, |
516 | | .obj_freeze_raw = OBJ_FREEZE_RAW, |
517 | | |
518 | | .fixnum_p = fixnum_p, |
519 | | .symbol_p = symbol_p, |
520 | | |
521 | | .attr_get = rb_attr_get, |
522 | | |
523 | | .ary_new = rb_ary_new, |
524 | | .ary_push = rb_ary_push, |
525 | | .ary_new_from_args = rb_ary_new_from_args, |
526 | | .ary_pop = rb_ary_pop, |
527 | | .ary_last = rb_ary_last, |
528 | | .ary_unshift = rb_ary_unshift, |
529 | | .ary_new2 = rb_ary_new2, |
530 | | .ary_entry = rb_ary_entry, |
531 | | .ary_clear = rb_ary_clear, |
532 | | .ary_modify = rb_ary_modify, |
533 | | .array_len = rb_array_len, |
534 | | .array_aref = RARRAY_AREF, |
535 | | |
536 | | .sym_intern_ascii_cstr = rb_sym_intern_ascii_cstr, |
537 | | .make_temporary_id = rb_make_temporary_id, |
538 | | .is_local_id = is_local_id2, |
539 | | .is_attrset_id = is_attrset_id2, |
540 | | .is_global_name_punct = is_global_name_punct, |
541 | | .id_type = id_type, |
542 | | .id_attrset = rb_id_attrset, |
543 | | .intern = rb_intern, |
544 | | .intern2 = rb_intern2, |
545 | | .intern3 = intern3, |
546 | | .intern_str = rb_intern_str, |
547 | | .is_notop_id = is_notop_id2, |
548 | | .enc_symname_type = enc_symname_type, |
549 | | .str_intern = rb_str_intern, |
550 | | .id2name = rb_id2name, |
551 | | .id2str = rb_id2str, |
552 | | .id2sym = rb_id2sym, |
553 | | .sym2id = rb_sym2id, |
554 | | |
555 | | .str_catf = rb_str_catf, |
556 | | .str_cat_cstr = rb_str_cat_cstr, |
557 | | .str_subseq = rb_str_subseq, |
558 | | .str_dup = rb_str_dup, |
559 | | .str_new_frozen = rb_str_new_frozen, |
560 | | .str_buf_new = rb_str_buf_new, |
561 | | .str_buf_cat = rb_str_buf_cat, |
562 | | .str_modify = rb_str_modify, |
563 | | .str_set_len = rb_str_set_len, |
564 | | .str_cat = rb_str_cat, |
565 | | .str_resize = rb_str_resize, |
566 | | .str_new = rb_str_new, |
567 | | .str_new_cstr = rb_str_new_cstr, |
568 | | .fstring = rb_fstring, |
569 | | .is_ascii_string = is_ascii_string2, |
570 | | .enc_str_new = enc_str_new, |
571 | | .enc_str_buf_cat = enc_str_buf_cat, |
572 | | .str_buf_append = rb_str_buf_append, |
573 | | .str_vcatf = rb_str_vcatf, |
574 | | .string_value_cstr = rb_string_value_cstr, |
575 | | .rb_sprintf = rb_sprintf, |
576 | | .rstring_ptr = RSTRING_PTR, |
577 | | .rstring_end = RSTRING_END, |
578 | | .rstring_len = RSTRING_LEN, |
579 | | .filesystem_str_new_cstr = rb_filesystem_str_new_cstr, |
580 | | .obj_as_string = rb_obj_as_string, |
581 | | |
582 | | .hash_clear = rb_hash_clear, |
583 | | .hash_new = rb_hash_new, |
584 | | .hash_aset = rb_hash_aset, |
585 | | .hash_delete = rb_hash_delete, |
586 | | .hash_lookup = rb_hash_lookup, |
587 | | .ident_hash_new = rb_ident_hash_new, |
588 | | |
589 | | .num2int = rb_num2int_inline, |
590 | | .int2num = rb_int2num_inline, |
591 | | |
592 | | .stderr_tty_p = rb_stderr_tty_p, |
593 | | .write_error_str = rb_write_error_str, |
594 | | .default_rs = default_rs, |
595 | | .io_write = rb_io_write, |
596 | | .io_flush = rb_io_flush, |
597 | | .io_puts = rb_io_puts, |
598 | | .io_gets_internal = rb_io_gets_internal, |
599 | | |
600 | | .debug_output_stdout = rb_ractor_stdout, |
601 | | .debug_output_stderr = rb_ractor_stderr, |
602 | | |
603 | | .is_usascii_enc = is_usascii_enc, |
604 | | .enc_isalnum = enc_isalnum, |
605 | | .enc_precise_mbclen = enc_precise_mbclen, |
606 | | .mbclen_charfound_p = mbclen_charfound_p, |
607 | | .mbclen_charfound_len = mbclen_charfound_len, |
608 | | .enc_name = enc_name, |
609 | | .enc_prev_char = enc_prev_char, |
610 | | .enc_get = enc_get, |
611 | | .enc_asciicompat = enc_asciicompat, |
612 | | .utf8_encoding = utf8_encoding, |
613 | | .enc_associate = enc_associate, |
614 | | .ascii8bit_encoding = ascii8bit_encoding, |
615 | | .enc_codelen = enc_codelen, |
616 | | .enc_mbcput = enc_mbcput, |
617 | | .char_to_option_kcode = rb_char_to_option_kcode, |
618 | | .ascii8bit_encindex = rb_ascii8bit_encindex, |
619 | | .enc_find_index = rb_enc_find_index, |
620 | | .enc_from_index = enc_from_index, |
621 | | .enc_associate_index = rb_enc_associate_index, |
622 | | .enc_isspace = enc_isspace, |
623 | | .enc_coderange_7bit = ENC_CODERANGE_7BIT, |
624 | | .enc_coderange_unknown = ENC_CODERANGE_UNKNOWN, |
625 | | .enc_compatible = enc_compatible, |
626 | | .enc_from_encoding = enc_from_encoding, |
627 | | .encoding_get = encoding_get, |
628 | | .encoding_set = encoding_set, |
629 | | .encoding_is_ascii8bit = encoding_is_ascii8bit, |
630 | | .usascii_encoding = usascii_encoding, |
631 | | |
632 | | .ractor_make_shareable = rb_ractor_make_shareable, |
633 | | |
634 | | .local_defined = local_defined, |
635 | | .dvar_defined = dvar_defined, |
636 | | |
637 | | .literal_cmp = literal_cmp, |
638 | | .literal_hash = literal_hash, |
639 | | |
640 | | .syntax_error_append = syntax_error_append, |
641 | | .raise = rb_raise, |
642 | | .syntax_error_new = syntax_error_new, |
643 | | |
644 | | .errinfo = rb_errinfo, |
645 | | .set_errinfo = rb_set_errinfo, |
646 | | .exc_raise = rb_exc_raise, |
647 | | .make_exception = rb_make_exception, |
648 | | |
649 | | .sized_xfree = ruby_sized_xfree, |
650 | | .sized_realloc_n = ruby_sized_realloc_n, |
651 | | .obj_write = obj_write, |
652 | | .obj_written = obj_written, |
653 | | .gc_register_mark_object = rb_gc_register_mark_object, |
654 | | .gc_guard = gc_guard, |
655 | | .gc_mark = rb_gc_mark, |
656 | | .gc_mark_movable = rb_gc_mark_movable, |
657 | | .gc_location = rb_gc_location, |
658 | | |
659 | | .reg_compile = rb_reg_compile, |
660 | | .reg_check_preprocess = rb_reg_check_preprocess, |
661 | | .memcicmp = rb_memcicmp, |
662 | | |
663 | | .compile_warn = rb_compile_warn, |
664 | | .compile_warning = rb_compile_warning, |
665 | | .bug = rb_bug, |
666 | | .fatal = rb_fatal, |
667 | | .verbose = ruby_verbose2, |
668 | | .errno_ptr = rb_errno_ptr2, |
669 | | |
670 | | .make_backtrace = rb_make_backtrace, |
671 | | |
672 | | .scan_hex = ruby_scan_hex, |
673 | | .scan_oct = ruby_scan_oct, |
674 | | .scan_digits = ruby_scan_digits, |
675 | | .strtod = ruby_strtod, |
676 | | |
677 | | .rbool = rbool, |
678 | | .undef_p = undef_p, |
679 | | .rtest = rtest, |
680 | | .nil_p = nil_p, |
681 | | .qnil = Qnil, |
682 | | .qtrue = Qtrue, |
683 | | .qfalse = Qfalse, |
684 | | .qundef = Qundef, |
685 | | .eArgError = arg_error, |
686 | | .mRubyVMFrozenCore = ruby_vm_frozen_core, |
687 | | .long2int = rb_long2int, |
688 | | .special_const_p = special_const_p, |
689 | | .builtin_type = builtin_type, |
690 | | |
691 | | .node_case_when_optimizable_literal = rb_node_case_when_optimizable_literal, |
692 | | |
693 | | /* For Ripper */ |
694 | | .static_id2sym = static_id2sym, |
695 | | .str_coderange_scan_restartable = str_coderange_scan_restartable, |
696 | | }; |
697 | | |
698 | | rb_parser_t * |
699 | | rb_parser_params_allocate(void) |
700 | | { |
701 | | return rb_ruby_parser_allocate(&rb_global_parser_config); |
702 | | } |
703 | | |
704 | | rb_parser_t * |
705 | | rb_parser_params_new(void) |
706 | | { |
707 | | return rb_ruby_parser_new(&rb_global_parser_config); |
708 | | } |
709 | | |
710 | | VALUE |
711 | | rb_parser_new(void) |
712 | | { |
713 | | struct ruby_parser *parser; |
714 | | rb_parser_t *parser_params; |
715 | | |
716 | | /* |
717 | | * Create parser_params ahead of vparser because |
718 | | * rb_ruby_parser_new can run GC so if create vparser |
719 | | * first, parser_mark tries to mark not initialized parser_params. |
720 | | */ |
721 | | parser_params = rb_parser_params_new(); |
722 | | VALUE vparser = TypedData_Make_Struct(0, struct ruby_parser, |
723 | | &ruby_parser_data_type, parser); |
724 | | parser->parser_params = parser_params; |
725 | | |
726 | | return vparser; |
727 | | } |
728 | | |
729 | | void |
730 | | rb_parser_set_options(VALUE vparser, int print, int loop, int chomp, int split) |
731 | | { |
732 | | struct ruby_parser *parser; |
733 | | |
734 | | TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); |
735 | | rb_ruby_parser_set_options(parser->parser_params, print, loop, chomp, split); |
736 | | } |
737 | | |
738 | | VALUE |
739 | | rb_parser_set_context(VALUE vparser, const struct rb_iseq_struct *base, int main) |
740 | | { |
741 | | struct ruby_parser *parser; |
742 | | |
743 | | TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); |
744 | | rb_ruby_parser_set_context(parser->parser_params, base, main); |
745 | | return vparser; |
746 | | } |
747 | | |
748 | | void |
749 | | rb_parser_set_script_lines(VALUE vparser, VALUE lines) |
750 | | { |
751 | | struct ruby_parser *parser; |
752 | | |
753 | | TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); |
754 | | rb_ruby_parser_set_script_lines(parser->parser_params, lines); |
755 | | } |
756 | | |
757 | | void |
758 | | rb_parser_error_tolerant(VALUE vparser) |
759 | | { |
760 | | struct ruby_parser *parser; |
761 | | |
762 | | TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); |
763 | | rb_ruby_parser_error_tolerant(parser->parser_params); |
764 | | } |
765 | | |
766 | | rb_ast_t* |
767 | | rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE file, int start) |
768 | | { |
769 | | struct ruby_parser *parser; |
770 | | rb_ast_t *ast; |
771 | | |
772 | | TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); |
773 | | ast = rb_ruby_parser_compile_file_path(parser->parser_params, fname, file, start); |
774 | | RB_GC_GUARD(vparser); |
775 | | |
776 | | return ast; |
777 | | } |
778 | | |
779 | | void |
780 | | rb_parser_keep_tokens(VALUE vparser) |
781 | | { |
782 | | struct ruby_parser *parser; |
783 | | |
784 | | TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); |
785 | | rb_ruby_parser_keep_tokens(parser->parser_params); |
786 | | } |
787 | | |
788 | | rb_ast_t* |
789 | | rb_parser_compile_generic(VALUE vparser, VALUE (*lex_gets)(VALUE, int), VALUE fname, VALUE input, int start) |
790 | | { |
791 | | struct ruby_parser *parser; |
792 | | rb_ast_t *ast; |
793 | | |
794 | | TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); |
795 | | ast = rb_ruby_parser_compile_generic(parser->parser_params, lex_gets, fname, input, start); |
796 | | RB_GC_GUARD(vparser); |
797 | | |
798 | | return ast; |
799 | | } |
800 | | |
801 | | rb_ast_t* |
802 | | rb_parser_compile_string(VALUE vparser, const char *f, VALUE s, int line) |
803 | | { |
804 | | struct ruby_parser *parser; |
805 | | rb_ast_t *ast; |
806 | | |
807 | | TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); |
808 | | ast = rb_ruby_parser_compile_string(parser->parser_params, f, s, line); |
809 | | RB_GC_GUARD(vparser); |
810 | | |
811 | | return ast; |
812 | | } |
813 | | |
814 | | rb_ast_t* |
815 | | rb_parser_compile_string_path(VALUE vparser, VALUE f, VALUE s, int line) |
816 | | { |
817 | | struct ruby_parser *parser; |
818 | | rb_ast_t *ast; |
819 | | |
820 | | TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); |
821 | | ast = rb_ruby_parser_compile_string_path(parser->parser_params, f, s, line); |
822 | | RB_GC_GUARD(vparser); |
823 | | |
824 | | return ast; |
825 | | } |
826 | | |
827 | | VALUE |
828 | | rb_parser_encoding(VALUE vparser) |
829 | | { |
830 | | struct ruby_parser *parser; |
831 | | |
832 | | TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); |
833 | | return rb_ruby_parser_encoding(parser->parser_params); |
834 | | } |
835 | | |
836 | | VALUE |
837 | | rb_parser_end_seen_p(VALUE vparser) |
838 | | { |
839 | | struct ruby_parser *parser; |
840 | | |
841 | | TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); |
842 | | return RBOOL(rb_ruby_parser_end_seen_p(parser->parser_params)); |
843 | | } |
844 | | |
845 | | VALUE |
846 | | rb_parser_set_yydebug(VALUE vparser, VALUE flag) |
847 | | { |
848 | | struct ruby_parser *parser; |
849 | | |
850 | | TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); |
851 | | rb_ruby_parser_set_yydebug(parser->parser_params, RTEST(flag)); |
852 | | return flag; |
853 | | } |
854 | | #endif |
855 | | |
856 | | VALUE |
857 | | rb_str_new_parser_string(rb_parser_string_t *str) |
858 | 0 | { |
859 | 0 | return rb_enc_str_new(str->ptr, str->len, str->enc); |
860 | 0 | } |
861 | | |
862 | | static VALUE |
863 | | negative_numeric(VALUE val) |
864 | 0 | { |
865 | 0 | if (FIXNUM_P(val)) { |
866 | 0 | return LONG2FIX(-FIX2LONG(val)); |
867 | 0 | } |
868 | 0 | if (SPECIAL_CONST_P(val)) { |
869 | 0 | #if USE_FLONUM |
870 | 0 | if (FLONUM_P(val)) { |
871 | 0 | return DBL2NUM(-RFLOAT_VALUE(val)); |
872 | 0 | } |
873 | 0 | #endif |
874 | 0 | goto unknown; |
875 | 0 | } |
876 | 0 | switch (BUILTIN_TYPE(val)) { |
877 | 0 | case T_BIGNUM: |
878 | 0 | BIGNUM_NEGATE(val); |
879 | 0 | val = rb_big_norm(val); |
880 | 0 | break; |
881 | 0 | case T_RATIONAL: |
882 | 0 | RATIONAL_SET_NUM(val, negative_numeric(RRATIONAL(val)->num)); |
883 | 0 | break; |
884 | 0 | case T_COMPLEX: |
885 | 0 | RCOMPLEX_SET_REAL(val, negative_numeric(RCOMPLEX(val)->real)); |
886 | 0 | RCOMPLEX_SET_IMAG(val, negative_numeric(RCOMPLEX(val)->imag)); |
887 | 0 | break; |
888 | 0 | case T_FLOAT: |
889 | 0 | val = DBL2NUM(-RFLOAT_VALUE(val)); |
890 | 0 | break; |
891 | 0 | unknown: |
892 | 0 | default: |
893 | 0 | rb_bug("unknown literal type (%s) passed to negative_numeric", |
894 | 0 | rb_builtin_class_name(val)); |
895 | 0 | break; |
896 | 0 | } |
897 | 0 | return val; |
898 | 0 | } |
899 | | |
900 | | static VALUE |
901 | | integer_value(const char *val, int base) |
902 | 0 | { |
903 | 0 | return rb_cstr_to_inum(val, base, FALSE); |
904 | 0 | } |
905 | | |
906 | | static VALUE |
907 | | rational_value(const char *node_val, int base, int seen_point) |
908 | 0 | { |
909 | 0 | VALUE lit; |
910 | 0 | char* val = strdup(node_val); |
911 | 0 | if (seen_point > 0) { |
912 | 0 | int len = (int)(strlen(val)); |
913 | 0 | char *point = &val[seen_point]; |
914 | 0 | size_t fraclen = len-seen_point-1; |
915 | 0 | memmove(point, point+1, fraclen+1); |
916 | |
|
917 | 0 | lit = rb_rational_new(integer_value(val, base), rb_int_positive_pow(10, fraclen)); |
918 | 0 | } |
919 | 0 | else { |
920 | 0 | lit = rb_rational_raw1(integer_value(val, base)); |
921 | 0 | } |
922 | |
|
923 | 0 | free(val); |
924 | |
|
925 | 0 | return lit; |
926 | 0 | } |
927 | | |
928 | | VALUE |
929 | | rb_node_integer_literal_val(const NODE *n) |
930 | 0 | { |
931 | 0 | const rb_node_integer_t *node = RNODE_INTEGER(n); |
932 | 0 | VALUE val = integer_value(node->val, node->base); |
933 | 0 | if (node->minus) { |
934 | 0 | val = negative_numeric(val); |
935 | 0 | } |
936 | 0 | return val; |
937 | 0 | } |
938 | | |
939 | | VALUE |
940 | | rb_node_float_literal_val(const NODE *n) |
941 | 0 | { |
942 | 0 | const rb_node_float_t *node = RNODE_FLOAT(n); |
943 | 0 | double d = strtod(node->val, 0); |
944 | 0 | if (node->minus) { |
945 | 0 | d = -d; |
946 | 0 | } |
947 | 0 | VALUE val = DBL2NUM(d); |
948 | 0 | return val; |
949 | 0 | } |
950 | | |
951 | | VALUE |
952 | | rb_node_rational_literal_val(const NODE *n) |
953 | 0 | { |
954 | 0 | VALUE lit; |
955 | 0 | const rb_node_rational_t *node = RNODE_RATIONAL(n); |
956 | |
|
957 | 0 | lit = rational_value(node->val, node->base, node->seen_point); |
958 | |
|
959 | 0 | if (node->minus) { |
960 | 0 | lit = negative_numeric(lit); |
961 | 0 | } |
962 | |
|
963 | 0 | return lit; |
964 | 0 | } |
965 | | |
966 | | VALUE |
967 | | rb_node_imaginary_literal_val(const NODE *n) |
968 | 0 | { |
969 | 0 | VALUE lit; |
970 | 0 | const rb_node_imaginary_t *node = RNODE_IMAGINARY(n); |
971 | |
|
972 | 0 | enum rb_numeric_type type = node->type; |
973 | |
|
974 | 0 | switch (type) { |
975 | 0 | case integer_literal: |
976 | 0 | lit = integer_value(node->val, node->base); |
977 | 0 | break; |
978 | 0 | case float_literal:{ |
979 | 0 | double d = strtod(node->val, 0); |
980 | 0 | lit = DBL2NUM(d); |
981 | 0 | break; |
982 | 0 | } |
983 | 0 | case rational_literal: |
984 | 0 | lit = rational_value(node->val, node->base, node->seen_point); |
985 | 0 | break; |
986 | 0 | default: |
987 | 0 | rb_bug("unreachable"); |
988 | 0 | } |
989 | | |
990 | 0 | lit = rb_complex_raw(INT2FIX(0), lit); |
991 | |
|
992 | 0 | if (node->minus) { |
993 | 0 | lit = negative_numeric(lit); |
994 | 0 | } |
995 | 0 | return lit; |
996 | 0 | } |
997 | | |
998 | | VALUE |
999 | | rb_node_str_string_val(const NODE *node) |
1000 | 0 | { |
1001 | 0 | rb_parser_string_t *str = RNODE_STR(node)->string; |
1002 | 0 | return rb_str_new_parser_string(str); |
1003 | 0 | } |
1004 | | |
1005 | | VALUE |
1006 | | rb_node_sym_string_val(const NODE *node) |
1007 | 0 | { |
1008 | 0 | rb_parser_string_t *str = RNODE_SYM(node)->string; |
1009 | 0 | return ID2SYM(rb_intern3(str->ptr, str->len, str->enc)); |
1010 | 0 | } |
1011 | | |
1012 | | VALUE |
1013 | | rb_node_dstr_string_val(const NODE *node) |
1014 | 0 | { |
1015 | 0 | rb_parser_string_t *str = RNODE_DSTR(node)->string; |
1016 | 0 | return str ? rb_str_new_parser_string(str) : Qnil; |
1017 | 0 | } |
1018 | | |
1019 | | VALUE |
1020 | | rb_node_dregx_string_val(const NODE *node) |
1021 | 0 | { |
1022 | 0 | rb_parser_string_t *str = RNODE_DREGX(node)->string; |
1023 | 0 | return rb_str_new_parser_string(str); |
1024 | 0 | } |
1025 | | |
1026 | | VALUE |
1027 | | rb_node_line_lineno_val(const NODE *node) |
1028 | 0 | { |
1029 | 0 | return INT2FIX(node->nd_loc.beg_pos.lineno); |
1030 | 0 | } |
1031 | | |
1032 | | VALUE |
1033 | | rb_node_file_path_val(const NODE *node) |
1034 | 0 | { |
1035 | 0 | return rb_str_new_parser_string(RNODE_FILE(node)->path); |
1036 | 0 | } |
1037 | | |
1038 | | VALUE |
1039 | | rb_node_encoding_val(const NODE *node) |
1040 | 0 | { |
1041 | 0 | return rb_enc_from_encoding(RNODE_ENCODING(node)->enc); |
1042 | 0 | } |
1043 | | |
1044 | | VALUE |
1045 | | rb_node_const_decl_val(const NODE *node) |
1046 | 0 | { |
1047 | 0 | VALUE path; |
1048 | 0 | switch (nd_type(node)) { |
1049 | 0 | case NODE_CDECL: |
1050 | 0 | if (RNODE_CDECL(node)->nd_vid) { |
1051 | 0 | path = rb_id2str(RNODE_CDECL(node)->nd_vid); |
1052 | 0 | goto end; |
1053 | 0 | } |
1054 | 0 | else { |
1055 | 0 | node = RNODE_CDECL(node)->nd_else; |
1056 | 0 | } |
1057 | 0 | break; |
1058 | 0 | case NODE_COLON2: |
1059 | 0 | break; |
1060 | 0 | case NODE_COLON3: |
1061 | | // ::Const |
1062 | 0 | path = rb_str_new_cstr("::"); |
1063 | 0 | rb_str_append(path, rb_id2str(RNODE_COLON3(node)->nd_mid)); |
1064 | 0 | goto end; |
1065 | 0 | default: |
1066 | 0 | rb_bug("unexpected node: %s", ruby_node_name(nd_type(node))); |
1067 | 0 | UNREACHABLE_RETURN(0); |
1068 | 0 | } |
1069 | | |
1070 | 0 | path = rb_ary_new(); |
1071 | 0 | if (node) { |
1072 | 0 | for (; node && nd_type_p(node, NODE_COLON2); node = RNODE_COLON2(node)->nd_head) { |
1073 | 0 | rb_ary_push(path, rb_id2str(RNODE_COLON2(node)->nd_mid)); |
1074 | 0 | } |
1075 | 0 | if (node && nd_type_p(node, NODE_CONST)) { |
1076 | | // Const::Name |
1077 | 0 | rb_ary_push(path, rb_id2str(RNODE_CONST(node)->nd_vid)); |
1078 | 0 | } |
1079 | 0 | else if (node && nd_type_p(node, NODE_COLON3)) { |
1080 | | // ::Const::Name |
1081 | 0 | rb_ary_push(path, rb_id2str(RNODE_COLON3(node)->nd_mid)); |
1082 | 0 | rb_ary_push(path, rb_str_new(0, 0)); |
1083 | 0 | } |
1084 | 0 | else { |
1085 | | // expression::Name |
1086 | 0 | rb_ary_push(path, rb_str_new_cstr("...")); |
1087 | 0 | } |
1088 | 0 | path = rb_ary_join(rb_ary_reverse(path), rb_str_new_cstr("::")); |
1089 | 0 | } |
1090 | 0 | end: |
1091 | 0 | path = rb_fstring(path); |
1092 | 0 | return path; |
1093 | 0 | } |