summaryrefslogtreecommitdiff
path: root/marshal.c
diff options
context:
space:
mode:
Diffstat (limited to 'marshal.c')
-rw-r--r--marshal.c83
1 files changed, 59 insertions, 24 deletions
diff --git a/marshal.c b/marshal.c
index fe29385b42..9c802d0666 100644
--- a/marshal.c
+++ b/marshal.c
@@ -17,7 +17,7 @@ double strtod();
#endif
#define MARSHAL_MAJOR 4
-#define MARSHAL_MINOR 2
+#define MARSHAL_MINOR 3
#define TYPE_NIL '0'
#define TYPE_TRUE 'T'
@@ -42,6 +42,7 @@ double strtod();
#define TYPE_SYMBOL ':'
#define TYPE_SYMLINK ';'
+#define TYPE_IVAR 'I'
#define TYPE_LINK '@'
static ID s_dump, s_load;
@@ -201,12 +202,29 @@ w_uclass(obj, klass, arg)
}
static void
+w_ivar(tbl, arg)
+ st_table *tbl;
+ struct dump_call_arg *arg;
+{
+ struct dump_call_arg c_arg;
+
+ if (tbl) {
+ w_long(tbl->num_entries, arg->arg);
+ st_foreach(tbl, obj_each, arg);
+ }
+ else {
+ w_long(0, arg->arg);
+ }
+}
+
+static void
w_object(obj, arg, limit)
VALUE obj;
struct dump_arg *arg;
int limit;
{
struct dump_call_arg c_arg;
+ st_table *ivtbl = 0;;
if (limit == 0) {
rb_raise(rb_eRuntimeError, "exceed depth limit");
@@ -262,6 +280,10 @@ w_object(obj, arg, limit)
return;
}
+ if (ivtbl = rb_generic_ivar_table(obj)) {
+ w_byte(TYPE_IVAR, arg);
+ }
+
switch (BUILTIN_TYPE(obj)) {
case T_CLASS:
w_byte(TYPE_CLASS, arg);
@@ -269,7 +291,7 @@ w_object(obj, arg, limit)
VALUE path = rb_class_path(obj);
w_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg);
}
- return;
+ break;
case T_MODULE:
w_byte(TYPE_MODULE, arg);
@@ -277,12 +299,12 @@ w_object(obj, arg, limit)
VALUE path = rb_class_path(obj);
w_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg);
}
- return;
+ break;
case T_FLOAT:
w_byte(TYPE_FLOAT, arg);
w_float(RFLOAT(obj)->value, arg);
- return;
+ break;
case T_BIGNUM:
w_byte(TYPE_BIGNUM, arg);
@@ -298,20 +320,20 @@ w_object(obj, arg, limit)
d++;
}
}
- return;
+ break;
case T_STRING:
w_uclass(obj, rb_cString, arg);
w_byte(TYPE_STRING, arg);
w_bytes(RSTRING(obj)->ptr, RSTRING(obj)->len, arg);
- return;
+ break;
case T_REGEXP:
w_uclass(obj, rb_cRegexp, arg);
w_byte(TYPE_REGEXP, arg);
w_bytes(RREGEXP(obj)->str, RREGEXP(obj)->len, arg);
w_byte(rb_reg_options(obj), arg);
- return;
+ break;
case T_ARRAY:
w_uclass(obj, rb_cArray, arg);
@@ -375,13 +397,7 @@ w_object(obj, arg, limit)
}
path = rb_class2name(klass);
w_unique(path, arg);
- if (ROBJECT(obj)->iv_tbl) {
- w_long(ROBJECT(obj)->iv_tbl->num_entries, arg);
- st_foreach(ROBJECT(obj)->iv_tbl, obj_each, &c_arg);
- }
- else {
- w_long(0, arg);
- }
+ w_ivar(ROBJECT(obj)->iv_tbl);
}
break;
@@ -391,6 +407,9 @@ w_object(obj, arg, limit)
break;
}
}
+ if (ivtbl) {
+ w_ivar(ivtbl, &c_arg);
+ }
}
static VALUE
@@ -471,6 +490,8 @@ struct load_arg {
VALUE proc;
};
+static VALUE r_object _((struct load_arg *arg));
+
static int
r_byte(arg)
struct load_arg *arg;
@@ -624,6 +645,23 @@ r_regist(v, arg)
return v;
}
+static void
+r_ivar(obj, arg)
+ VALUE obj;
+ struct load_arg *arg;
+{
+ int len;
+
+ len = r_long(arg);
+ if (len > 0) {
+ while (len--) {
+ ID id = r_symbol(arg);
+ VALUE val = r_object(arg);
+ rb_ivar_set(obj, id, val);
+ }
+ }
+}
+
static VALUE
r_object(arg)
struct load_arg *arg;
@@ -642,6 +680,11 @@ r_object(arg)
return v;
break;
+ case TYPE_IVAR:
+ v = r_object(arg);
+ r_ivar(v, arg);
+ return v;
+
case TYPE_UCLASS:
{
VALUE c = rb_path2class(r_unique(arg));
@@ -793,19 +836,11 @@ r_object(arg)
case TYPE_OBJECT:
{
VALUE klass;
- int len;
klass = rb_path2class(r_unique(arg));
- len = r_long(arg);
v = rb_obj_alloc(klass);
r_regist(v, arg);
- if (len > 0) {
- while (len--) {
- ID id = r_symbol(arg);
- VALUE val = r_object(arg);
- rb_ivar_set(v, id, val);
- }
- }
+ r_ivar(v, arg);
return v;
}
break;
@@ -887,7 +922,7 @@ marshal_load(argc, argv)
int len;
arg.fp = 0;
- arg.ptr = str2cstr(port, &len);
+ arg.ptr = rb_str2cstr(port, &len);
arg.end = arg.ptr + len;
}
else {