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