static VALUE
marshal_load(int argc, VALUE *argv)
{
VALUE port, proc;
int major, minor;
VALUE v;
struct load_arg arg;
rb_scan_args(argc, argv, "11", &port, &proc);
v = rb_check_string_type(port);
if (!NIL_P(v)) {
arg.taint = OBJ_TAINTED(port); /* original taintedness */
port = v;
}
else if (rb_respond_to(port, s_getbyte) && rb_respond_to(port, s_read)) {
if (rb_respond_to(port, s_binmode)) {
rb_funcall2(port, s_binmode, 0, 0);
}
arg.taint = Qtrue;
}
else {
rb_raise(rb_eTypeError, "instance of IO needed");
}
arg.untrust = OBJ_UNTRUSTED(port);
arg.src = port;
arg.offset = 0;
arg.symbols = st_init_numtable();
arg.data = st_init_numtable();
arg.compat_tbl = st_init_numtable();
arg.proc = 0;
arg.wrapper = Data_Wrap_Struct(rb_cData, mark_load_arg, 0, &arg);
major = r_byte(&arg);
minor = r_byte(&arg);
if (major != MARSHAL_MAJOR || minor > MARSHAL_MINOR) {
rb_raise(rb_eTypeError, "incompatible marshal file format (can't be read)\n\
\tformat version %d.%d required; %d.%d given",
MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
}
if (RTEST(ruby_verbose) && minor != MARSHAL_MINOR) {
rb_warn("incompatible marshal file format (can be read)\n\
\tformat version %d.%d required; %d.%d given",
MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
}
if (!NIL_P(proc)) arg.proc = proc;
v = rb_ensure(load, (VALUE)&arg, load_ensure, (VALUE)&arg);
return v;
}