Ruby 2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)

marshal.c
Go to the documentation of this file.
1 /**********************************************************************
2
3 marshal.c -
4
5 $Author$
6 created at: Thu Apr 27 16:30:01 JST 1995
7
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
9
10 **********************************************************************/
11
12 #include "ruby/ruby.h"
13 #include "ruby/io.h"
14 #include "internal.h"
15 #include "ruby/st.h"
16 #include "ruby/util.h"
17 #include "encindex.h"
18 #include "id_table.h"
19
20 #include <math.h>
21 #ifdef HAVE_FLOAT_H
22 #include <float.h>
23 #endif
24 #ifdef HAVE_IEEEFP_H
25 #include <ieeefp.h>
26 #endif
27
28 #define BITSPERSHORT (2*CHAR_BIT)
29 #define SHORTMASK ((1<<BITSPERSHORT)-1)
30 #define SHORTDN(x) RSHIFT((x),BITSPERSHORT)
31
32 #if SIZEOF_SHORT == SIZEOF_BDIGIT
33 #define SHORTLEN(x) (x)
34 #else
35 static size_t
36 shortlen(size_t len, BDIGIT *ds)
37 {
38 BDIGIT num;
39 int offset = 0;
40
41 num = ds[len-1];
42 while (num) {
43 num = SHORTDN(num);
44 offset++;
45 }
46 return (len - 1)*SIZEOF_BDIGIT/2 + offset;
47 }
48 #define SHORTLEN(x) shortlen((x),d)
49 #endif
50
51 #define MARSHAL_MAJOR 4
52 #define MARSHAL_MINOR 8
53
54 #define TYPE_NIL '0'
55 #define TYPE_TRUE 'T'
56 #define TYPE_FALSE 'F'
57 #define TYPE_FIXNUM 'i'
58
59 #define TYPE_EXTENDED 'e'
60 #define TYPE_UCLASS 'C'
61 #define TYPE_OBJECT 'o'
62 #define TYPE_DATA 'd'
63 #define TYPE_USERDEF 'u'
64 #define TYPE_USRMARSHAL 'U'
65 #define TYPE_FLOAT 'f'
66 #define TYPE_BIGNUM 'l'
67 #define TYPE_STRING '"'
68 #define TYPE_REGEXP '/'
69 #define TYPE_ARRAY '['
70 #define TYPE_HASH '{'
71 #define TYPE_HASH_DEF '}'
72 #define TYPE_STRUCT 'S'
73 #define TYPE_MODULE_OLD 'M'
74 #define TYPE_CLASS 'c'
75 #define TYPE_MODULE 'm'
76
77 #define TYPE_SYMBOL ':'
78 #define TYPE_SYMLINK ';'
79
80 #define TYPE_IVAR 'I'
81 #define TYPE_LINK '@'
82
83 static ID s_dump, s_load, s_mdump, s_mload;
84 static ID s_dump_data, s_load_data, s_alloc, s_call;
85 static ID s_getbyte, s_read, s_write, s_binmode;
86 static ID s_encoding_short;
87
88 #define name_s_dump "_dump"
89 #define name_s_load "_load"
90 #define name_s_mdump "marshal_dump"
91 #define name_s_mload "marshal_load"
92 #define name_s_dump_data "_dump_data"
93 #define name_s_load_data "_load_data"
94 #define name_s_alloc "_alloc"
95 #define name_s_call "call"
96 #define name_s_getbyte "getbyte"
97 #define name_s_read "read"
98 #define name_s_write "write"
99 #define name_s_binmode "binmode"
100 #define name_s_encoding_short "E"
101
102 typedef struct {
103 VALUE newclass;
104 VALUE oldclass;
105 VALUE (*dumper)(VALUE);
106 VALUE (*loader)(VALUE, VALUE);
107 } marshal_compat_t;
108
109 static st_table *compat_allocator_tbl;
110 static VALUE compat_allocator_tbl_wrapper;
111 static VALUE rb_marshal_dump_limited(VALUE obj, VALUE port, int limit);
112 static VALUE rb_marshal_load_with_proc(VALUE port, VALUE proc);
113
114 static int
115 mark_marshal_compat_i(st_data_t key, st_data_t value, st_data_t _)
116 {
117 marshal_compat_t *p = (marshal_compat_t *)value;
118 rb_gc_mark(p->newclass);
119 rb_gc_mark(p->oldclass);
120 return ST_CONTINUE;
121 }
122
123 static void
124 mark_marshal_compat_t(void *tbl)
125 {
126 if (!tbl) return;
127 st_foreach(tbl, mark_marshal_compat_i, 0);
128 }
129
130 static st_table *compat_allocator_table(void);
131
132 void
133 rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE (*dumper)(VALUE), VALUE (*loader)(VALUE, VALUE))
134 {
135 marshal_compat_t *compat;
136 rb_alloc_func_t allocator = rb_get_alloc_func(newclass);
137
138 if (!allocator) {
139 rb_raise(rb_eTypeError, "no allocator");
140 }
141
142 compat = ALLOC(marshal_compat_t);
143 compat->newclass = Qnil;
144 compat->oldclass = Qnil;
145 compat->newclass = newclass;
146 compat->oldclass = oldclass;
147 compat->dumper = dumper;
148 compat->loader = loader;
149
150 st_insert(compat_allocator_table(), (st_data_t)allocator, (st_data_t)compat);
151 }
152
153 struct dump_arg {
154 VALUE str, dest;
155 st_table *symbols;
156 st_table *data;
157 st_table *compat_tbl;
158 st_table *encodings;
159 };
160
161 struct dump_call_arg {
162 VALUE obj;
163 struct dump_arg *arg;
164 int limit;
165 };
166
167 static VALUE
168 check_dump_arg(VALUE ret, struct dump_arg *arg, const char *name)
169 {
170 if (!arg->symbols) {
171 rb_raise(rb_eRuntimeError, "Marshal.dump reentered at %s",
172 name);
173 }
174 return ret;
175 }
176
177 static VALUE
178 check_userdump_arg(VALUE obj, ID sym, int argc, const VALUE *argv,
179 struct dump_arg *arg, const char *name)
180 {
181 VALUE ret = rb_funcallv(obj, sym, argc, argv);
182 VALUE klass = CLASS_OF(obj);
183 if (CLASS_OF(ret) == klass) {
184 rb_raise(rb_eRuntimeError, "%"PRIsVALUE"#%s returned same class instance",
185 klass, name);
186 }
187 return check_dump_arg(ret, arg, name);
188 }
189
190 #define dump_funcall(arg, obj, sym, argc, argv) \
191 check_userdump_arg(obj, sym, argc, argv, arg, name_##sym)
192 #define dump_check_funcall(arg, obj, sym, argc, argv) \
193 check_dump_arg(rb_check_funcall(obj, sym, argc, argv), arg, name_##sym)
194
195 static void clear_dump_arg(struct dump_arg *arg);
196
197 static void
198 mark_dump_arg(void *ptr)
199 {
200 struct dump_arg *p = ptr;
201 if (!p->symbols)
202 return;
203 rb_mark_set(p->symbols);
204 rb_mark_set(p->data);
205 rb_mark_hash(p->compat_tbl);
206 rb_gc_mark(p->str);
207 }
208
209 static void
210 free_dump_arg(void *ptr)
211 {
212 clear_dump_arg(ptr);
213 xfree(ptr);
214 }
215
216 static size_t
217 memsize_dump_arg(const void *ptr)
218 {
219 return sizeof(struct dump_arg);
220 }
221
222 static const rb_data_type_t dump_arg_data = {
223 "dump_arg",
224 {mark_dump_arg, free_dump_arg, memsize_dump_arg,},
225 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
226 };
227
228 static VALUE
229 must_not_be_anonymous(const char *type, VALUE path)
230 {
231 char *n = RSTRING_PTR(path);
232
233 if (!rb_enc_asciicompat(rb_enc_get(path))) {
234 /* cannot occur? */
235 rb_raise(rb_eTypeError, "can't dump non-ascii %s name % "PRIsVALUE,
236 type, path);
237 }
238 if (n[0] == '#') {
239 rb_raise(rb_eTypeError, "can't dump anonymous %s % "PRIsVALUE,
240 type, path);
241 }
242 return path;
243 }
244
245 static VALUE
246 class2path(VALUE klass)
247 {
248 VALUE path = rb_class_path(klass);
249
250 must_not_be_anonymous((RB_TYPE_P(klass, T_CLASS) ? "class" : "module"), path);
251 if (rb_path_to_class(path) != rb_class_real(klass)) {
252 rb_raise(rb_eTypeError, "% "PRIsVALUE" can't be referred to", path);
253 }
254 return path;
255 }
256
257 int ruby_marshal_write_long(long x, char *buf);
258 static void w_long(long, struct dump_arg*);
259 static int w_encoding(VALUE encname, struct dump_call_arg *arg);
260 static VALUE encoding_name(VALUE obj, struct dump_arg *arg);
261
262 static void
263 w_nbyte(const char *s, long n, struct dump_arg *arg)
264 {
265 VALUE buf = arg->str;
266 rb_str_buf_cat(buf, s, n);
267 if (arg->dest && RSTRING_LEN(buf) >= BUFSIZ) {
268 rb_io_write(arg->dest, buf);
269 rb_str_resize(buf, 0);
270 }
271 }
272
273 static void
274 w_byte(char c, struct dump_arg *arg)
275 {
276 w_nbyte(&c, 1, arg);
277 }
278
279 static void
280 w_bytes(const char *s, long n, struct dump_arg *arg)
281 {
282 w_long(n, arg);
283 w_nbyte(s, n, arg);
284 }
285
286 #define w_cstr(s, arg) w_bytes((s), strlen(s), (arg))
287
288 static void
289 w_short(int x, struct dump_arg *arg)
290 {
291 w_byte((char)((x >> 0) & 0xff), arg);
292 w_byte((char)((x >> 8) & 0xff), arg);
293 }
294
295 static void
296 w_long(long x, struct dump_arg *arg)
297 {
298 char buf[sizeof(long)+1];
299 int i = ruby_marshal_write_long(x, buf);
300 if (i < 0) {
301 rb_raise(rb_eTypeError, "long too big to dump");
302 }
303 w_nbyte(buf, i, arg);
304 }
305
306 int
307 ruby_marshal_write_long(long x, char *buf)
308 {
309 int i;
310
311 #if SIZEOF_LONG > 4
312 if (!(RSHIFT(x, 31) == 0 || RSHIFT(x, 31) == -1)) {
313 /* big long does not fit in 4 bytes */
314 return -1;
315 }
316 #endif
317
318 if (x == 0) {
319 buf[0] = 0;
320 return 1;
321 }
322 if (0 < x && x < 123) {
323 buf[0] = (char)(x + 5);
324 return 1;
325 }
326 if (-124 < x && x < 0) {
327 buf[0] = (char)((x - 5)&0xff);
328 return 1;
329 }
330 for (i=1;i<(int)sizeof(long)+1;i++) {
331 buf[i] = (char)(x & 0xff);
332 x = RSHIFT(x,8);
333 if (x == 0) {
334 buf[0] = i;
335 break;
336 }
337 if (x == -1) {
338 buf[0] = -i;
339 break;
340 }
341 }
342 return i+1;
343 }
344
345 #ifdef DBL_MANT_DIG
346 #define DECIMAL_MANT (53-16) /* from IEEE754 double precision */
347
348 #if DBL_MANT_DIG > 32
349 #define MANT_BITS 32
350 #elif DBL_MANT_DIG > 24
351 #define MANT_BITS 24
352 #elif DBL_MANT_DIG > 16
353 #define MANT_BITS 16
354 #else
355 #define MANT_BITS 8
356 #endif
357
358 static double
359 load_mantissa(double d, const char *buf, long len)
360 {
361 if (!len) return d;
362 if (--len > 0 && !*buf++) { /* binary mantissa mark */
363 int e, s = d < 0, dig = 0;
364 unsigned long m;
365
366 modf(ldexp(frexp(fabs(d), &e), DECIMAL_MANT), &d);
367 do {
368 m = 0;
369 switch (len) {
370 default: m = *buf++ & 0xff; /* fall through */
371 #if MANT_BITS > 24
372 case 3: m = (m << 8) | (*buf++ & 0xff); /* fall through */
373 #endif
374 #if MANT_BITS > 16
375 case 2: m = (m << 8) | (*buf++ & 0xff); /* fall through */
376 #endif
377 #if MANT_BITS > 8
378 case 1: m = (m << 8) | (*buf++ & 0xff);
379 #endif
380 }
381 dig -= len < MANT_BITS / 8 ? 8 * (unsigned)len : MANT_BITS;
382 d += ldexp((double)m, dig);
383 } while ((len -= MANT_BITS / 8) > 0);
384 d = ldexp(d, e - DECIMAL_MANT);
385 if (s) d = -d;
386 }
387 return d;
388 }
389 #else
390 #define load_mantissa(d, buf, len) (d)
391 #endif
392
393 #ifdef DBL_DIG
394 #define FLOAT_DIG (DBL_DIG+2)
395 #else
396 #define FLOAT_DIG 17
397 #endif
398
399 static void
400 w_float(double d, struct dump_arg *arg)
401 {
402 char buf[FLOAT_DIG + (DECIMAL_MANT + 7) / 8 + 10];
403
404 if (isinf(d)) {
405 if (d < 0) w_cstr("-inf", arg);
406 else w_cstr("inf", arg);
407 }
408 else if (isnan(d)) {
409 w_cstr("nan", arg);
410 }
411 else if (d == 0.0) {
412 if (signbit(d)) w_cstr("-0", arg);
413 else w_cstr("0", arg);
414 }
415 else {
416 int decpt, sign, digs, len = 0;
417 char *e, *p = ruby_dtoa(d, 0, 0, &decpt, &sign, &e);
418 if (sign) buf[len++] = '-';
419 digs = (int)(e - p);
420 if (decpt < -3 || decpt > digs) {
421 buf[len++] = p[0];
422 if (--digs > 0) buf[len++] = '.';
423 memcpy(buf + len, p + 1, digs);
424 len += digs;
425 len += snprintf(buf + len, sizeof(buf) - len, "e%d", decpt - 1);
426 }
427 else if (decpt > 0) {
428 memcpy(buf + len, p, decpt);
429 len += decpt;
430 if ((digs -= decpt) > 0) {
431 buf[len++] = '.';
432 memcpy(buf + len, p + decpt, digs);
433 len += digs;
434 }
435 }
436 else {
437 buf[len++] = '0';
438 buf[len++] = '.';
439 if (decpt) {
440 memset(buf + len, '0', -decpt);
441 len -= decpt;
442 }
443 memcpy(buf + len, p, digs);
444 len += digs;
445 }
446 xfree(p);
447 w_bytes(buf, len, arg);
448 }
449 }
450
451 static void
452 w_symbol(VALUE sym, struct dump_arg *arg)
453 {
454 st_data_t num;
455 VALUE encname;
456
457 if (st_lookup(arg->symbols, sym, &num)) {
458 w_byte(TYPE_SYMLINK, arg);
459 w_long((long)num, arg);
460 }
461 else {
462 const VALUE orig_sym = sym;
463 sym = rb_sym2str(sym);
464 if (!sym) {
465 rb_raise(rb_eTypeError, "can't dump anonymous ID %"PRIdVALUE, sym);
466 }
467 encname = encoding_name(sym, arg);
468 if (NIL_P(encname) ||
469 rb_enc_str_coderange(sym) == ENC_CODERANGE_7BIT) {
470 encname = Qnil;
471 }
472 else {
473 w_byte(TYPE_IVAR, arg);
474 }
475 w_byte(TYPE_SYMBOL, arg);
476 w_bytes(RSTRING_PTR(sym), RSTRING_LEN(sym), arg);
477 st_add_direct(arg->symbols, orig_sym, arg->symbols->num_entries);
478 if (!NIL_P(encname)) {
479 struct dump_call_arg c_arg;
480 c_arg.limit = 1;
481 c_arg.arg = arg;
482 w_long(1L, arg);
483 w_encoding(encname, &c_arg);
484 }
485 }
486 }
487
488 static void
489 w_unique(VALUE s, struct dump_arg *arg)
490 {
491 must_not_be_anonymous("class", s);
492 w_symbol(rb_str_intern(s), arg);
493 }
494
495 static void w_object(VALUE,struct dump_arg*,int);
496
497 static int
498 hash_each(VALUE key, VALUE value, VALUE v)
499 {
500 struct dump_call_arg *arg = (void *)v;
501 w_object(key, arg->arg, arg->limit);
502 w_object(value, arg->arg, arg->limit);
503 return ST_CONTINUE;
504 }
505
506 #define SINGLETON_DUMP_UNABLE_P(klass) \
507 (rb_id_table_size(RCLASS_M_TBL(klass)) > 0 || \
508 (RCLASS_IV_TBL(klass) && RCLASS_IV_TBL(klass)->num_entries > 1))
509
510 static void
511 w_extended(VALUE klass, struct dump_arg *arg, int check)
512 {
513 if (check && FL_TEST(klass, FL_SINGLETON)) {
514 VALUE origin = RCLASS_ORIGIN(klass);
515 if (SINGLETON_DUMP_UNABLE_P(klass) ||
516 (origin != klass && SINGLETON_DUMP_UNABLE_P(origin))) {
517 rb_raise(rb_eTypeError, "singleton can't be dumped");
518 }
519 klass = RCLASS_SUPER(klass);
520 }
521 while (BUILTIN_TYPE(klass) == T_ICLASS) {
522 VALUE path = rb_class_name(RBASIC(klass)->klass);
523 w_byte(TYPE_EXTENDED, arg);
524 w_unique(path, arg);
525 klass = RCLASS_SUPER(klass);
526 }
527 }
528
529 static void
530 w_class(char type, VALUE obj, struct dump_arg *arg, int check)
531 {
532 VALUE path;
533 st_data_t real_obj;
534 VALUE klass;
535
536 if (arg->compat_tbl &&
537 st_lookup(arg->compat_tbl, (st_data_t)obj, &real_obj)) {
538 obj = (VALUE)real_obj;
539 }
540 klass = CLASS_OF(obj);
541 w_extended(klass, arg, check);
542 w_byte(type, arg);
543 path = class2path(rb_class_real(klass));
544 w_unique(path, arg);
545 }
546
547 static void
548 w_uclass(VALUE obj, VALUE super, struct dump_arg *arg)
549 {
550 VALUE klass = CLASS_OF(obj);
551
552 w_extended(klass, arg, TRUE);
553 klass = rb_class_real(klass);
554 if (klass != super) {
555 w_byte(TYPE_UCLASS, arg);
556 w_unique(class2path(klass), arg);
557 }
558 }
559
560 #define to_be_skipped_id(id) (id == rb_id_encoding() || id == s_encoding_short || !rb_id2str(id))
561
562 struct w_ivar_arg {
563 struct dump_call_arg *dump;
564 st_data_t num_ivar;
565 };
566
567 static int
568 w_obj_each(st_data_t key, st_data_t val, st_data_t a)
569 {
570 ID id = (ID)key;
571 VALUE value = (VALUE)val;
572 struct w_ivar_arg *ivarg = (struct w_ivar_arg *)a;
573 struct dump_call_arg *arg = ivarg->dump;
574
575 if (to_be_skipped_id(id)) {
576 if (id == s_encoding_short) {
577 rb_warn("instance variable `E' on class %"PRIsVALUE" is not dumped",
578 CLASS_OF(arg->obj));
579 }
580 return ST_CONTINUE;
581 }
582 if (!ivarg->num_ivar) {
583 rb_raise(rb_eRuntimeError, "instance variable added to %"PRIsVALUE" instance",
584 CLASS_OF(arg->obj));
585 }
586 --ivarg->num_ivar;
587 w_symbol(ID2SYM(id), arg->arg);
588 w_object(value, arg->arg, arg->limit);
589 return ST_CONTINUE;
590 }
591
592 static int
593 obj_count_ivars(st_data_t key, st_data_t val, st_data_t a)
594 {
595 ID id = (ID)key;
596 if (!to_be_skipped_id(id)) ++*(st_index_t *)a;
597 return ST_CONTINUE;
598 }
599
600 static VALUE
601 encoding_name(VALUE obj, struct dump_arg *arg)
602 {
603 if (rb_enc_capable(obj)) {
604 int encidx = rb_enc_get_index(obj);
605 rb_encoding *enc = 0;
606 st_data_t name;
607
608 if (encidx <= 0 || !(enc = rb_enc_from_index(encidx))) {
609 return Qnil;
610 }
611
612 /* special treatment for US-ASCII and UTF-8 */
613 if (encidx == rb_usascii_encindex()) {
614 return Qfalse;
615 }
616 else if (encidx == rb_utf8_encindex()) {
617 return Qtrue;
618 }
619
620 if (arg->encodings ?
621 !st_lookup(arg->encodings, (st_data_t)rb_enc_name(enc), &name) :
622 (arg->encodings = st_init_strcasetable(), 1)) {
623 name = (st_data_t)rb_str_new_cstr(rb_enc_name(enc));
624 st_insert(arg->encodings, (st_data_t)rb_enc_name(enc), name);
625 }
626 return (VALUE)name;
627 }
628 else {
629 return Qnil;
630 }
631 }
632
633 static int
634 w_encoding(VALUE encname, struct dump_call_arg *arg)
635 {
636 int limit = arg->limit;
637 if (limit >= 0) ++limit;
638 switch (encname) {
639 case Qfalse:
640 case Qtrue:
641 w_symbol(ID2SYM(s_encoding_short), arg->arg);
642 w_object(encname, arg->arg, limit);
643 return 1;
644 case Qnil:
645 return 0;
646 }
647 w_symbol(ID2SYM(rb_id_encoding()), arg->arg);
648 w_object(encname, arg->arg, limit);
649 return 1;
650 }
651
652 static st_index_t
653 has_ivars(VALUE obj, VALUE encname, VALUE *ivobj)
654 {
655 st_index_t enc = !NIL_P(encname);
656 st_index_t num = 0;
657
658 if (SPECIAL_CONST_P(obj)) goto generic;
659 switch (BUILTIN_TYPE(obj)) {
660 case T_OBJECT:
661 case T_CLASS:
662 case T_MODULE:
663 break; /* counted elsewhere */
664 default:
665 generic:
666 rb_ivar_foreach(obj, obj_count_ivars, (st_data_t)&num);
667 if (num) *ivobj = obj;
668 }
669
670 return num + enc;
671 }
672
673 static void
674 w_ivar_each(VALUE obj, st_index_t num, struct dump_call_arg *arg)
675 {
676 struct w_ivar_arg ivarg = {arg, num};
677 if (!num) return;
678 rb_ivar_foreach(obj, w_obj_each, (st_data_t)&ivarg);
679 if (ivarg.num_ivar) {
680 rb_raise(rb_eRuntimeError, "instance variable removed from %"PRIsVALUE" instance",
681 CLASS_OF(arg->obj));
682 }
683 }
684
685 static void
686 w_ivar(st_index_t num, VALUE ivobj, VALUE encname, struct dump_call_arg *arg)
687 {
688 w_long(num, arg->arg);
689 num -= w_encoding(encname, arg);
690 if (ivobj != Qundef) {
691 w_ivar_each(ivobj, num, arg);
692 }
693 }
694
695 static void
696 w_objivar(VALUE obj, struct dump_call_arg *arg)
697 {
698 st_data_t num = 0;
699
700 rb_ivar_foreach(obj, obj_count_ivars, (st_data_t)&num);
701 w_long(num, arg->arg);
702 w_ivar_each(obj, num, arg);
703 }
704
705 static void
706 w_object(VALUE obj, struct dump_arg *arg, int limit)
707 {
708 struct dump_call_arg c_arg;
709 VALUE ivobj = Qundef;
710 st_data_t num;
711 st_index_t hasiv = 0;
712 VALUE encname = Qnil;
713
714 if (limit == 0) {
715 rb_raise(rb_eArgError, "exceed depth limit");
716 }
717
718 if (limit > 0) limit--;
719 c_arg.limit = limit;
720 c_arg.arg = arg;
721 c_arg.obj = obj;
722
723 if (st_lookup(arg->data, obj, &num)) {
724 w_byte(TYPE_LINK, arg);
725 w_long((long)num, arg);
726 return;
727 }
728
729 if (obj == Qnil) {
730 w_byte(TYPE_NIL, arg);
731 }
732 else if (obj == Qtrue) {
733 w_byte(TYPE_TRUE, arg);
734 }
735 else if (obj == Qfalse) {
736 w_byte(TYPE_FALSE, arg);
737 }
738 else if (FIXNUM_P(obj)) {
739 #if SIZEOF_LONG <= 4
740 w_byte(TYPE_FIXNUM, arg);
741 w_long(FIX2INT(obj), arg);
742 #else
743 if (RSHIFT((long)obj, 31) == 0 || RSHIFT((long)obj, 31) == -1) {
744 w_byte(TYPE_FIXNUM, arg);
745 w_long(FIX2LONG(obj), arg);
746 }
747 else {
748 w_object(rb_int2big(FIX2LONG(obj)), arg, limit);
749 }
750 #endif
751 }
752 else if (SYMBOL_P(obj)) {
753 w_symbol(obj, arg);
754 }
755 else if (FLONUM_P(obj)) {
756 st_add_direct(arg->data, obj, arg->data->num_entries);
757 w_byte(TYPE_FLOAT, arg);
758 w_float(RFLOAT_VALUE(obj), arg);
759 }
760 else {
761 VALUE v;
762
763 if (!RBASIC_CLASS(obj)) {
764 rb_raise(rb_eTypeError, "can't dump internal %s",
765 rb_builtin_type_name(BUILTIN_TYPE(obj)));
766 }
767
768 if (rb_obj_respond_to(obj, s_mdump, TRUE)) {
769 st_add_direct(arg->data, obj, arg->data->num_entries);
770
771 v = dump_funcall(arg, obj, s_mdump, 0, 0);
772 w_class(TYPE_USRMARSHAL, obj, arg, FALSE);
773 w_object(v, arg, limit);
774 return;
775 }
776 if (rb_obj_respond_to(obj, s_dump, TRUE)) {
777 VALUE ivobj2 = Qundef;
778 st_index_t hasiv2;
779 VALUE encname2;
780
781 v = INT2NUM(limit);
782 v = dump_funcall(arg, obj, s_dump, 1, &v);
783 if (!RB_TYPE_P(v, T_STRING)) {
784 rb_raise(rb_eTypeError, "_dump() must return string");
785 }
786 hasiv = has_ivars(obj, (encname = encoding_name(obj, arg)), &ivobj);
787 hasiv2 = has_ivars(v, (encname2 = encoding_name(v, arg)), &ivobj2);
788 if (hasiv2) {
789 hasiv = hasiv2;
790 ivobj = ivobj2;
791 encname = encname2;
792 }
793 if (hasiv) w_byte(TYPE_IVAR, arg);
794 w_class(TYPE_USERDEF, obj, arg, FALSE);
795 w_bytes(RSTRING_PTR(v), RSTRING_LEN(v), arg);
796 if (hasiv) {
797 w_ivar(hasiv, ivobj, encname, &c_arg);
798 }
799 st_add_direct(arg->data, obj, arg->data->num_entries);
800 return;
801 }
802
803 st_add_direct(arg->data, obj, arg->data->num_entries);
804
805 hasiv = has_ivars(obj, (encname = encoding_name(obj, arg)), &ivobj);
806 {
807 st_data_t compat_data;
808 rb_alloc_func_t allocator = rb_get_alloc_func(RBASIC(obj)->klass);
809 if (st_lookup(compat_allocator_tbl,
810 (st_data_t)allocator,
811 &compat_data)) {
812 marshal_compat_t *compat = (marshal_compat_t*)compat_data;
813 VALUE real_obj = obj;
814 obj = compat->dumper(real_obj);
815 if (!arg->compat_tbl) {
816 arg->compat_tbl = rb_init_identtable();
817 }
818 st_insert(arg->compat_tbl, (st_data_t)obj, (st_data_t)real_obj);
819 if (obj != real_obj && ivobj == Qundef) hasiv = 0;
820 }
821 }
822 if (hasiv) w_byte(TYPE_IVAR, arg);
823
824 switch (BUILTIN_TYPE(obj)) {
825 case T_CLASS:
826 if (FL_TEST(obj, FL_SINGLETON)) {
827 rb_raise(rb_eTypeError, "singleton class can't be dumped");
828 }
829 w_byte(TYPE_CLASS, arg);
830 {
831 VALUE path = class2path(obj);
832 w_bytes(RSTRING_PTR(path), RSTRING_LEN(path), arg);
833 RB_GC_GUARD(path);
834 }
835 break;
836
837 case T_MODULE:
838 w_byte(TYPE_MODULE, arg);
839 {
840 VALUE path = class2path(obj);
841 w_bytes(RSTRING_PTR(path), RSTRING_LEN(path), arg);
842 RB_GC_GUARD(path);
843 }
844 break;
845
846 case T_FLOAT:
847 w_byte(TYPE_FLOAT, arg);
848 w_float(RFLOAT_VALUE(obj), arg);
849 break;
850
851 case T_BIGNUM:
852 w_byte(TYPE_BIGNUM, arg);
853 {
854 char sign = BIGNUM_SIGN(obj) ? '+' : '-';
855 size_t len = BIGNUM_LEN(obj);
856 size_t slen;
857 size_t j;
858 BDIGIT *d = BIGNUM_DIGITS(obj);
859
860 slen = SHORTLEN(len);
861 if (LONG_MAX < slen) {
862 rb_raise(rb_eTypeError, "too big Bignum can't be dumped");
863 }
864
865 w_byte(sign, arg);
866 w_long((long)slen, arg);
867 for (j = 0; j < len; j++) {
868 #if SIZEOF_BDIGIT > SIZEOF_SHORT
869 BDIGIT num = *d;
870 int i;
871
872 for (i=0; i<SIZEOF_BDIGIT; i+=SIZEOF_SHORT) {
873 w_short(num & SHORTMASK, arg);
874 num = SHORTDN(num);
875 if (j == len - 1 && num == 0) break;
876 }
877 #else
878 w_short(*d, arg);
879 #endif
880 d++;
881 }
882 }
883 break;
884
885 case T_STRING:
886 w_uclass(obj, rb_cString, arg);
887 w_byte(TYPE_STRING, arg);
888 w_bytes(RSTRING_PTR(obj), RSTRING_LEN(obj), arg);
889 break;
890
891 case T_REGEXP:
892 w_uclass(obj, rb_cRegexp, arg);
893 w_byte(TYPE_REGEXP, arg);
894 {
895 int opts = rb_reg_options(obj);
896 w_bytes(RREGEXP_SRC_PTR(obj), RREGEXP_SRC_LEN(obj), arg);
897 w_byte((char)opts, arg);
898 }
899 break;
900
901 case T_ARRAY:
902 w_uclass(obj, rb_cArray, arg);
903 w_byte(TYPE_ARRAY, arg);
904 {
905 long i, len = RARRAY_LEN(obj);
906
907 w_long(len, arg);
908 for (i=0; i<RARRAY_LEN(obj); i++) {
909 w_object(RARRAY_AREF(obj, i), arg, limit);
910 if (len != RARRAY_LEN(obj)) {
911 rb_raise(rb_eRuntimeError, "array modified during dump");
912 }
913 }
914 }
915 break;
916
917 case T_HASH:
918 w_uclass(obj, rb_cHash, arg);
919 if (NIL_P(RHASH_IFNONE(obj))) {
920 w_byte(TYPE_HASH, arg);
921 }
922 else if (FL_TEST(obj, RHASH_PROC_DEFAULT)) {
923 rb_raise(rb_eTypeError, "can't dump hash with default proc");
924 }
925 else {
926 w_byte(TYPE_HASH_DEF, arg);
927 }
928 w_long(rb_hash_size_num(obj), arg);
929 rb_hash_foreach(obj, hash_each, (st_data_t)&c_arg);
930 if (!NIL_P(RHASH_IFNONE(obj))) {
931 w_object(RHASH_IFNONE(obj), arg, limit);
932 }
933 break;
934
935 case T_STRUCT:
936 w_class(TYPE_STRUCT, obj, arg, TRUE);
937 {
938 long len = RSTRUCT_LEN(obj);
939 VALUE mem;
940 long i;
941
942 w_long(len, arg);
943 mem = rb_struct_members(obj);
944 for (i=0; i<len; i++) {
945 w_symbol(RARRAY_AREF(mem, i), arg);
946 w_object(RSTRUCT_GET(obj, i), arg, limit);
947 }
948 }
949 break;
950
951 case T_OBJECT:
952 w_class(TYPE_OBJECT, obj, arg, TRUE);
953 w_objivar(obj, &c_arg);
954 break;
955
956 case T_DATA:
957 {
958 VALUE v;
959
960 if (!rb_obj_respond_to(obj, s_dump_data, TRUE)) {
961 rb_raise(rb_eTypeError,
962 "no _dump_data is defined for class %"PRIsVALUE,
963 rb_obj_class(obj));
964 }
965 v = dump_funcall(arg, obj, s_dump_data, 0, 0);
966 w_class(TYPE_DATA, obj, arg, TRUE);
967 w_object(v, arg, limit);
968 }
969 break;
970
971 default:
972 rb_raise(rb_eTypeError, "can't dump %"PRIsVALUE,
973 rb_obj_class(obj));
974 break;
975 }
976 RB_GC_GUARD(obj);
977 }
978 if (hasiv) {
979 w_ivar(hasiv, ivobj, encname, &c_arg);
980 }
981 }
982
983 static void
984 clear_dump_arg(struct dump_arg *arg)
985 {
986 if (!arg->symbols) return;
987 st_free_table(arg->symbols);
988 arg->symbols = 0;
989 st_free_table(arg->data);
990 arg->data = 0;
991 if (arg->compat_tbl) {
992 st_free_table(arg->compat_tbl);
993 arg->compat_tbl = 0;
994 }
995 if (arg->encodings) {
996 st_free_table(arg->encodings);
997 arg->encodings = 0;
998 }
999 }
1000
1001 NORETURN(static inline void io_needed(void));
1002 static inline void
1003 io_needed(void)
1004 {
1005 rb_raise(rb_eTypeError, "instance of IO needed");
1006 }
1007
1008 /*
1009 * call-seq:
1010 * dump( obj [, anIO] , limit=-1 ) -> anIO
1011 *
1012 * Serializes obj and all descendant objects. If anIO is
1013 * specified, the serialized data will be written to it, otherwise the
1014 * data will be returned as a String. If limit is specified, the
1015 * traversal of subobjects will be limited to that depth. If limit is
1016 * negative, no checking of depth will be performed.
1017 *
1018 * class Klass
1019 * def initialize(str)
1020 * @str = str
1021 * end
1022 * def say_hello
1023 * @str
1024 * end
1025 * end
1026 *
1027 * (produces no output)
1028 *
1029 * o = Klass.new("hello\n")
1030 * data = Marshal.dump(o)
1031 * obj = Marshal.load(data)
1032 * obj.say_hello #=> "hello\n"
1033 *
1034 * Marshal can't dump following objects:
1035 * * anonymous Class/Module.
1036 * * objects which are related to system (ex: Dir, File::Stat, IO, File, Socket
1037 * and so on)
1038 * * an instance of MatchData, Data, Method, UnboundMethod, Proc, Thread,
1039 * ThreadGroup, Continuation
1040 * * objects which define singleton methods
1041 */
1042 static VALUE
1043 marshal_dump(int argc, VALUE *argv, VALUE _)
1044 {
1045 VALUE obj, port, a1, a2;
1046 int limit = -1;
1047
1048 port = Qnil;
1049 rb_scan_args(argc, argv, "12", &obj, &a1, &a2);
1050 if (argc == 3) {
1051 if (!NIL_P(a2)) limit = NUM2INT(a2);
1052 if (NIL_P(a1)) io_needed();
1053 port = a1;
1054 }
1055 else if (argc == 2) {
1056 if (FIXNUM_P(a1)) limit = FIX2INT(a1);
1057 else if (NIL_P(a1)) io_needed();
1058 else port = a1;
1059 }
1060 return rb_marshal_dump_limited(obj, port, limit);
1061 }
1062
1063 VALUE
1064 rb_marshal_dump_limited(VALUE obj, VALUE port, int limit)
1065 {
1066 struct dump_arg *arg;
1067 VALUE wrapper; /* used to avoid memory leak in case of exception */
1068
1069 wrapper = TypedData_Make_Struct(0, struct dump_arg, &dump_arg_data, arg);
1070 arg->dest = 0;
1071 arg->symbols = st_init_numtable();
1072 arg->data = rb_init_identtable();
1073 arg->compat_tbl = 0;
1074 arg->encodings = 0;
1075 arg->str = rb_str_buf_new(0);
1076 if (!NIL_P(port)) {
1077 if (!rb_respond_to(port, s_write)) {
1078 io_needed();
1079 }
1080 arg->dest = port;
1081 dump_check_funcall(arg, port, s_binmode, 0, 0);
1082 }
1083 else {
1084 port = arg->str;
1085 }
1086
1087 w_byte(MARSHAL_MAJOR, arg);
1088 w_byte(MARSHAL_MINOR, arg);
1089
1090 w_object(obj, arg, limit);
1091 if (arg->dest) {
1092 rb_io_write(arg->dest, arg->str);
1093 rb_str_resize(arg->str, 0);
1094 }
1095 clear_dump_arg(arg);
1096 RB_GC_GUARD(wrapper);
1097
1098 return port;
1099 }
1100
1101 struct load_arg {
1102 VALUE src;
1103 char *buf;
1104 long buflen;
1105 long readable;
1106 long offset;
1107 st_table *symbols;
1108 st_table *data;
1109 VALUE proc;
1110 st_table *compat_tbl;
1111 };
1112
1113 static VALUE
1114 check_load_arg(VALUE ret, struct load_arg *arg, const char *name)
1115 {
1116 if (!arg->symbols) {
1117 rb_raise(rb_eRuntimeError, "Marshal.load reentered at %s",
1118 name);
1119 }
1120 return ret;
1121 }
1122 #define load_funcall(arg, obj, sym, argc, argv) \
1123 check_load_arg(rb_funcallv(obj, sym, argc, argv), arg, name_##sym)
1124
1125 static void clear_load_arg(struct load_arg *arg);
1126
1127 static void
1128 mark_load_arg(void *ptr)
1129 {
1130 struct load_arg *p = ptr;
1131 if (!p->symbols)
1132 return;
1133 rb_mark_tbl(p->symbols);
1134 rb_mark_tbl(p->data);
1135 rb_mark_hash(p->compat_tbl);
1136 }
1137
1138 static void
1139 free_load_arg(void *ptr)
1140 {
1141 clear_load_arg(ptr);
1142 xfree(ptr);
1143 }
1144
1145 static size_t
1146 memsize_load_arg(const void *ptr)
1147 {
1148 return sizeof(struct load_arg);
1149 }
1150
1151 static const rb_data_type_t load_arg_data = {
1152 "load_arg",
1153 {mark_load_arg, free_load_arg, memsize_load_arg,},
1154 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
1155 };
1156
1157 #define r_entry(v, arg) r_entry0((v), (arg)->data->num_entries, (arg))
1158 static VALUE r_entry0(VALUE v, st_index_t num, struct load_arg *arg);
1159 static VALUE r_object(struct load_arg *arg);
1160 static VALUE r_symbol(struct load_arg *arg);
1161 static VALUE path2class(VALUE path);
1162
1163 NORETURN(static void too_short(void));
1164 static void
1165 too_short(void)
1166 {
1167 rb_raise(rb_eArgError, "marshal data too short");
1168 }
1169
1170 static st_index_t
1171 r_prepare(struct load_arg *arg)
1172 {
1173 st_index_t idx = arg->data->num_entries;
1174
1175 st_insert(arg->data, (st_data_t)idx, (st_data_t)Qundef);
1176 return idx;
1177 }
1178
1179 static unsigned char
1180 r_byte1_buffered(struct load_arg *arg)
1181 {
1182 if (arg->buflen == 0) {
1183 long readable = arg->readable < BUFSIZ ? arg->readable : BUFSIZ;
1184 VALUE str, n = LONG2NUM(readable);
1185
1186 str = load_funcall(arg, arg->src, s_read, 1, &n);
1187 if (NIL_P(str)) too_short();
1188 StringValue(str);
1189 memcpy(arg->buf, RSTRING_PTR(str), RSTRING_LEN(str));
1190 arg->offset = 0;
1191 arg->buflen = RSTRING_LEN(str);
1192 }
1193 arg->buflen--;
1194 return arg->buf[arg->offset++];
1195 }
1196
1197 static int
1198 r_byte(struct load_arg *arg)
1199 {
1200 int c;
1201
1202 if (RB_TYPE_P(arg->src, T_STRING)) {
1203 if (RSTRING_LEN(arg->src) > arg->offset) {
1204 c = (unsigned char)RSTRING_PTR(arg->src)[arg->offset++];
1205 }
1206 else {
1207 too_short();
1208 }
1209 }
1210 else {
1211 if (arg->readable >0 || arg->buflen > 0) {
1212 c = r_byte1_buffered(arg);
1213 }
1214 else {
1215 VALUE v = load_funcall(arg, arg->src, s_getbyte, 0, 0);
1216 if (NIL_P(v)) rb_eof_error();
1217 c = (unsigned char)NUM2CHR(v);
1218 }
1219 }
1220 return c;
1221 }
1222
1223 NORETURN(static void long_toobig(int size));
1224
1225 static void
1226 long_toobig(int size)
1227 {
1228 rb_raise(rb_eTypeError, "long too big for this architecture (size "
1229 STRINGIZE(SIZEOF_LONG)", given %d)", size);
1230 }
1231
1232 static long
1233 r_long(struct load_arg *arg)
1234 {
1235 register long x;
1236 int c = (signed char)r_byte(arg);
1237 long i;
1238
1239 if (c == 0) return 0;
1240 if (c > 0) {
1241 if (4 < c && c < 128) {
1242 return c - 5;
1243 }
1244 if (c > (int)sizeof(long)) long_toobig(c);
1245 x = 0;
1246 for (i=0;i<c;i++) {
1247 x |= (long)r_byte(arg) << (8*i);
1248 }
1249 }
1250 else {
1251 if (-129 < c && c < -4) {
1252 return c + 5;
1253 }
1254 c = -c;
1255 if (c > (int)sizeof(long)) long_toobig(c);
1256 x = -1;
1257 for (i=0;i<c;i++) {
1258 x &= ~((long)0xff << (8*i));
1259 x |= (long)r_byte(arg) << (8*i);
1260 }
1261 }
1262 return x;
1263 }
1264
1265 long
1266 ruby_marshal_read_long(const char **buf, long len)
1267 {
1268 long x;
1269 struct RString src;
1270 struct load_arg arg;
1271 memset(&arg, 0, sizeof(arg));
1272 arg.src = rb_setup_fake_str(&src, *buf, len, 0);
1273 x = r_long(&arg);
1274 *buf += arg.offset;
1275 return x;
1276 }
1277
1278 static VALUE
1279 r_bytes1(long len, struct load_arg *arg)
1280 {
1281 VALUE str, n = LONG2NUM(len);
1282
1283 str = load_funcall(arg, arg->src, s_read, 1, &n);
1284 if (NIL_P(str)) too_short();
1285 StringValue(str);
1286 if (RSTRING_LEN(str) != len) too_short();
1287
1288 return str;
1289 }
1290
1291 static VALUE
1292 r_bytes1_buffered(long len, struct load_arg *arg)
1293 {
1294 VALUE str;
1295
1296 if (len <= arg->buflen) {
1297 str = rb_str_new(arg->buf+arg->offset, len);
1298 arg->offset += len;
1299 arg->buflen -= len;
1300 }
1301 else {
1302 long buflen = arg->buflen;
1303 long readable = arg->readable + 1;
1304 long tmp_len, read_len, need_len = len - buflen;
1305 VALUE tmp, n;
1306
1307 readable = readable < BUFSIZ ? readable : BUFSIZ;
1308 read_len = need_len > readable ? need_len : readable;
1309 n = LONG2NUM(read_len);
1310 tmp = load_funcall(arg, arg->src, s_read, 1, &n);
1311 if (NIL_P(tmp)) too_short();
1312 StringValue(tmp);
1313
1314 tmp_len = RSTRING_LEN(tmp);
1315
1316 if (tmp_len < need_len) too_short();
1317
1318 str = rb_str_new(arg->buf+arg->offset, buflen);
1319 rb_str_cat(str, RSTRING_PTR(tmp), need_len);
1320
1321 if (tmp_len > need_len) {
1322 buflen = tmp_len - need_len;
1323 memcpy(arg->buf, RSTRING_PTR(tmp)+need_len, buflen);
1324 arg->buflen = buflen;
1325 }
1326 else {
1327 arg->buflen = 0;
1328 }
1329 arg->offset = 0;
1330 }
1331
1332 return str;
1333 }
1334
1335 #define r_bytes(arg) r_bytes0(r_long(arg), (arg))
1336
1337 static VALUE
1338 r_bytes0(long len, struct load_arg *arg)
1339 {
1340 VALUE str;
1341
1342 if (len == 0) return rb_str_new(0, 0);
1343 if (RB_TYPE_P(arg->src, T_STRING)) {
1344 if (RSTRING_LEN(arg->src) - arg->offset >= len) {
1345 str = rb_str_new(RSTRING_PTR(arg->src)+arg->offset, len);
1346 arg->offset += len;
1347 }
1348 else {
1349 too_short();
1350 }
1351 }
1352 else {
1353 if (arg->readable > 0 || arg->buflen > 0) {
1354 str = r_bytes1_buffered(len, arg);
1355 }
1356 else {
1357 str = r_bytes1(len, arg);
1358 }
1359 }
1360 return str;
1361 }
1362
1363 static int
1364 sym2encidx(VALUE sym, VALUE val)
1365 {
1366 static const char name_encoding[8] = "encoding";
1367 const char *p;
1368 long l;
1369 if (rb_enc_get_index(sym) != ENCINDEX_US_ASCII) return -1;
1370 RSTRING_GETMEM(sym, p, l);
1371 if (l <= 0) return -1;
1372 if (l == sizeof(name_encoding) &&
1373 memcmp(p, name_encoding, sizeof(name_encoding)) == 0) {
1374 int idx = rb_enc_find_index(StringValueCStr(val));
1375 return idx;
1376 }
1377 else if (l == 1 && *p == 'E') {
1378 if (val == Qfalse) return rb_usascii_encindex();
1379 else if (val == Qtrue) return rb_utf8_encindex();
1380 /* bogus ignore */
1381 }
1382 return -1;
1383 }
1384
1385 static VALUE
1386 r_symlink(struct load_arg *arg)
1387 {
1388 st_data_t sym;
1389 long num = r_long(arg);
1390
1391 if (!st_lookup(arg->symbols, num, &sym)) {
1392 rb_raise(rb_eArgError, "bad symbol");
1393 }
1394 return (VALUE)sym;
1395 }
1396
1397 static VALUE
1398 r_symreal(struct load_arg *arg, int ivar)
1399 {
1400 VALUE s = r_bytes(arg);
1401 VALUE sym;
1402 int idx = -1;
1403 st_index_t n = arg->symbols->num_entries;
1404
1405 if (rb_enc_str_asciionly_p(s)) rb_enc_associate_index(s, ENCINDEX_US_ASCII);
1406 st_insert(arg->symbols, (st_data_t)n, (st_data_t)s);
1407 if (ivar) {
1408 long num = r_long(arg);
1409 while (num-- > 0) {
1410 sym = r_symbol(arg);
1411 idx = sym2encidx(sym, r_object(arg));
1412 }
1413 }
1414 if (idx > 0) rb_enc_associate_index(s, idx);
1415
1416 return s;
1417 }
1418
1419 static VALUE
1420 r_symbol(struct load_arg *arg)
1421 {
1422 int type, ivar = 0;
1423
1424 again:
1425 switch ((type = r_byte(arg))) {
1426 default:
1427 rb_raise(rb_eArgError, "dump format error for symbol(0x%x)", type);
1428 case TYPE_IVAR:
1429 ivar = 1;
1430 goto again;
1431 case TYPE_SYMBOL:
1432 return r_symreal(arg, ivar);
1433 case TYPE_SYMLINK:
1434 if (ivar) {
1435 rb_raise(rb_eArgError, "dump format error (symlink with encoding)");
1436 }
1437 return r_symlink(arg);
1438 }
1439 }
1440
1441 static VALUE
1442 r_unique(struct load_arg *arg)
1443 {
1444 return r_symbol(arg);
1445 }
1446
1447 static VALUE
1448 r_string(struct load_arg *arg)
1449 {
1450 return r_bytes(arg);
1451 }
1452
1453 static VALUE
1454 r_entry0(VALUE v, st_index_t num, struct load_arg *arg)
1455 {
1456 st_data_t real_obj = (VALUE)Qundef;
1457 if (arg->compat_tbl && st_lookup(arg->compat_tbl, v, &real_obj)) {
1458 st_insert(arg->data, num, (st_data_t)real_obj);
1459 }
1460 else {
1461 st_insert(arg->data, num, (st_data_t)v);
1462 }
1463 return v;
1464 }
1465
1466 static VALUE
1467 r_fixup_compat(VALUE v, struct load_arg *arg)
1468 {
1469 st_data_t data;
1470 st_data_t key = (st_data_t)v;
1471 if (arg->compat_tbl && st_delete(arg->compat_tbl, &key, &data)) {
1472 VALUE real_obj = (VALUE)data;
1473 rb_alloc_func_t allocator = rb_get_alloc_func(CLASS_OF(real_obj));
1474 if (st_lookup(compat_allocator_tbl, (st_data_t)allocator, &data)) {
1475 marshal_compat_t *compat = (marshal_compat_t*)data;
1476 compat->loader(real_obj, v);
1477 }
1478 v = real_obj;
1479 }
1480 return v;
1481 }
1482
1483 static VALUE
1484 r_post_proc(VALUE v, struct load_arg *arg)
1485 {
1486 if (arg->proc) {
1487 v = load_funcall(arg, arg->proc, s_call, 1, &v);
1488 }
1489 return v;
1490 }
1491
1492 static VALUE
1493 r_leave(VALUE v, struct load_arg *arg)
1494 {
1495 v = r_fixup_compat(v, arg);
1496 v = r_post_proc(v, arg);
1497 return v;
1498 }
1499
1500 static int
1501 copy_ivar_i(st_data_t key, st_data_t val, st_data_t arg)
1502 {
1503 VALUE obj = (VALUE)arg, value = (VALUE)val;
1504 ID vid = (ID)key;
1505
1506 if (!rb_ivar_defined(obj, vid))
1507 rb_ivar_set(obj, vid, value);
1508 return ST_CONTINUE;
1509 }
1510
1511 static VALUE
1512 r_copy_ivar(VALUE v, VALUE data)
1513 {
1514 rb_ivar_foreach(data, copy_ivar_i, (st_data_t)v);
1515 return v;
1516 }
1517
1518 static void
1519 r_ivar(VALUE obj, int *has_encoding, struct load_arg *arg)
1520 {
1521 long len;
1522
1523 len = r_long(arg);
1524 if (len > 0) {
1525 do {
1526 VALUE sym = r_symbol(arg);
1527 VALUE val = r_object(arg);
1528 int idx = sym2encidx(sym, val);
1529 if (idx >= 0) {
1530 if (rb_enc_capable(obj)) {
1531 rb_enc_associate_index(obj, idx);
1532 }
1533 else {
1534 rb_raise(rb_eArgError, "%"PRIsVALUE" is not enc_capable", obj);
1535 }
1536 if (has_encoding) *has_encoding = TRUE;
1537 }
1538 else {
1539 rb_ivar_set(obj, rb_intern_str(sym), val);
1540 }
1541 } while (--len > 0);
1542 }
1543 }
1544
1545 static VALUE
1546 path2class(VALUE path)
1547 {
1548 VALUE v = rb_path_to_class(path);
1549
1550 if (!RB_TYPE_P(v, T_CLASS)) {
1551 rb_raise(rb_eArgError, "%"PRIsVALUE" does not refer to class", path);
1552 }
1553 return v;
1554 }
1555
1556 #define path2module(path) must_be_module(rb_path_to_class(path), path)
1557
1558 static VALUE
1559 must_be_module(VALUE v, VALUE path)
1560 {
1561 if (!RB_TYPE_P(v, T_MODULE)) {
1562 rb_raise(rb_eArgError, "%"PRIsVALUE" does not refer to module", path);
1563 }
1564 return v;
1565 }
1566
1567 static VALUE
1568 obj_alloc_by_klass(VALUE klass, struct load_arg *arg, VALUE *oldclass)
1569 {
1570 st_data_t data;
1571 rb_alloc_func_t allocator;
1572
1573 allocator = rb_get_alloc_func(klass);
1574 if (st_lookup(compat_allocator_tbl, (st_data_t)allocator, &data)) {
1575 marshal_compat_t *compat = (marshal_compat_t*)data;
1576 VALUE real_obj = rb_obj_alloc(klass);
1577 VALUE obj = rb_obj_alloc(compat->oldclass);
1578 if (oldclass) *oldclass = compat->oldclass;
1579
1580 if (!arg->compat_tbl) {
1581 arg->compat_tbl = rb_init_identtable();
1582 }
1583 st_insert(arg->compat_tbl, (st_data_t)obj, (st_data_t)real_obj);
1584 return obj;
1585 }
1586
1587 return rb_obj_alloc(klass);
1588 }
1589
1590 static VALUE
1591 obj_alloc_by_path(VALUE path, struct load_arg *arg)
1592 {
1593 return obj_alloc_by_klass(path2class(path), arg, 0);
1594 }
1595
1596 static VALUE
1597 append_extmod(VALUE obj, VALUE extmod)
1598 {
1599 long i = RARRAY_LEN(extmod);
1600 while (i > 0) {
1601 VALUE m = RARRAY_AREF(extmod, --i);
1602 rb_extend_object(obj, m);
1603 }
1604 return obj;
1605 }
1606
1607 #define prohibit_ivar(type, str) do { \
1608 if (!ivp || !*ivp) break; \
1609 rb_raise(rb_eTypeError, \
1610 "can't override instance variable of "type" `%"PRIsVALUE"'", \
1611 (str)); \
1612 } while (0)
1613
1614 static VALUE
1615 r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
1616 {
1617 VALUE v = Qnil;
1618 int type = r_byte(arg);
1619 long id;
1620 st_data_t link;
1621
1622 switch (type) {
1623 case TYPE_LINK:
1624 id = r_long(arg);
1625 if (!st_lookup(arg->data, (st_data_t)id, &link)) {
1626 rb_raise(rb_eArgError, "dump format error (unlinked)");
1627 }
1628 v = (VALUE)link;
1629 v = r_post_proc(v, arg);
1630 break;
1631
1632 case TYPE_IVAR:
1633 {
1634 int ivar = TRUE;
1635
1636 v = r_object0(arg, &ivar, extmod);
1637 if (ivar) r_ivar(v, NULL, arg);
1638 }
1639 break;
1640
1641 case TYPE_EXTENDED:
1642 {
1643 VALUE path = r_unique(arg);
1644 VALUE m = rb_path_to_class(path);
1645 if (NIL_P(extmod)) extmod = rb_ary_tmp_new(0);
1646
1647 if (RB_TYPE_P(m, T_CLASS)) { /* prepended */
1648 VALUE c;
1649
1650 v = r_object0(arg, 0, Qnil);
1651 c = CLASS_OF(v);
1652 if (c != m || FL_TEST(c, FL_SINGLETON)) {
1653 rb_raise(rb_eArgError,
1654 "prepended class %"PRIsVALUE" differs from class %"PRIsVALUE,
1655 path, rb_class_name(c));
1656 }
1657 c = rb_singleton_class(v);
1658 while (RARRAY_LEN(extmod) > 0) {
1659 m = rb_ary_pop(extmod);
1660 rb_prepend_module(c, m);
1661 }
1662 }
1663 else {
1664 must_be_module(m, path);
1665 rb_ary_push(extmod, m);
1666
1667 v = r_object0(arg, 0, extmod);
1668 while (RARRAY_LEN(extmod) > 0) {
1669 m = rb_ary_pop(extmod);
1670 rb_extend_object(v, m);
1671 }
1672 }
1673 }
1674 break;
1675
1676 case TYPE_UCLASS:
1677 {
1678 VALUE c = path2class(r_unique(arg));
1679
1680 if (FL_TEST(c, FL_SINGLETON)) {
1681 rb_raise(rb_eTypeError, "singleton can't be loaded");
1682 }
1683 v = r_object0(arg, 0, extmod);
1684 if (rb_special_const_p(v) || RB_TYPE_P(v, T_OBJECT) || RB_TYPE_P(v, T_CLASS)) {
1685 format_error:
1686 rb_raise(rb_eArgError, "dump format error (user class)");
1687 }
1688 if (RB_TYPE_P(v, T_MODULE) || !RTEST(rb_class_inherited_p(c, RBASIC(v)->klass))) {
1689 VALUE tmp = rb_obj_alloc(c);
1690
1691 if (TYPE(v) != TYPE(tmp)) goto format_error;
1692 }
1693 RBASIC_SET_CLASS(v, c);
1694 }
1695 break;
1696
1697 case TYPE_NIL:
1698 v = Qnil;
1699 v = r_leave(v, arg);
1700 break;
1701
1702 case TYPE_TRUE:
1703 v = Qtrue;
1704 v = r_leave(v, arg);
1705 break;
1706
1707 case TYPE_FALSE:
1708 v = Qfalse;
1709 v = r_leave(v, arg);
1710 break;
1711
1712 case TYPE_FIXNUM:
1713 {
1714 long i = r_long(arg);
1715 v = LONG2FIX(i);
1716 }
1717 v = r_leave(v, arg);
1718 break;
1719
1720 case TYPE_FLOAT:
1721 {
1722 double d;
1723 VALUE str = r_bytes(arg);
1724 const char *ptr = RSTRING_PTR(str);
1725
1726 if (strcmp(ptr, "nan") == 0) {
1727 d = nan("");
1728 }
1729 else if (strcmp(ptr, "inf") == 0) {
1730 d = HUGE_VAL;
1731 }
1732 else if (strcmp(ptr, "-inf") == 0) {
1733 d = -HUGE_VAL;
1734 }
1735 else {
1736 char *e;
1737 d = strtod(ptr, &e);
1738 d = load_mantissa(d, e, RSTRING_LEN(str) - (e - ptr));
1739 }
1740 v = DBL2NUM(d);
1741 v = r_entry(v, arg);
1742 v = r_leave(v, arg);
1743 }
1744 break;
1745
1746 case TYPE_BIGNUM:
1747 {
1748 long len;
1749 VALUE data;
1750 int sign;
1751
1752 sign = r_byte(arg);
1753 len = r_long(arg);
1754 data = r_bytes0(len * 2, arg);
1755 v = rb_integer_unpack(RSTRING_PTR(data), len, 2, 0,
1756 INTEGER_PACK_LITTLE_ENDIAN | (sign == '-' ? INTEGER_PACK_NEGATIVE : 0));
1757 rb_str_resize(data, 0L);
1758 v = r_entry(v, arg);
1759 v = r_leave(v, arg);
1760 }
1761 break;
1762
1763 case TYPE_STRING:
1764 v = r_entry(r_string(arg), arg);
1765 v = r_leave(v, arg);
1766 break;
1767
1768 case TYPE_REGEXP:
1769 {
1770 VALUE str = r_bytes(arg);
1771 int options = r_byte(arg);
1772 int has_encoding = FALSE;
1773 st_index_t idx = r_prepare(arg);
1774
1775 if (ivp) {
1776 r_ivar(str, &has_encoding, arg);
1777 *ivp = FALSE;
1778 }
1779 if (!has_encoding) {
1780 /* 1.8 compatibility; remove escapes undefined in 1.8 */
1781 char *ptr = RSTRING_PTR(str), *dst = ptr, *src = ptr;
1782 long len = RSTRING_LEN(str);
1783 long bs = 0;
1784 for (; len-- > 0; *dst++ = *src++) {
1785 switch (*src) {
1786 case '\\': bs++; break;
1787 case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
1788 case 'm': case 'o': case 'p': case 'q': case 'u': case 'y':
1789 case 'E': case 'F': case 'H': case 'I': case 'J': case 'K':
1790 case 'L': case 'N': case 'O': case 'P': case 'Q': case 'R':
1791 case 'S': case 'T': case 'U': case 'V': case 'X': case 'Y':
1792 if (bs & 1) --dst;
1793 /* fall through */
1794 default: bs = 0; break;
1795 }
1796 }
1797 rb_str_set_len(str, dst - ptr);
1798 }
1799 v = r_entry0(rb_reg_new_str(str, options), idx, arg);
1800 v = r_leave(v, arg);
1801 }
1802 break;
1803
1804 case TYPE_ARRAY:
1805 {
1806 long len = r_long(arg);
1807
1808 v = rb_ary_new2(len);
1809 v = r_entry(v, arg);
1810 arg->readable += len - 1;
1811 while (len--) {
1812 rb_ary_push(v, r_object(arg));
1813 arg->readable--;
1814 }
1815 v = r_leave(v, arg);
1816 arg->readable++;
1817 }
1818 break;
1819
1820 case TYPE_HASH:
1821 case TYPE_HASH_DEF:
1822 {
1823 long len = r_long(arg);
1824
1825 v = rb_hash_new_with_size(len);
1826 v = r_entry(v, arg);
1827 arg->readable += (len - 1) * 2;
1828 while (len--) {
1829 VALUE key = r_object(arg);
1830 VALUE value = r_object(arg);
1831 rb_hash_aset(v, key, value);
1832 arg->readable -= 2;
1833 }
1834 arg->readable += 2;
1835 if (type == TYPE_HASH_DEF) {
1836 RHASH_SET_IFNONE(v, r_object(arg));
1837 }
1838 v = r_leave(v, arg);
1839 }
1840 break;
1841
1842 case TYPE_STRUCT:
1843 {
1844 VALUE mem, values;
1845 long i;
1846 VALUE slot;
1847 st_index_t idx = r_prepare(arg);
1848 VALUE klass = path2class(r_unique(arg));
1849 long len = r_long(arg);
1850
1851 v = rb_obj_alloc(klass);
1852 if (!RB_TYPE_P(v, T_STRUCT)) {
1853 rb_raise(rb_eTypeError, "class %"PRIsVALUE" not a struct", rb_class_name(klass));
1854 }
1855 mem = rb_struct_s_members(klass);
1856 if (RARRAY_LEN(mem) != len) {
1857 rb_raise(rb_eTypeError, "struct %"PRIsVALUE" not compatible (struct size differs)",
1858 rb_class_name(klass));
1859 }
1860
1861 arg->readable += (len - 1) * 2;
1862 v = r_entry0(v, idx, arg);
1863 values = rb_ary_new2(len);
1864 {
1865 VALUE keywords = Qfalse;
1866 if (RTEST(rb_struct_s_keyword_init(klass))) {
1867 keywords = rb_hash_new();
1868 rb_ary_push(values, keywords);
1869 }
1870
1871 for (i=0; i<len; i++) {
1872 VALUE n = rb_sym2str(RARRAY_AREF(mem, i));
1873 slot = r_symbol(arg);
1874
1875 if (!rb_str_equal(n, slot)) {
1876 rb_raise(rb_eTypeError, "struct %"PRIsVALUE" not compatible (:%"PRIsVALUE" for :%"PRIsVALUE")",
1877 rb_class_name(klass),
1878 slot, n);
1879 }
1880 if (keywords) {
1881 rb_hash_aset(keywords, RARRAY_AREF(mem, i), r_object(arg));
1882 }
1883 else {
1884 rb_ary_push(values, r_object(arg));
1885 }
1886 arg->readable -= 2;
1887 }
1888 }
1889 rb_struct_initialize(v, values);
1890 v = r_leave(v, arg);
1891 arg->readable += 2;
1892 }
1893 break;
1894
1895 case TYPE_USERDEF:
1896 {
1897 VALUE name = r_unique(arg);
1898 VALUE klass = path2class(name);
1899 VALUE data;
1900 st_data_t d;
1901
1902 if (!rb_obj_respond_to(klass, s_load, TRUE)) {
1903 rb_raise(rb_eTypeError, "class %"PRIsVALUE" needs to have method `_load'",
1904 name);
1905 }
1906 data = r_string(arg);
1907 if (ivp) {
1908 r_ivar(data, NULL, arg);
1909 *ivp = FALSE;
1910 }
1911 v = load_funcall(arg, klass, s_load, 1, &data);
1912 v = r_entry(v, arg);
1913 if (st_lookup(compat_allocator_tbl, (st_data_t)rb_get_alloc_func(klass), &d)) {
1914 marshal_compat_t *compat = (marshal_compat_t*)d;
1915 v = compat->loader(klass, v);
1916 }
1917 v = r_post_proc(v, arg);
1918 }
1919 break;
1920
1921 case TYPE_USRMARSHAL:
1922 {
1923 VALUE name = r_unique(arg);
1924 VALUE klass = path2class(name);
1925 VALUE oldclass = 0;
1926 VALUE data;
1927
1928 v = obj_alloc_by_klass(klass, arg, &oldclass);
1929 if (!NIL_P(extmod)) {
1930 /* for the case marshal_load is overridden */
1931 append_extmod(v, extmod);
1932 }
1933 if (!rb_obj_respond_to(v, s_mload, TRUE)) {
1934 rb_raise(rb_eTypeError, "instance of %"PRIsVALUE" needs to have method `marshal_load'",
1935 name);
1936 }
1937 v = r_entry(v, arg);
1938 data = r_object(arg);
1939 load_funcall(arg, v, s_mload, 1, &data);
1940 v = r_fixup_compat(v, arg);
1941 v = r_copy_ivar(v, data);
1942 v = r_post_proc(v, arg);
1943 if (!NIL_P(extmod)) {
1944 if (oldclass) append_extmod(v, extmod);
1945 rb_ary_clear(extmod);
1946 }
1947 }
1948 break;
1949
1950 case TYPE_OBJECT:
1951 {
1952 st_index_t idx = r_prepare(arg);
1953 v = obj_alloc_by_path(r_unique(arg), arg);
1954 if (!RB_TYPE_P(v, T_OBJECT)) {
1955 rb_raise(rb_eArgError, "dump format error");
1956 }
1957 v = r_entry0(v, idx, arg);
1958 r_ivar(v, NULL, arg);
1959 v = r_leave(v, arg);
1960 }
1961 break;
1962
1963 case TYPE_DATA:
1964 {
1965 VALUE name = r_unique(arg);
1966 VALUE klass = path2class(name);
1967 VALUE oldclass = 0;
1968 VALUE r;
1969
1970 v = obj_alloc_by_klass(klass, arg, &oldclass);
1971 if (!RB_TYPE_P(v, T_DATA)) {
1972 rb_raise(rb_eArgError, "dump format error");
1973 }
1974 v = r_entry(v, arg);
1975 if (!rb_obj_respond_to(v, s_load_data, TRUE)) {
1976 rb_raise(rb_eTypeError,
1977 "class %"PRIsVALUE" needs to have instance method `_load_data'",
1978 name);
1979 }
1980 r = r_object0(arg, 0, extmod);
1981 load_funcall(arg, v, s_load_data, 1, &r);
1982 v = r_leave(v, arg);
1983 }
1984 break;
1985
1986 case TYPE_MODULE_OLD:
1987 {
1988 VALUE str = r_bytes(arg);
1989
1990 v = rb_path_to_class(str);
1991 prohibit_ivar("class/module", str);
1992 v = r_entry(v, arg);
1993 v = r_leave(v, arg);
1994 }
1995 break;
1996
1997 case TYPE_CLASS:
1998 {
1999 VALUE str = r_bytes(arg);
2000
2001 v = path2class(str);
2002 prohibit_ivar("class", str);
2003 v = r_entry(v, arg);
2004 v = r_leave(v, arg);
2005 }
2006 break;
2007
2008 case TYPE_MODULE:
2009 {
2010 VALUE str = r_bytes(arg);
2011
2012 v = path2module(str);
2013 prohibit_ivar("module", str);
2014 v = r_entry(v, arg);
2015 v = r_leave(v, arg);
2016 }
2017 break;
2018
2019 case TYPE_SYMBOL:
2020 if (ivp) {
2021 v = r_symreal(arg, *ivp);
2022 *ivp = FALSE;
2023 }
2024 else {
2025 v = r_symreal(arg, 0);
2026 }
2027 v = rb_str_intern(v);
2028 v = r_leave(v, arg);
2029 break;
2030
2031 case TYPE_SYMLINK:
2032 v = rb_str_intern(r_symlink(arg));
2033 break;
2034
2035 default:
2036 rb_raise(rb_eArgError, "dump format error(0x%x)", type);
2037 break;
2038 }
2039
2040 if (v == Qundef) {
2041 rb_raise(rb_eArgError, "dump format error (bad link)");
2042 }
2043
2044 return v;
2045 }
2046
2047 static VALUE
2048 r_object(struct load_arg *arg)
2049 {
2050 return r_object0(arg, 0, Qnil);
2051 }
2052
2053 static void
2054 clear_load_arg(struct load_arg *arg)
2055 {
2056 if (arg->buf) {
2057 xfree(arg->buf);
2058 arg->buf = 0;
2059 }
2060 arg->buflen = 0;
2061 arg->offset = 0;
2062 arg->readable = 0;
2063 if (!arg->symbols) return;
2064 st_free_table(arg->symbols);
2065 arg->symbols = 0;
2066 st_free_table(arg->data);
2067 arg->data = 0;
2068 if (arg->compat_tbl) {
2069 st_free_table(arg->compat_tbl);
2070 arg->compat_tbl = 0;
2071 }
2072 }
2073
2074 /*
2075 * call-seq:
2076 * load( source [, proc] ) -> obj
2077 * restore( source [, proc] ) -> obj
2078 *
2079 * Returns the result of converting the serialized data in source into a
2080 * Ruby object (possibly with associated subordinate objects). source
2081 * may be either an instance of IO or an object that responds to
2082 * to_str. If proc is specified, each object will be passed to the proc, as the object
2083 * is being deserialized.
2084 *
2085 * Never pass untrusted data (including user supplied input) to this method.
2086 * Please see the overview for further details.
2087 */
2088 static VALUE
2089 marshal_load(int argc, VALUE *argv, VALUE _)
2090 {
2091 VALUE port, proc;
2092
2093 rb_check_arity(argc, 1, 2);
2094 port = argv[0];
2095 proc = argc > 1 ? argv[1] : Qnil;
2096 return rb_marshal_load_with_proc(port, proc);
2097 }
2098
2099 VALUE
2100 rb_marshal_load_with_proc(VALUE port, VALUE proc)
2101 {
2102 int major, minor;
2103 VALUE v;
2104 VALUE wrapper; /* used to avoid memory leak in case of exception */
2105 struct load_arg *arg;
2106
2107 v = rb_check_string_type(port);
2108 if (!NIL_P(v)) {
2109 port = v;
2110 }
2111 else if (rb_respond_to(port, s_getbyte) && rb_respond_to(port, s_read)) {
2112 rb_check_funcall(port, s_binmode, 0, 0);
2113 }
2114 else {
2115 io_needed();
2116 }
2117 wrapper = TypedData_Make_Struct(0, struct load_arg, &load_arg_data, arg);
2118 arg->src = port;
2119 arg->offset = 0;
2120 arg->symbols = st_init_numtable();
2121 arg->data = rb_init_identtable();
2122 arg->compat_tbl = 0;
2123 arg->proc = 0;
2124 arg->readable = 0;
2125
2126 if (NIL_P(v))
2127 arg->buf = xmalloc(BUFSIZ);
2128 else
2129 arg->buf = 0;
2130
2131 major = r_byte(arg);
2132 minor = r_byte(arg);
2133 if (major != MARSHAL_MAJOR || minor > MARSHAL_MINOR) {
2134 clear_load_arg(arg);
2135 rb_raise(rb_eTypeError, "incompatible marshal file format (can't be read)\n\
2136 \tformat version %d.%d required; %d.%d given",
2137 MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
2138 }
2139 if (RTEST(ruby_verbose) && minor != MARSHAL_MINOR) {
2140 rb_warn("incompatible marshal file format (can be read)\n\
2141 \tformat version %d.%d required; %d.%d given",
2142 MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
2143 }
2144
2145 if (!NIL_P(proc)) arg->proc = proc;
2146 v = r_object(arg);
2147 clear_load_arg(arg);
2148 RB_GC_GUARD(wrapper);
2149
2150 return v;
2151 }
2152
2153 /*
2154 * The marshaling library converts collections of Ruby objects into a
2155 * byte stream, allowing them to be stored outside the currently
2156 * active script. This data may subsequently be read and the original
2157 * objects reconstituted.
2158 *
2159 * Marshaled data has major and minor version numbers stored along
2160 * with the object information. In normal use, marshaling can only
2161 * load data written with the same major version number and an equal
2162 * or lower minor version number. If Ruby's ``verbose'' flag is set
2163 * (normally using -d, -v, -w, or --verbose) the major and minor
2164 * numbers must match exactly. Marshal versioning is independent of
2165 * Ruby's version numbers. You can extract the version by reading the
2166 * first two bytes of marshaled data.
2167 *
2168 * str = Marshal.dump("thing")
2169 * RUBY_VERSION #=> "1.9.0"
2170 * str[0].ord #=> 4
2171 * str[1].ord #=> 8
2172 *
2173 * Some objects cannot be dumped: if the objects to be dumped include
2174 * bindings, procedure or method objects, instances of class IO, or
2175 * singleton objects, a TypeError will be raised.
2176 *
2177 * If your class has special serialization needs (for example, if you
2178 * want to serialize in some specific format), or if it contains
2179 * objects that would otherwise not be serializable, you can implement
2180 * your own serialization strategy.
2181 *
2182 * There are two methods of doing this, your object can define either
2183 * marshal_dump and marshal_load or _dump and _load. marshal_dump will take
2184 * precedence over _dump if both are defined. marshal_dump may result in
2185 * smaller Marshal strings.
2186 *
2187 * == Security considerations
2188 *
2189 * By design, Marshal.load can deserialize almost any class loaded into the
2190 * Ruby process. In many cases this can lead to remote code execution if the
2191 * Marshal data is loaded from an untrusted source.
2192 *
2193 * As a result, Marshal.load is not suitable as a general purpose serialization
2194 * format and you should never unmarshal user supplied input or other untrusted
2195 * data.
2196 *
2197 * If you need to deserialize untrusted data, use JSON or another serialization
2198 * format that is only able to load simple, 'primitive' types such as String,
2199 * Array, Hash, etc. Never allow user input to specify arbitrary types to
2200 * deserialize into.
2201 *
2202 * == marshal_dump and marshal_load
2203 *
2204 * When dumping an object the method marshal_dump will be called.
2205 * marshal_dump must return a result containing the information necessary for
2206 * marshal_load to reconstitute the object. The result can be any object.
2207 *
2208 * When loading an object dumped using marshal_dump the object is first
2209 * allocated then marshal_load is called with the result from marshal_dump.
2210 * marshal_load must recreate the object from the information in the result.
2211 *
2212 * Example:
2213 *
2214 * class MyObj
2215 * def initialize name, version, data
2216 * @name = name
2217 * @version = version
2218 * @data = data
2219 * end
2220 *
2221 * def marshal_dump
2222 * [@name, @version]
2223 * end
2224 *
2225 * def marshal_load array
2226 * @name, @version = array
2227 * end
2228 * end
2229 *
2230 * == _dump and _load
2231 *
2232 * Use _dump and _load when you need to allocate the object you're restoring
2233 * yourself.
2234 *
2235 * When dumping an object the instance method _dump is called with an Integer
2236 * which indicates the maximum depth of objects to dump (a value of -1 implies
2237 * that you should disable depth checking). _dump must return a String
2238 * containing the information necessary to reconstitute the object.
2239 *
2240 * The class method _load should take a String and use it to return an object
2241 * of the same class.
2242 *
2243 * Example:
2244 *
2245 * class MyObj
2246 * def initialize name, version, data
2247 * @name = name
2248 * @version = version
2249 * @data = data
2250 * end
2251 *
2252 * def _dump level
2253 * [@name, @version].join ':'
2254 * end
2255 *
2256 * def self._load args
2257 * new(*args.split(':'))
2258 * end
2259 * end
2260 *
2261 * Since Marshal.dump outputs a string you can have _dump return a Marshal
2262 * string which is Marshal.loaded in _load for complex objects.
2263 */
2264 void
2265 Init_marshal(void)
2266 {
2267 #undef rb_intern
2268 #define rb_intern(str) rb_intern_const(str)
2269
2270 VALUE rb_mMarshal = rb_define_module("Marshal");
2271 #define set_id(sym) sym = rb_intern_const(name_##sym)
2272 set_id(s_dump);
2273 set_id(s_load);
2274 set_id(s_mdump);
2275 set_id(s_mload);
2276 set_id(s_dump_data);
2277 set_id(s_load_data);
2278 set_id(s_alloc);
2279 set_id(s_call);
2280 set_id(s_getbyte);
2281 set_id(s_read);
2282 set_id(s_write);
2283 set_id(s_binmode);
2284 set_id(s_encoding_short);
2285
2286 rb_define_module_function(rb_mMarshal, "dump", marshal_dump, -1);
2287 rb_define_module_function(rb_mMarshal, "load", marshal_load, -1);
2288 rb_define_module_function(rb_mMarshal, "restore", marshal_load, -1);
2289
2290 /* major version */
2291 rb_define_const(rb_mMarshal, "MAJOR_VERSION", INT2FIX(MARSHAL_MAJOR));
2292 /* minor version */
2293 rb_define_const(rb_mMarshal, "MINOR_VERSION", INT2FIX(MARSHAL_MINOR));
2294 }
2295
2296 static st_table *
2297 compat_allocator_table(void)
2298 {
2299 if (compat_allocator_tbl) return compat_allocator_tbl;
2300 compat_allocator_tbl = st_init_numtable();
2301 #undef RUBY_UNTYPED_DATA_WARNING
2302 #define RUBY_UNTYPED_DATA_WARNING 0
2303 compat_allocator_tbl_wrapper =
2304 Data_Wrap_Struct(0, mark_marshal_compat_t, 0, compat_allocator_tbl);
2305 rb_gc_register_mark_object(compat_allocator_tbl_wrapper);
2306 return compat_allocator_tbl;
2307 }
2308
2309 VALUE
2310 rb_marshal_dump(VALUE obj, VALUE port)
2311 {
2312 return rb_marshal_dump_limited(obj, port, -1);
2313 }
2314
2315 VALUE
2316 rb_marshal_load(VALUE port)
2317 {
2318 return rb_marshal_load_with_proc(port, Qnil);
2319 }
TYPE_SYMLINK
#define TYPE_SYMLINK
Definition: marshal.c:78
rb_cArray
VALUE rb_cArray
Definition: array.c:27
FLONUM_P
#define FLONUM_P(x)
Definition: ruby.h:430
rb_prepend_module
void rb_prepend_module(VALUE klass, VALUE module)
Definition: class.c:999
ID
unsigned long ID
Definition: ruby.h:103
rb_check_funcall
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
Definition: vm_eval.c:505
BIGNUM_DIGITS
#define BIGNUM_DIGITS(b)
Definition: internal.h:780
RHASH_PROC_DEFAULT
@ RHASH_PROC_DEFAULT
Definition: internal.h:819
load_mantissa
#define load_mantissa(d, buf, len)
Definition: marshal.c:390
ruby_dtoa
char * ruby_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve)
TypedData_Make_Struct
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: ruby.h:1244
TRUE
#define TRUE
Definition: nkf.h:175
RSTRING_GETMEM
#define RSTRING_GETMEM(str, ptrvar, lenvar)
Definition: ruby.h:1018
T_FLOAT
#define T_FLOAT
Definition: ruby.h:527
strtod
#define strtod(s, e)
Definition: util.h:76
rb_enc_name
#define rb_enc_name(enc)
Definition: encoding.h:177
marshal_compat_t::newclass
VALUE newclass
Definition: marshal.c:103
INTEGER_PACK_NEGATIVE
#define INTEGER_PACK_NEGATIVE
Definition: intern.h:160
LONG_MAX
#define LONG_MAX
Definition: ruby.h:220
id
const int id
Definition: nkf.c:209
FIX2INT
#define FIX2INT(x)
Definition: ruby.h:717
rb_hash_new
VALUE rb_hash_new(void)
Definition: hash.c:1501
rb_gc_register_mark_object
void rb_gc_register_mark_object(VALUE obj)
Definition: gc.c:7063
marshal_compat_t::loader
VALUE(* loader)(VALUE, VALUE)
Definition: marshal.c:106
path
VALUE path
Definition: rb_mjit_min_header-2.7.0.h:7351
w_ivar_arg
Definition: marshal.c:562
rb_struct_members
VALUE rb_struct_members(VALUE)
Definition: struct.c:72
FLOAT_DIG
#define FLOAT_DIG
Definition: marshal.c:396
rb_str_buf_new
VALUE rb_str_buf_new(long)
Definition: string.c:1315
rb_warn
void rb_warn(const char *fmt,...)
Definition: error.c:313
memset
void * memset(void *, int, size_t)
rb_hash_size_num
size_t rb_hash_size_num(VALUE hash)
Definition: hash.c:2872
rb_scan_args
#define rb_scan_args(argc, argvp, fmt,...)
Definition: rb_mjit_min_header-2.7.0.h:6372
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:263
snprintf
int snprintf(char *__restrict, size_t, const char *__restrict,...) __attribute__((__format__(__printf__
rb_struct_s_keyword_init
VALUE rb_struct_s_keyword_init(VALUE klass)
Definition: struct.c:52
rb_get_alloc_func
rb_alloc_func_t rb_get_alloc_func(VALUE)
Definition: vm_method.c:728
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:1009
rb_int2big
VALUE rb_int2big(intptr_t n)
Definition: bignum.c:3180
st_init_numtable
st_table * st_init_numtable(void)
Definition: st.c:653
RREGEXP_SRC_LEN
#define RREGEXP_SRC_LEN(r)
Definition: ruby.h:1121
rb_utf8_encindex
int rb_utf8_encindex(void)
Definition: encoding.c:1334
path2module
#define path2module(path)
Definition: marshal.c:1556
VALUE
unsigned long VALUE
Definition: ruby.h:102
rb_eArgError
VALUE rb_eArgError
Definition: error.c:923
ruby_verbose
#define ruby_verbose
Definition: ruby.h:1925
st_delete
int st_delete(st_table *tab, st_data_t *key, st_data_t *value)
Definition: st.c:1418
RB_TYPE_P
#define RB_TYPE_P(obj, type)
Definition: ruby.h:560
TYPE
#define TYPE(x)
Definition: ruby.h:554
rb_enc_get
rb_encoding * rb_enc_get(VALUE obj)
Definition: encoding.c:872
st_add_direct
void st_add_direct(st_table *tab, st_data_t key, st_data_t value)
Definition: st.c:1251
rb_enc_asciicompat
#define rb_enc_asciicompat(enc)
Definition: encoding.h:245
ruby_marshal_read_long
long ruby_marshal_read_long(const char **buf, long len)
Definition: marshal.c:1266
int
__inline__ int
Definition: rb_mjit_min_header-2.7.0.h:2839
rb_define_module
VALUE rb_define_module(const char *name)
Definition: class.c:772
TYPE_CLASS
#define TYPE_CLASS
Definition: marshal.c:74
load_arg::compat_tbl
st_table * compat_tbl
Definition: marshal.c:1110
INTEGER_PACK_LITTLE_ENDIAN
#define INTEGER_PACK_LITTLE_ENDIAN
Definition: intern.h:162
StringValue
use StringValue() instead")))
TYPE_LINK
#define TYPE_LINK
Definition: marshal.c:81
TYPE_UCLASS
#define TYPE_UCLASS
Definition: marshal.c:60
rb_check_string_type
VALUE rb_check_string_type(VALUE)
Definition: string.c:2314
Qundef
#define Qundef
Definition: ruby.h:470
SHORTMASK
#define SHORTMASK
Definition: marshal.c:29
Data_Wrap_Struct
#define Data_Wrap_Struct(klass, mark, free, sval)
Definition: ruby.h:1211
INT2NUM
#define INT2NUM(x)
Definition: ruby.h:1609
ptr
struct RIMemo * ptr
Definition: debug.c:74
TYPE_STRING
#define TYPE_STRING
Definition: marshal.c:67
T_DATA
#define T_DATA
Definition: ruby.h:538
Qfalse
#define Qfalse
Definition: ruby.h:467
r_bytes
#define r_bytes(arg)
Definition: marshal.c:1335
BUFSIZ
#define BUFSIZ
Definition: rb_mjit_min_header-2.7.0.h:1474
DBL2NUM
#define DBL2NUM(dbl)
Definition: ruby.h:967
fabs
double fabs(double)
SPECIAL_CONST_P
#define SPECIAL_CONST_P(x)
Definition: ruby.h:1313
st.h
NULL
#define NULL
Definition: _sdbm.c:101
rb_struct_initialize
VALUE rb_struct_initialize(VALUE, VALUE)
Definition: struct.c:662
load_arg::buf
char * buf
Definition: marshal.c:1103
FL_TEST
#define FL_TEST(x, f)
Definition: ruby.h:1353
PRIsVALUE
#define PRIsVALUE
Definition: ruby.h:166
RBASIC_SET_CLASS
#define RBASIC_SET_CLASS(obj, cls)
Definition: internal.h:1983
ruby::backward::cxxanyargs::rb_ivar_foreach
void rb_ivar_foreach(VALUE q, int_type *w, VALUE e)
Iteration over each instance variable of the object.
Definition: cxxanyargs.hpp:428
rb_init_identtable
st_table * rb_init_identtable(void)
Definition: hash.c:4211
rb_obj_respond_to
int rb_obj_respond_to(VALUE, ID, int)
Definition: vm_method.c:2180
st_insert
int st_insert(st_table *tab, st_data_t key, st_data_t value)
Definition: st.c:1171
FIX2LONG
#define FIX2LONG(x)
Definition: ruby.h:394
ID2SYM
#define ID2SYM(x)
Definition: ruby.h:414
ruby.h
rb_eof_error
void rb_eof_error(void)
Definition: io.c:697
T_OBJECT
#define T_OBJECT
Definition: ruby.h:523
dump_call_arg
Definition: marshal.c:161
rb_ary_pop
VALUE rb_ary_pop(VALUE ary)
Definition: array.c:1241
rb_mark_set
void rb_mark_set(st_table *tbl)
Definition: gc.c:4798
dump_arg::dest
VALUE dest
Definition: marshal.c:154
L
#define L(x)
Definition: asm.h:125
rb_respond_to
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:2190
TYPE_FLOAT
#define TYPE_FLOAT
Definition: marshal.c:65
major
#define major(dev)
Definition: rb_mjit_min_header-2.7.0.h:1436
rb_check_arity
#define rb_check_arity
Definition: intern.h:347
SINGLETON_DUMP_UNABLE_P
#define SINGLETON_DUMP_UNABLE_P(klass)
Definition: marshal.c:506
SHORTLEN
#define SHORTLEN(x)
Definition: marshal.c:33
rb_hash_new_with_size
MJIT_FUNC_EXPORTED VALUE rb_hash_new_with_size(st_index_t size)
Definition: hash.c:1507
TYPE_BIGNUM
#define TYPE_BIGNUM
Definition: marshal.c:66
marshal_compat_t::dumper
VALUE(* dumper)(VALUE)
Definition: marshal.c:105
v
int VALUE v
Definition: rb_mjit_min_header-2.7.0.h:12332
rb_str_resize
VALUE rb_str_resize(VALUE, long)
Definition: string.c:2709
rb_funcallv
#define rb_funcallv(recv, mid, argc, argv)
Definition: rb_mjit_min_header-2.7.0.h:7899
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2669
RCLASS_ORIGIN
#define RCLASS_ORIGIN(c)
Definition: internal.h:1075
rb_id_encoding
ID rb_id_encoding(void)
Definition: encoding.c:759
SHORTDN
#define SHORTDN(x)
Definition: marshal.c:30
SIZEOF_BDIGIT
#define SIZEOF_BDIGIT
Definition: internal.h:689
LONG2NUM
#define LONG2NUM(x)
Definition: ruby.h:1644
SIZEOF_LONG
#define SIZEOF_LONG
Definition: rb_mjit_min_header-2.7.0.h:85
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.0.h:5742
NUM2CHR
#define NUM2CHR(x)
Definition: ruby.h:1647
rb_obj_class
VALUE rb_obj_class(VALUE)
Equivalent to Object#class in Ruby.
Definition: object.c:217
marshal_compat_t::oldclass
VALUE oldclass
Definition: marshal.c:104
rb_enc_get_index
int rb_enc_get_index(VALUE obj)
Definition: encoding.c:779
T_ICLASS
#define T_ICLASS
Definition: ruby.h:525
memcpy
void * memcpy(void *__restrict, const void *__restrict, size_t)
HUGE_VAL
#define HUGE_VAL
Definition: missing.h:161
rb_encoding
const typedef OnigEncodingType rb_encoding
Definition: encoding.h:115
TYPE_NIL
#define TYPE_NIL
Definition: marshal.c:54
rb_str_intern
VALUE rb_str_intern(VALUE)
Definition: symbol.c:710
dump_arg::encodings
st_table * encodings
Definition: marshal.c:158
prohibit_ivar
#define prohibit_ivar(type, str)
Definition: marshal.c:1607
TYPE_REGEXP
#define TYPE_REGEXP
Definition: marshal.c:68
TYPE_IVAR
#define TYPE_IVAR
Definition: marshal.c:80
rb_setup_fake_str
VALUE rb_setup_fake_str(struct RString *fake_str, const char *name, long len, rb_encoding *enc)
Definition: string.c:385
TYPE_USERDEF
#define TYPE_USERDEF
Definition: marshal.c:63
load_arg::symbols
st_table * symbols
Definition: marshal.c:1107
TYPE_FALSE
#define TYPE_FALSE
Definition: marshal.c:56
rb_enc_from_index
rb_encoding * rb_enc_from_index(int index)
Definition: encoding.c:609
TYPE_TRUE
#define TYPE_TRUE
Definition: marshal.c:55
rb_ary_tmp_new
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:768
i
uint32_t i
Definition: rb_mjit_min_header-2.7.0.h:5464
dump_call_arg::obj
VALUE obj
Definition: marshal.c:162
load_arg::proc
VALUE proc
Definition: marshal.c:1109
sym
#define sym(x)
Definition: date_core.c:3716
st_data_t
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
Definition: st.h:22
rb_builtin_type_name
const char * rb_builtin_type_name(int t)
Definition: error.c:761
dump_arg::data
st_table * data
Definition: marshal.c:156
T_REGEXP
#define T_REGEXP
Definition: ruby.h:529
long
#define long
Definition: rb_mjit_min_header-2.7.0.h:2880
TYPE_ARRAY
#define TYPE_ARRAY
Definition: marshal.c:69
rb_reg_new_str
VALUE rb_reg_new_str(VALUE, int)
Definition: re.c:2894
rb_str_equal
VALUE rb_str_equal(VALUE str1, VALUE str2)
Definition: string.c:3267
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1195
st_index_t
st_data_t st_index_t
Definition: st.h:50
TYPE_MODULE_OLD
#define TYPE_MODULE_OLD
Definition: marshal.c:73
TYPE_HASH_DEF
#define TYPE_HASH_DEF
Definition: marshal.c:71
TYPE_USRMARSHAL
#define TYPE_USRMARSHAL
Definition: marshal.c:64
RHASH_IFNONE
#define RHASH_IFNONE(h)
Definition: ruby.h:1129
nan
RUBY_EXTERN double nan(const char *)
Definition: nan.c:7
isnan
#define isnan(x)
Definition: win32.h:369
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:922
RBASIC_CLASS
#define RBASIC_CLASS(obj)
Definition: ruby.h:906
ALLOC
#define ALLOC(type)
Definition: ruby.h:1664
T_CLASS
#define T_CLASS
Definition: ruby.h:524
dump_call_arg::arg
struct dump_arg * arg
Definition: marshal.c:163
rb_integer_unpack
VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
Definition: bignum.c:3633
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:920
st_init_strcasetable
st_table * st_init_strcasetable(void)
Definition: st.c:683
RSHIFT
#define RSHIFT(x, y)
Definition: rb_mjit_min_header-2.7.0.h:414
RARRAY_AREF
#define RARRAY_AREF(a, i)
Definition: ruby.h:1101
size
int size
Definition: encoding.c:58
rb_str_set_len
void rb_str_set_len(VALUE, long)
Definition: string.c:2692
FALSE
#define FALSE
Definition: nkf.h:174
isinf
#define isinf(__x)
Definition: rb_mjit_min_header-2.7.0.h:3673
FIXNUM_P
#define FIXNUM_P(f)
Definition: ruby.h:396
TYPE_MODULE
#define TYPE_MODULE
Definition: marshal.c:75
RString
Definition: ruby.h:988
w_ivar_arg::num_ivar
st_data_t num_ivar
Definition: marshal.c:564
RCLASS_SUPER
#define RCLASS_SUPER(c)
Definition: classext.h:16
marshal_compat_t
Definition: marshal.c:102
w_ivar_arg::dump
struct dump_call_arg * dump
Definition: marshal.c:563
rb_hash_foreach
void rb_hash_foreach(VALUE hash, rb_foreach_func *func, VALUE farg)
Definition: hash.c:1461
MARSHAL_MINOR
#define MARSHAL_MINOR
Definition: marshal.c:52
memcmp
int memcmp(const void *s1, const void *s2, size_t len)
Definition: memcmp.c:7
rb_str_new_cstr
#define rb_str_new_cstr(str)
Definition: rb_mjit_min_header-2.7.0.h:6117
TYPE_STRUCT
#define TYPE_STRUCT
Definition: marshal.c:72
ruby_marshal_write_long
int ruby_marshal_write_long(long x, char *buf)
Definition: marshal.c:307
dump_check_funcall
#define dump_check_funcall(arg, obj, sym, argc, argv)
Definition: marshal.c:192
frexp
double frexp(double, int *)
TYPE_SYMBOL
#define TYPE_SYMBOL
Definition: marshal.c:77
to_be_skipped_id
#define to_be_skipped_id(id)
Definition: marshal.c:560
rb_extend_object
void rb_extend_object(VALUE obj, VALUE module)
Extend the object with the module.
Definition: eval.c:1700
StringValueCStr
#define StringValueCStr(v)
Definition: ruby.h:604
rb_cHash
VALUE rb_cHash
Definition: hash.c:92
link
int link(const char *, const char *)
Definition: win32.c:4931
key
key
Definition: openssl_missing.h:181
T_HASH
#define T_HASH
Definition: ruby.h:531
dump_arg::str
VALUE str
Definition: marshal.c:154
rb_ary_clear
VALUE rb_ary_clear(VALUE ary)
Definition: array.c:3862
CLASS_OF
#define CLASS_OF(v)
Definition: ruby.h:484
src
__inline__ const void *__restrict src
Definition: rb_mjit_min_header-2.7.0.h:2836
signbit
#define signbit(__x)
Definition: rb_mjit_min_header-2.7.0.h:3676
strcmp
int strcmp(const char *, const char *)
T_MODULE
#define T_MODULE
Definition: ruby.h:526
RARRAY_LEN
#define RARRAY_LEN(a)
Definition: ruby.h:1070
st_foreach
int st_foreach(st_table *tab, st_foreach_callback_func *func, st_data_t arg)
Definition: st.c:1718
MARSHAL_MAJOR
#define MARSHAL_MAJOR
Definition: marshal.c:51
rb_define_module_function
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1771
rb_reg_options
int rb_reg_options(VALUE)
Definition: re.c:3578
RSTRUCT_LEN
#define RSTRUCT_LEN(st)
Definition: ruby.h:1255
char
#define char
Definition: rb_mjit_min_header-2.7.0.h:2876
rb_ary_new2
#define rb_ary_new2
Definition: intern.h:103
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4322
n
const char size_t n
Definition: rb_mjit_min_header-2.7.0.h:5456
rb_usascii_encindex
int rb_usascii_encindex(void)
Definition: encoding.c:1346
T_BIGNUM
#define T_BIGNUM
Definition: ruby.h:533
rb_enc_str_coderange
int rb_enc_str_coderange(VALUE)
Definition: string.c:657
TYPE_HASH
#define TYPE_HASH
Definition: marshal.c:70
Init_marshal
void Init_marshal(void)
Definition: marshal.c:2265
internal.h
T_ARRAY
#define T_ARRAY
Definition: ruby.h:530
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.0.h:5601
load_arg::offset
long offset
Definition: marshal.c:1106
argv
char ** argv
Definition: ruby.c:223
ST_CONTINUE
@ ST_CONTINUE
Definition: st.h:99
xmalloc
#define xmalloc
Definition: defines.h:211
rb_mark_hash
void rb_mark_hash(st_table *tbl)
Definition: gc.c:4862
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.0.h:13254
st_data_t
unsigned long st_data_t
Definition: rb_mjit_min_header-2.7.0.h:5363
w_cstr
#define w_cstr(s, arg)
Definition: marshal.c:286
dump_arg::compat_tbl
st_table * compat_tbl
Definition: marshal.c:157
BDIGIT
#define BDIGIT
Definition: bigdecimal.h:48
rb_obj_alloc
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
Definition: object.c:1895
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
RREGEXP_SRC_PTR
#define RREGEXP_SRC_PTR(r)
Definition: ruby.h:1120
rb_struct_s_members
VALUE rb_struct_s_members(VALUE)
Definition: struct.c:58
BIGNUM_SIGN
#define BIGNUM_SIGN(b)
Definition: internal.h:761
modf
double modf(double, double *)
load_arg
Definition: marshal.c:1101
rb_enc_find_index
int rb_enc_find_index(const char *name)
Definition: encoding.c:693
load_arg::src
VALUE src
Definition: marshal.c:1102
TYPE_DATA
#define TYPE_DATA
Definition: marshal.c:62
TYPE_FIXNUM
#define TYPE_FIXNUM
Definition: marshal.c:57
RUBY_TYPED_FREE_IMMEDIATELY
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1207
ENC_CODERANGE_7BIT
#define ENC_CODERANGE_7BIT
Definition: encoding.h:104
rb_hash_aset
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:2779
rb_cString
RUBY_EXTERN VALUE rb_cString
Definition: ruby.h:2044
rb_marshal_load
VALUE rb_marshal_load(VALUE port)
Definition: marshal.c:2316
RHASH_SET_IFNONE
#define RHASH_SET_IFNONE(h, ifnone)
Definition: ruby.h:1132
rb_alloc_func_t
VALUE(* rb_alloc_func_t)(VALUE)
Definition: intern.h:427
r_entry
#define r_entry(v, arg)
Definition: marshal.c:1157
rb_ivar_defined
VALUE rb_ivar_defined(VALUE, ID)
Definition: variable.c:1317
NIL_P
#define NIL_P(v)
Definition: ruby.h:482
io.h
argc
int argc
Definition: ruby.c:222
rb_singleton_class
VALUE rb_singleton_class(VALUE obj)
Returns the singleton class of obj.
Definition: class.c:1725
minor
#define minor(dev)
Definition: rb_mjit_min_header-2.7.0.h:1437
load_arg::readable
long readable
Definition: marshal.c:1105
rb_define_const
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2880
encindex.h
dump_arg::symbols
st_table * symbols
Definition: marshal.c:155
rb_io_write
VALUE rb_io_write(VALUE, VALUE)
Definition: io.c:1804
rb_data_type_struct
Definition: ruby.h:1148
BUILTIN_TYPE
#define BUILTIN_TYPE(x)
Definition: ruby.h:551
RFLOAT_VALUE
#define RFLOAT_VALUE(v)
Definition: ruby.h:966
xfree
#define xfree
Definition: defines.h:216
RSTRUCT_GET
#define RSTRUCT_GET(st, idx)
Definition: ruby.h:1258
RBASIC
#define RBASIC(obj)
Definition: ruby.h:1267
rb_str_new
#define rb_str_new(str, len)
Definition: rb_mjit_min_header-2.7.0.h:6116
dump_call_arg::limit
int limit
Definition: marshal.c:164
rb_gc_mark
void rb_gc_mark(VALUE ptr)
Definition: gc.c:5212
load_funcall
#define load_funcall(arg, obj, sym, argc, argv)
Definition: marshal.c:1122
dump_arg
Definition: marshal.c:153
_
#define _(args)
Definition: dln.h:28
load_arg::data
st_table * data
Definition: marshal.c:1108
ENCINDEX_US_ASCII
#define ENCINDEX_US_ASCII
Definition: encindex.h:44
Qtrue
#define Qtrue
Definition: ruby.h:468
NORETURN
NORETURN(static inline void io_needed(void))
rb_class_name
VALUE rb_class_name(VALUE)
Definition: variable.c:274
len
uint8_t len
Definition: escape.c:17
rb_class_path
VALUE rb_class_path(VALUE)
Definition: variable.c:153
SYMBOL_P
#define SYMBOL_P(x)
Definition: ruby.h:413
PRIdVALUE
#define PRIdVALUE
Definition: ruby.h:161
rb_mark_tbl
void rb_mark_tbl(st_table *tbl)
Definition: gc.c:5005
load_arg::buflen
long buflen
Definition: marshal.c:1104
LONG2FIX
#define LONG2FIX(i)
Definition: ruby.h:265
rb_ivar_set
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1300
dump_funcall
#define dump_funcall(arg, obj, sym, argc, argv)
Definition: marshal.c:190
rb_intern_str
#define rb_intern_str(string)
Definition: generator.h:16
T_STRING
#define T_STRING
Definition: ruby.h:528
FL_SINGLETON
#define FL_SINGLETON
Definition: ruby.h:1278
rb_sym2str
VALUE rb_sym2str(VALUE)
Definition: symbol.c:784
rb_enc_str_asciionly_p
int rb_enc_str_asciionly_p(VALUE)
Definition: string.c:678
set_id
#define set_id(sym)
NUM2INT
#define NUM2INT(x)
Definition: ruby.h:715
T_STRUCT
#define T_STRUCT
Definition: ruby.h:532
Qnil
#define Qnil
Definition: ruby.h:469
TYPE_EXTENDED
#define TYPE_EXTENDED
Definition: marshal.c:59
rb_str_buf_cat
#define rb_str_buf_cat
Definition: intern.h:910
rb_marshal_define_compat
void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE(*dumper)(VALUE), VALUE(*loader)(VALUE, VALUE))
Definition: marshal.c:133
unsigned
#define unsigned
Definition: rb_mjit_min_header-2.7.0.h:2875
st_lookup
int st_lookup(st_table *tab, st_data_t key, st_data_t *value)
Definition: st.c:1101
util.h
BIGNUM_LEN
#define BIGNUM_LEN(b)
Definition: internal.h:774
rb_cRegexp
RUBY_EXTERN VALUE rb_cRegexp
Definition: ruby.h:2042
RB_GC_GUARD
#define RB_GC_GUARD(v)
Definition: ruby.h:585
rb_marshal_dump
VALUE rb_marshal_dump(VALUE obj, VALUE port)
Definition: marshal.c:2310
RSTRING_LEN
#define RSTRING_LEN(str)
Definition: ruby.h:1005
st_free_table
void st_free_table(st_table *tab)
Definition: st.c:709
st_table
Definition: st.h:79
rb_path_to_class
VALUE rb_path_to_class(VALUE)
Definition: variable.c:226
TYPE_OBJECT
#define TYPE_OBJECT
Definition: marshal.c:61
STRINGIZE
#define STRINGIZE(expr)
Definition: defines.h:331
rb_str_cat
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:2812
id_table.h
RTEST
#define RTEST(v)
Definition: ruby.h:481
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
rb_enc_capable
int rb_enc_capable(VALUE obj)
Definition: encoding.c:753
rb_special_const_p
#define rb_special_const_p(obj)
Definition: rb_mjit_min_header-2.7.0.h:5357
SIZEOF_SHORT
#define SIZEOF_SHORT
Definition: rb_mjit_min_header-2.7.0.h:84
rb_enc_associate_index
VALUE rb_enc_associate_index(VALUE obj, int idx)
Definition: encoding.c:838
ldexp
double ldexp(double, int)
rb_class_inherited_p
VALUE rb_class_inherited_p(VALUE mod, VALUE arg)
Determines if mod inherits arg.
Definition: object.c:1574
rb_class_real
VALUE rb_class_real(VALUE cl)
Looks up the nearest ancestor of cl, skipping singleton classes or module inclusions.
Definition: object.c:202
name
const char * name
Definition: nkf.c:208