diff options
Diffstat (limited to 'marshal.c')
-rw-r--r-- | marshal.c | 66 |
1 files changed, 56 insertions, 10 deletions
@@ -47,7 +47,7 @@ shortlen(long len, BDIGIT *ds) #endif #define MARSHAL_MAJOR 4 -#define MARSHAL_MINOR 8 +#define MARSHAL_MINOR 9 #define TYPE_NIL '0' #define TYPE_TRUE 'T' @@ -73,6 +73,7 @@ shortlen(long len, BDIGIT *ds) #define TYPE_MODULE 'm' #define TYPE_SYMBOL ':' +#define TYPE_SYMBOL2 ',' #define TYPE_SYMLINK ';' #define TYPE_IVAR 'I' @@ -304,7 +305,7 @@ w_float(double d, struct dump_arg *arg) static void w_symbol(ID id, struct dump_arg *arg) { - const char *sym = rb_id2name(id); + const char *sym; st_data_t num; if (st_lookup(arg->symbols, id, &num)) { @@ -312,8 +313,22 @@ w_symbol(ID id, struct dump_arg *arg) w_long((long)num, arg); } else { - w_byte(TYPE_SYMBOL, arg); - w_bytes(sym, strlen(sym), arg); + if (rb_is_instance2_id(id)) { + VALUE klass; + volatile VALUE path; + + id = rb_decompose_ivar2(id, &klass); + path = class2path(klass); + w_byte(TYPE_SYMBOL2, arg); + sym = rb_id2name(id); + w_bytes(sym, strlen(sym), arg); + w_bytes(RSTRING_PTR(path), RSTRING_LEN(path), arg); + } + else { + sym = rb_id2name(id); + w_byte(TYPE_SYMBOL, arg); + w_bytes(sym, strlen(sym), arg); + } st_add_direct(arg->symbols, id, arg->symbols->num_entries); } } @@ -360,12 +375,14 @@ w_extended(VALUE klass, struct dump_arg *arg, int check) static void w_class(char type, VALUE obj, struct dump_arg *arg, int check) { + volatile VALUE p; char *path; VALUE klass = CLASS_OF(obj); w_extended(klass, arg, check); w_byte(type, arg); - path = RSTRING_PTR(class2path(rb_class_real(klass))); + p = class2path(rb_class_real(klass)); + path = RSTRING_PTR(p); w_unique(path, arg); } @@ -490,7 +507,7 @@ w_object(VALUE obj, struct dump_arg *arg, int limit) } w_byte(TYPE_CLASS, arg); { - VALUE path = class2path(obj); + volatile VALUE path = class2path(obj); w_bytes(RSTRING_PTR(path), RSTRING_LEN(path), arg); } break; @@ -738,7 +755,9 @@ struct load_arg { int taint; }; +static VALUE r_entry(VALUE v, struct load_arg *arg); static VALUE r_object(struct load_arg *arg); +static VALUE path2class(const char *path); static int r_byte(struct load_arg *arg) @@ -855,10 +874,24 @@ r_symlink(struct load_arg *arg) static ID r_symreal(struct load_arg *arg) { - ID id; volatile VALUE s = r_bytes(arg); + ID id = rb_intern(RSTRING_PTR(s)); + + st_insert(arg->symbols, arg->symbols->num_entries, id); + + return id; +} + +static ID +r_symivar2(struct load_arg *arg) +{ + volatile VALUE s = r_bytes(arg); + ID id = rb_intern(RSTRING_PTR(s)); + VALUE klass; - id = rb_intern(RSTRING_PTR(s)); + s = r_bytes(arg); + klass = r_entry(path2class(RSTRING_PTR(s)), arg); + id = rb_compose_ivar2(id, klass); st_insert(arg->symbols, arg->symbols->num_entries, id); return id; @@ -867,10 +900,19 @@ r_symreal(struct load_arg *arg) static ID r_symbol(struct load_arg *arg) { - if (r_byte(arg) == TYPE_SYMLINK) { + int type; + + switch ((type = r_byte(arg))) { + case TYPE_SYMBOL: + return r_symreal(arg); + case TYPE_SYMBOL2: + return r_symivar2(arg); + case TYPE_SYMLINK: return r_symlink(arg); + default: + rb_raise(rb_eArgError, "dump format error(0x%x)", type); + break; } - return r_symreal(arg); } static const char* @@ -1274,6 +1316,10 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) v = ID2SYM(r_symreal(arg)); break; + case TYPE_SYMBOL2: + v = ID2SYM(r_symivar2(arg)); + break; + case TYPE_SYMLINK: v = ID2SYM(r_symlink(arg)); break; |