Ruby  2.7.1p83(2020-03-31revisiona0c7c23c9cec0d0ffcba012279cd652d28ad5bf3)
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 {
105  VALUE (*dumper)(VALUE);
106  VALUE (*loader)(VALUE, VALUE);
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 {
159 };
160 
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);
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,},
226 };
227 
228 static VALUE
229 must_not_be_anonymous(const char *type, VALUE path)
230 {
231  char *n = RSTRING_PTR(path);
232 
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 {
249 
250  must_not_be_anonymous((RB_TYPE_P(klass, T_CLASS) ? "class" : "module"), path);
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
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) ||
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);
516  (origin != klass && SINGLETON_DUMP_UNABLE_P(origin))) {
517  rb_raise(rb_eTypeError, "singleton can't be dumped");
518  }
520  }
521  while (BUILTIN_TYPE(klass) == T_ICLASS) {
523  w_byte(TYPE_EXTENDED, arg);
524  w_unique(path, arg);
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);
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 {
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)) {
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",
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;
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);
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)) {
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 {
1103  char *buf;
1104  long buflen;
1105  long readable;
1106  long offset;
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);
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,},
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);
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 
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)) {
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 {
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);
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)) {
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);
1685  format_error:
1686  rb_raise(rb_eArgError, "dump format error (user class)");
1687  }
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 
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;
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")",
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)) {
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",
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",
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
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
2311 {
2312  return rb_marshal_dump_limited(obj, port, -1);
2313 }
2314 
2315 VALUE
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
strcmp
int strcmp(const char *, const char *)
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
i
uint32_t i
Definition: rb_mjit_min_header-2.7.1.h:5464
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
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.1.h:5742
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
long
#define long
Definition: rb_mjit_min_header-2.7.1.h:2880
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
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.1.h:13259
LONG_MAX
#define LONG_MAX
Definition: ruby.h:220
st_data_t
unsigned long st_data_t
Definition: rb_mjit_min_header-2.7.1.h:5363
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:1523
rb_gc_register_mark_object
void rb_gc_register_mark_object(VALUE obj)
Definition: gc.c:7065
marshal_compat_t::loader
VALUE(* loader)(VALUE, VALUE)
Definition: marshal.c:106
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
RSHIFT
#define RSHIFT(x, y)
Definition: rb_mjit_min_header-2.7.1.h:414
rb_hash_size_num
size_t rb_hash_size_num(VALUE hash)
Definition: hash.c:2940
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:263
n
const char size_t n
Definition: rb_mjit_min_header-2.7.1.h:5456
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
rb_str_new_cstr
#define rb_str_new_cstr(str)
Definition: rb_mjit_min_header-2.7.1.h:6117
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
modf
double modf(double, double *)
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
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
isinf
#define isinf(__x)
Definition: rb_mjit_min_header-2.7.1.h:3673
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
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.1.h:5601
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
frexp
double frexp(double, int *)
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
rb_str_new
#define rb_str_new(str, len)
Definition: rb_mjit_min_header-2.7.1.h:6116
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
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
char
#define char
Definition: rb_mjit_min_header-2.7.1.h:2876
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:1988
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:4280
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:4800
SIZEOF_SHORT
#define SIZEOF_SHORT
Definition: rb_mjit_min_header-2.7.1.h:84
rb_special_const_p
#define rb_special_const_p(obj)
Definition: rb_mjit_min_header-2.7.1.h:5357
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
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:1529
TYPE_BIGNUM
#define TYPE_BIGNUM
Definition: marshal.c:66
marshal_compat_t::dumper
VALUE(* dumper)(VALUE)
Definition: marshal.c:105
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: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
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
HUGE_VAL
#define HUGE_VAL
Definition: missing.h:161
minor
#define minor(dev)
Definition: rb_mjit_min_header-2.7.1.h:1437
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
ldexp
double ldexp(double, int)
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
unsigned
#define unsigned
Definition: rb_mjit_min_header-2.7.1.h:2875
rb_ary_tmp_new
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:768
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
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
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
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
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: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:307
dump_check_funcall
#define dump_check_funcall(arg, obj, sym, argc, argv)
Definition: marshal.c:192
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: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
path
VALUE path
Definition: rb_mjit_min_header-2.7.1.h:7353
dump_arg::str
VALUE str
Definition: marshal.c:154
BUFSIZ
#define BUFSIZ
Definition: rb_mjit_min_header-2.7.1.h:1474
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
fabs
double fabs(double)
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_scan_args
#define rb_scan_args(argc, argvp, fmt,...)
Definition: rb_mjit_min_header-2.7.1.h:6372
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
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
StringValue
use StringValue() instead")))
Init_marshal
void Init_marshal(void)
Definition: marshal.c:2265
internal.h
T_ARRAY
#define T_ARRAY
Definition: ruby.h:530
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:4864
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
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
SIZEOF_LONG
#define SIZEOF_LONG
Definition: rb_mjit_min_header-2.7.1.h:85
memset
void * memset(void *, int, size_t)
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:2847
int
__inline__ int
Definition: rb_mjit_min_header-2.7.1.h:2839
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
memcpy
void * memcpy(void *__restrict, const void *__restrict, size_t)
snprintf
int snprintf(char *__restrict, size_t, const char *__restrict,...) __attribute__((__format__(__printf__
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
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
v
int VALUE v
Definition: rb_mjit_min_header-2.7.1.h:12337
RBASIC
#define RBASIC(obj)
Definition: ruby.h:1267
dump_call_arg::limit
int limit
Definition: marshal.c:164
rb_gc_mark
void rb_gc_mark(VALUE ptr)
Definition: gc.c:5214
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:5007
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
major
#define major(dev)
Definition: rb_mjit_min_header-2.7.1.h:1436
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
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_enc_associate_index
VALUE rb_enc_associate_index(VALUE obj, int idx)
Definition: encoding.c:838
src
__inline__ const void *__restrict src
Definition: rb_mjit_min_header-2.7.1.h:2836
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
signbit
#define signbit(__x)
Definition: rb_mjit_min_header-2.7.1.h:3676
rb_funcallv
#define rb_funcallv(recv, mid, argc, argv)
Definition: rb_mjit_min_header-2.7.1.h:7904