marshal.c:1331
static VALUE
marshal_load(argc, argv)
    int argc;
    VALUE *argv;
{
    VALUE port, proc;
    int major, minor;
    VALUE v;
    struct load_arg arg;

    rb_scan_args(argc, argv, "11", &port, &proc);
    if (rb_respond_to(port, rb_intern("to_str"))) {
	arg.taint = OBJ_TAINTED(port); /* original taintedness */
	StringValue(port);	       /* possible conversion */
	arg.ptr = RSTRING(port)->ptr;
	arg.end = arg.ptr + RSTRING(port)->len;
    }
    else if (rb_respond_to(port, s_getc) && rb_respond_to(port, s_read)) {
	if (rb_respond_to(port, s_binmode)) {
	    rb_funcall2(port, s_binmode, 0, 0);
	}
	arg.taint = Qtrue;
	arg.ptr = (char *)port;
	arg.end = 0;
    }
    else {
	rb_raise(rb_eTypeError, "instance of IO needed");
    }

    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);
    }

    arg.symbols = st_init_numtable();
    arg.data   = rb_hash_new();
    if (NIL_P(proc)) arg.proc = 0;
    else             arg.proc = proc;
    v = rb_ensure(load, (VALUE)&arg, load_ensure, (VALUE)&arg);

    return v;
}
