27 #define BITSPERSHORT (2*CHAR_BIT)
28 #define SHORTMASK ((1<<BITSPERSHORT)-1)
29 #define SHORTDN(x) RSHIFT((x),BITSPERSHORT)
31 #if SIZEOF_SHORT == SIZEOF_BDIGITS
32 #define SHORTLEN(x) (x)
45 return (len - 1)*
sizeof(
BDIGIT)/2 + offset;
47 #define SHORTLEN(x) shortlen((x),d)
50 #define MARSHAL_MAJOR 4
51 #define MARSHAL_MINOR 8
55 #define TYPE_FALSE 'F'
56 #define TYPE_FIXNUM 'i'
58 #define TYPE_EXTENDED 'e'
59 #define TYPE_UCLASS 'C'
60 #define TYPE_OBJECT 'o'
62 #define TYPE_USERDEF 'u'
63 #define TYPE_USRMARSHAL 'U'
64 #define TYPE_FLOAT 'f'
65 #define TYPE_BIGNUM 'l'
66 #define TYPE_STRING '"'
67 #define TYPE_REGEXP '/'
68 #define TYPE_ARRAY '['
70 #define TYPE_HASH_DEF '}'
71 #define TYPE_STRUCT 'S'
72 #define TYPE_MODULE_OLD 'M'
73 #define TYPE_CLASS 'c'
74 #define TYPE_MODULE 'm'
76 #define TYPE_SYMBOL ':'
77 #define TYPE_SYMLINK ';'
133 #define MARSHAL_INFECTION (FL_TAINT|FL_UNTRUSTED)
183 return ptr ?
sizeof(
struct dump_arg) : 0;
248 #define w_cstr(s, arg) w_bytes((s), strlen(s), (arg))
253 w_byte((
char)((x >> 0) & 0xff), arg);
254 w_byte((
char)((x >> 8) & 0xff), arg);
260 char buf[
sizeof(long)+1];
264 if (!(RSHIFT(x, 31) == 0 || RSHIFT(x, 31) == -1)) {
274 if (0 < x && x < 123) {
275 w_byte((
char)(x + 5), arg);
278 if (-124 < x && x < 0) {
279 w_byte((
char)((x - 5)&0xff), arg);
282 for (i=1;i<(
int)
sizeof(
long)+1;i++) {
283 buf[
i] = (char)(x & 0xff);
295 for (i=0;i<=
len;i++) {
301 #define DECIMAL_MANT (53-16)
303 #if DBL_MANT_DIG > 32
305 #elif DBL_MANT_DIG > 24
307 #elif DBL_MANT_DIG > 16
317 if (--len > 0 && !*buf++) {
318 int e,
s = d < 0, dig = 0;
321 modf(ldexp(frexp(fabs(d), &e), DECIMAL_MANT), &d);
325 default: m = *buf++ & 0xff;
327 case 3: m = (m << 8) | (*buf++ & 0xff);
330 case 2: m = (m << 8) | (*buf++ & 0xff);
333 case 1: m = (m << 8) | (*buf++ & 0xff);
336 dig -= len < MANT_BITS / 8 ? 8 * (unsigned)len : MANT_BITS;
337 d += ldexp((
double)m, dig);
338 }
while ((len -= MANT_BITS / 8) > 0);
339 d = ldexp(d, e - DECIMAL_MANT);
345 #define load_mantissa(d, buf, len) (d)
349 #define FLOAT_DIG (DBL_DIG+2)
357 char *
ruby_dtoa(
double d_,
int mode,
int ndigits,
int *decpt,
int *sign,
char **rve);
358 char buf[
FLOAT_DIG + (DECIMAL_MANT + 7) / 8 + 10];
361 if (d < 0)
w_cstr(
"-inf", arg);
368 if (1.0/d < 0)
w_cstr(
"-0", arg);
372 int decpt, sign, digs, len = 0;
373 char *
e, *
p =
ruby_dtoa(d, 0, 0, &decpt, &sign, &e);
374 if (sign) buf[len++] =
'-';
376 if (decpt < -3 || decpt > digs) {
378 if (--digs > 0) buf[len++] =
'.';
379 memcpy(buf + len, p + 1, digs);
381 len +=
snprintf(buf + len,
sizeof(buf) - len,
"e%d", decpt - 1);
383 else if (decpt > 0) {
384 memcpy(buf + len, p, decpt);
386 if ((digs -= decpt) > 0) {
388 memcpy(buf + len, p + decpt, digs);
396 memset(buf + len,
'0', -decpt);
399 memcpy(buf + len, p, digs);
460 #define SINGLETON_DUMP_UNABLE_P(klass) \
461 (RCLASS_M_TBL(klass)->num_entries || \
462 (RCLASS_IV_TBL(klass) && RCLASS_IV_TBL(klass)->num_entries > 1))
491 obj = (
VALUE)real_obj;
507 if (klass != super) {
584 for (i = 0; i <
len; i++)
601 #define has_ivars(obj, ivtbl) (((ivtbl) = rb_generic_ivar_table(obj)) != 0 || \
602 (!SPECIAL_CONST_P(obj) && !ENCODING_IS_ASCII8BIT(obj)))
621 else if (obj ==
Qtrue) {
632 if (RSHIFT((
long)obj, 31) == 0 || RSHIFT((
long)obj, 31) == -1) {
663 if (hasiv)
w_ivar(v, ivtbl, &c_arg);
678 if ((hasiv2 =
has_ivars(v, ivtbl2)) != 0 && !hasiv) {
684 w_ivar(v, ivtbl2, &c_arg);
687 w_ivar(obj, ivtbl, &c_arg);
704 obj = compat->
dumper(real_obj);
706 if (obj != real_obj && !ivtbl) hasiv = 0;
748 #if SIZEOF_BDIGITS > SIZEOF_SHORT
755 if (len == 0 && num == 0)
break;
825 for (i=0; i<
len; i++) {
843 "no _dump_data is defined for class %s",
861 w_ivar(obj, ivtbl, &c_arg);
928 volatile VALUE wrapper;
937 else if (argc == 2) {
1021 return ptr ?
sizeof(
struct load_arg) : 0;
1029 #define r_entry(v, arg) r_entry0((v), (arg)->data->num_entries, (arg))
1051 static unsigned char
1093 c = (
unsigned char)
NUM2CHR(v);
1103 STRINGIZE(SIZEOF_LONG)
", given %d)", size);
1106 #undef SIGN_EXTEND_CHAR
1108 # define SIGN_EXTEND_CHAR(c) ((signed char)(c))
1111 # define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128)
1121 if (c == 0)
return 0;
1123 if (4 < c && c < 128) {
1129 x |= (long)
r_byte(arg) << (8*
i);
1133 if (-129 < c && c < -4) {
1140 x &= ~((long)0xff << (8*i));
1141 x |= (long)
r_byte(arg) << (8*
i);
1167 if (len <= arg->buflen) {
1173 long buflen = arg->
buflen;
1175 long tmp_len, read_len, need_len = len - buflen;
1178 readable = readable < BUFSIZ ? readable : BUFSIZ;
1179 read_len = need_len > readable ? need_len :
readable;
1195 if (tmp_len > need_len) {
1196 buflen = tmp_len - need_len;
1209 #define r_bytes(arg) r_bytes0(r_long(arg), (arg))
1293 switch ((type =
r_byte(arg))) {
1350 compat->
loader(real_obj, v);
1375 if (has_encoding) *has_encoding =
TRUE;
1380 }
while (--len > 0);
1417 if (oldclass) *oldclass = compat->
oldclass;
1442 #define prohibit_ivar(type, str) do { \
1443 if (!ivp || !*ivp) break; \
1444 rb_raise(rb_eTypeError, \
1445 "can't override instance variable of "type" `%"PRIsVALUE"'", \
1509 if (
TYPE(v) !=
TYPE(tmp))
goto format_error;
1544 if (strcmp(ptr,
"nan") == 0) {
1547 else if (strcmp(ptr,
"inf") == 0) {
1550 else if (strcmp(ptr,
"-inf") == 0) {
1574 #if SIZEOF_BDIGITS == SIZEOF_SHORT
1582 #if SIZEOF_BDIGITS > SIZEOF_SHORT
1583 MEMZERO((
char *)digits + len * 2,
char,
1588 unsigned char *
p = (
unsigned char *)digits;
1590 #if SIZEOF_BDIGITS > SIZEOF_SHORT
1595 num |= (
int)p[i] << shift;
1599 num = p[0] | (p[1] << 8);
1619 int has_encoding =
FALSE;
1623 r_ivar(str, &has_encoding, arg);
1626 if (!has_encoding) {
1631 for (; len-- > 0; *
dst++ = *src++) {
1633 case '\\': bs++;
break;
1634 case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
1635 case 'm':
case 'o':
case 'p':
case 'q':
case 'u':
case 'y':
1636 case 'E':
case 'F':
case 'H':
case 'I':
case 'J':
case 'K':
1637 case 'L':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
1638 case 'S':
case 'T':
case 'U':
case 'V':
case 'X':
case 'Y':
1640 default: bs = 0;
break;
1652 volatile long len =
r_long(arg);
1710 for (i=0; i<
len; i++) {
1756 if (!
NIL_P(extmod)) {
1769 if (!
NIL_P(extmod)) {
1802 "class %s needs to have instance method `_load_data'",
1912 volatile VALUE wrapper;
1918 infection = (
int)
FL_TEST(port, MARSHAL_INFECTION);
1948 \tformat version %d.%d required; %d.%d given",
1952 rb_warn(
"incompatible marshal file format (can be read)\n\
1953 \tformat version %d.%d required; %d.%d given",
2080 #define rb_intern(str) rb_intern_const(str)
2118 if (!
NIL_P(port)) argc = 2;
#define RB_TYPE_P(obj, type)
static VALUE marshal_load(int argc, VALUE *argv)
static const rb_data_type_t dump_arg_data
static void long_toobig(int size)
int rb_enc_get_index(VALUE obj)
static long r_long(struct load_arg *arg)
VALUE rb_ary_pop(VALUE ary)
static int rb_special_const_p(VALUE obj)
static VALUE class2path(VALUE klass)
#define load_mantissa(d, buf, len)
void rb_mark_tbl(struct st_table *)
VALUE(* rb_alloc_func_t)(VALUE)
VALUE rb_struct_members(VALUE)
const char * rb_obj_classname(VALUE)
static unsigned char r_byte1_buffered(struct load_arg *arg)
static size_t memsize_dump_arg(const void *ptr)
int st_lookup(st_table *, st_data_t, st_data_t *)
void st_add_direct(st_table *, st_data_t, st_data_t)
static int w_obj_each(st_data_t key, st_data_t val, st_data_t a)
static void w_objivar(VALUE obj, struct dump_call_arg *arg)
st_table * st_init_numtable(void)
static const char * must_not_be_anonymous(const char *type, VALUE path)
static void w_long(long, struct dump_arg *)
static void w_object(VALUE, struct dump_arg *, int)
static VALUE marshal_dump(int argc, VALUE *argv)
VALUE rb_ary_push(VALUE ary, VALUE item)
st_table * st_init_strcasetable(void)
int rb_usascii_encindex(void)
VALUE rb_ary_tmp_new(long capa)
static int r_byte(struct load_arg *arg)
int rb_reg_options(VALUE)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
static void w_short(int x, struct dump_arg *arg)
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_ary_clear(VALUE ary)
VALUE rb_marshal_dump(VALUE, VALUE)
VALUE rb_class_name(VALUE)
void rb_mark_set(struct st_table *)
char ruby_check_marshal_viral_flags[MARSHAL_INFECTION==(int) MARSHAL_INFECTION?1:-1]
static void w_uclass(VALUE obj, VALUE super, struct dump_arg *arg)
static void w_ivar(VALUE obj, st_table *tbl, struct dump_call_arg *arg)
void rb_big_resize(VALUE big, long len)
VALUE rb_path_to_class(VALUE)
static VALUE path2class(VALUE path)
VALUE rb_class_path(VALUE)
static VALUE r_bytes1_buffered(long len, struct load_arg *arg)
static void w_class(char type, VALUE obj, struct dump_arg *arg, int check)
static int hash_each(VALUE key, VALUE value, struct dump_call_arg *arg)
static VALUE obj_alloc_by_path(VALUE path, struct load_arg *arg)
void rb_hash_foreach(VALUE, int(*)(ANYARGS), VALUE)
RUBY_EXTERN VALUE rb_cRegexp
static void w_nbyte(const char *s, long n, struct dump_arg *arg)
#define MEMZERO(p, type, n)
static VALUE r_string(struct load_arg *arg)
void st_foreach_safe(struct st_table *, int(*)(ANYARGS), st_data_t)
VALUE rb_reg_new_str(VALUE, int)
int st_delete(st_table *, st_data_t *, st_data_t *)
#define prohibit_ivar(type, str)
memset(y->frac+ix+1, 0,(y->Prec-(ix+1))*sizeof(BDIGIT))
return Data_Wrap_Struct(CLASS_OF(interp), 0, ip_free, slave)
static void check_dump_arg(struct dump_arg *arg, ID sym)
static void check_load_arg(struct load_arg *arg, ID sym)
#define rb_intern_str(string)
static VALUE path2module(VALUE path)
#define SINGLETON_DUMP_UNABLE_P(klass)
RUBY_EXTERN VALUE rb_cHash
#define StringValueCStr(v)
void rb_define_const(VALUE, const char *, VALUE)
static ID r_symlink(struct load_arg *arg)
static VALUE r_entry0(VALUE v, st_index_t num, struct load_arg *arg)
static VALUE r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
static st_index_t r_prepare(struct load_arg *arg)
unsigned char buf[MIME_BUF_SIZE]
VALUE rb_enc_associate_index(VALUE obj, int idx)
VALUE rb_check_funcall(VALUE, ID, int, VALUE *)
int link(const char *, const char *)
static size_t memsize_load_arg(const void *ptr)
#define RBIGNUM_DIGITS(b)
static void mark_dump_arg(void *ptr)
VALUE rb_str_buf_cat(VALUE, const char *, long)
VALUE rb_struct_s_members(VALUE)
static void too_short(void)
static void w_unique(VALUE s, struct dump_arg *arg)
VALUE rb_hash_aset(VALUE, VALUE, VALUE)
VALUE rb_str_resize(VALUE, long)
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
int st_foreach(st_table *, int(*)(ANYARGS), st_data_t)
#define RREGEXP_SRC_PTR(r)
#define RBIGNUM_SET_SIGN(b, sign)
VALUE rb_marshal_load(VALUE)
static VALUE r_bytes1(long len, struct load_arg *arg)
void rb_gc_register_mark_object(VALUE)
VALUE rb_class_inherited_p(VALUE, VALUE)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
static st_table * compat_allocator_tbl
VALUE(* loader)(VALUE, VALUE)
static ID r_symbol(struct load_arg *arg)
static void r_ivar(VALUE obj, int *has_encoding, struct load_arg *arg)
VALUE rb_str_buf_new(long)
static void clear_dump_arg(struct dump_arg *arg)
void rb_extend_object(VALUE obj, VALUE module)
int rb_utf8_encindex(void)
#define has_ivars(obj, ivtbl)
static void free_load_arg(void *ptr)
#define SIGN_EXTEND_CHAR(c)
static int mark_marshal_compat_i(st_data_t key, st_data_t value)
RUBY_EXTERN int isinf(double)
static void mark_load_arg(void *ptr)
RUBY_EXTERN VALUE rb_cString
static int id2encidx(ID id, VALUE val)
void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE(*dumper)(VALUE), VALUE(*loader)(VALUE, VALUE))
static VALUE r_bytes0(long len, struct load_arg *arg)
#define MARSHAL_INFECTION
#define MEMCPY(p1, p2, type, n)
const char * rb_class2name(VALUE)
VALUE rb_ivar_set(VALUE, ID, VALUE)
static void w_bytes(const char *s, long n, struct dump_arg *arg)
#define NEWOBJ_OF(obj, type, klass, flags)
VALUE rb_str_cat(VALUE, const char *, long)
#define ENC_CODERANGE_7BIT
rb_encoding * rb_enc_get(VALUE obj)
static void clear_load_arg(struct load_arg *arg)
int rb_obj_respond_to(VALUE, ID, int)
VALUE rb_struct_initialize(VALUE, VALUE)
#define TypedData_Make_Struct(klass, type, data_type, sval)
static void w_symbol(ID id, struct dump_arg *arg)
VALUE rb_big_norm(VALUE x)
static VALUE compat_allocator_tbl_wrapper
rb_alloc_func_t rb_get_alloc_func(VALUE)
static VALUE append_extmod(VALUE obj, VALUE extmod)
int rb_respond_to(VALUE, ID)
static VALUE r_unique(struct load_arg *arg)
static ID r_symreal(struct load_arg *arg, int ivar)
int st_insert(st_table *, st_data_t, st_data_t)
static void free_dump_arg(void *ptr)
VALUE rb_int2big(SIGNED_VALUE n)
VALUE rb_ary_new2(long capa)
static VALUE r_object(struct load_arg *arg)
VALUE rb_str_new(const char *, long)
static void mark_marshal_compat_t(void *tbl)
static struct StringIO * readable(VALUE strio)
#define rb_enc_asciicompat(enc)
static VALUE obj_alloc_by_klass(VALUE klass, struct load_arg *arg, VALUE *oldclass)
static void io_needed(void)
VALUE rb_obj_alloc(VALUE)
const char * rb_id2name(ID id)
VALUE rb_class_real(VALUE)
void rb_mark_hash(struct st_table *)
static const rb_data_type_t load_arg_data
VALUE rb_funcall2(VALUE, ID, int, const VALUE *)
Calls a method.
int rb_enc_find_index(const char *name)
#define RREGEXP_SRC_LEN(r)
VALUE rb_define_module(const char *name)
void rb_ivar_foreach(VALUE, int(*)(ANYARGS), st_data_t)
RUBY_EXTERN VALUE rb_cData
static void w_extended(VALUE klass, struct dump_arg *arg, int check)
static void w_byte(char c, struct dump_arg *arg)
static void w_float(double d, struct dump_arg *arg)
VALUE rb_check_string_type(VALUE)
int rb_enc_str_coderange(VALUE)
void rb_warn(const char *fmt,...)
void st_free_table(st_table *)
static VALUE r_leave(VALUE v, struct load_arg *arg)
VALUE rb_io_write(VALUE, VALUE)
char * ruby_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve)
rb_encoding * rb_enc_from_index(int index)
static void w_encoding(VALUE obj, long num, struct dump_call_arg *arg)
void rb_str_set_len(VALUE, long)