diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-02-27 04:50:30 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-02-27 04:50:30 +0000 |
commit | bf95c21de1a5a91a969b2677504da262c8cb1c21 (patch) | |
tree | 9c8fcdf87cfc279f6dd3348de22d1bc74f26f48a /marshal.c | |
parent | a08335cc90e1e6d559b0ead207c42babe424ec57 (diff) |
* eval.c (rb_f_missing): NoMethod error messages for true, false,
nil must respond visibility like for other objects.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_6@2144 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'marshal.c')
-rw-r--r-- | marshal.c | 115 |
1 files changed, 66 insertions, 49 deletions
@@ -750,9 +750,6 @@ r_regist(v, arg) VALUE v; struct load_arg *arg; { - if (arg->proc) { - rb_funcall(arg->proc, rb_intern("call"), 1, v); - } rb_hash_aset(arg->data, INT2FIX(RHASH(arg->data)->tbl->num_entries), v); if (arg->taint) OBJ_TAINT(v); return v; @@ -779,7 +776,7 @@ static VALUE r_object(arg) struct load_arg *arg; { - VALUE v; + VALUE v = Qnil; int type = r_byte(arg); long id; @@ -791,7 +788,6 @@ r_object(arg) rb_raise(rb_eArgError, "dump format error (unlinked)"); } return v; - break; case TYPE_IVAR: v = r_object(arg); @@ -801,47 +797,62 @@ r_object(arg) case TYPE_UCLASS: { VALUE c = rb_path2class(r_unique(arg)); - VALUE tmp; v = r_object(arg); - if (rb_special_const_p(v) || - TYPE(v) == T_OBJECT || TYPE(v) == T_CLASS || TYPE(v) == T_MODULE || - !RTEST(rb_funcall(c, '<', 1, RBASIC(v)->klass))) { + if (rb_special_const_p(v) || TYPE(v) == T_OBJECT || TYPE(v) == T_CLASS) { + format_error: rb_raise(rb_eArgError, "dump format error (user class)"); } -#if 0 - tmp = rb_obj_alloc(c); - if (TYPE(v) != TYPE(tmp)) { - rb_raise(rb_eArgError, "dump format error (user class)"); + if (TYPE(v) == T_MODULE || !RTEST(rb_funcall(c, '<', 1, RBASIC(v)->klass))) { + VALUE tmp = rb_obj_alloc(c); + + if (TYPE(v) != TYPE(tmp)) goto format_error; } -#endif RBASIC(v)->klass = c; return v; } case TYPE_NIL: - return Qnil; + v = Qnil; + break; case TYPE_TRUE: - return Qtrue; + v = Qtrue; + break; case TYPE_FALSE: - return Qfalse; + v = Qfalse; case TYPE_FIXNUM: { long i = r_long(arg); - return INT2FIX(i); + v = INT2FIX(i); } + break; case TYPE_FLOAT: { char *buf; + double d, t = 0.0; r_bytes(buf, arg); - v = rb_float_new(strtod(buf, 0)); - return r_regist(v, arg); + if (strcmp(buf, "nan") == 0) { + d = t / t; + } + else if (strcmp(buf, "inf") == 0) { + d = 1.0 / t; + } + else if (strcmp(buf, "-inf") == 0) { + d = -1.0 / t; + } + else { + /* xxx: should not use system's strtod(3) */ + d = strtod(buf, 0); + } + v = rb_float_new(d); + r_regist(v, arg); } + break; case TYPE_BIGNUM: { @@ -876,15 +887,16 @@ r_object(arg) len--; #endif } - big = RBIGNUM(rb_big_norm((VALUE)big)); - if (TYPE(big) == T_BIGNUM) { - r_regist((VALUE)big, arg); + v = rb_big_norm((VALUE)big); + if (TYPE(v) == T_BIGNUM) { + r_regist(v, arg); } - return (VALUE)big; } + break; case TYPE_STRING: - return r_regist(r_string(arg), arg); + v = r_regist(r_string(arg), arg); + break; case TYPE_REGEXP: { @@ -894,19 +906,21 @@ r_object(arg) r_bytes2(buf, len, arg); options = r_byte(arg); - return r_regist(rb_reg_new(buf, len, options), arg); + v = r_regist(rb_reg_new(buf, len, options), arg); } + break; case TYPE_ARRAY: { volatile long len = r_long(arg); /* gcc 2.7.2.3 -O2 bug?? */ v = rb_ary_new2(len); + r_regist(v, arg); while (len--) { rb_ary_push(v, r_object(arg)); } - return r_regist(v, arg);; } + break; case TYPE_HASH: case TYPE_HASH_DEF: @@ -914,6 +928,7 @@ r_object(arg) long len = r_long(arg); v = rb_hash_new(); + r_regist(v, arg); while (len--) { VALUE key = r_object(arg); VALUE value = r_object(arg); @@ -922,8 +937,8 @@ r_object(arg) if (type == TYPE_HASH_DEF) { RHASH(v)->ifnone = r_object(arg); } - return r_regist(v, arg); } + break; case TYPE_STRUCT: { @@ -944,6 +959,7 @@ r_object(arg) rb_ary_push(values, Qnil); } v = rb_struct_alloc(klass, values); + r_regist(v, arg); for (i=0; i<len; i++) { slot = r_symbol(arg); @@ -955,8 +971,6 @@ r_object(arg) } rb_struct_aset(v, INT2FIX(i), r_object(arg)); } - r_regist(v, arg); - return v; } break; @@ -965,12 +979,12 @@ r_object(arg) VALUE klass; klass = rb_path2class(r_unique(arg)); - if (rb_respond_to(klass, s_load)) { - v = rb_funcall(klass, s_load, 1, r_string(arg)); - return r_regist(v, arg); + if (!rb_respond_to(klass, s_load)) { + rb_raise(rb_eTypeError, "class %s needs to have method `_load'", + rb_class2name(klass)); } - rb_raise(rb_eTypeError, "class %s needs to have method `_load'", - rb_class2name(klass)); + v = rb_funcall(klass, s_load, 1, r_string(arg)); + r_regist(v, arg); } break; @@ -983,8 +997,8 @@ r_object(arg) if (TYPE(v) != T_OBJECT) { rb_raise(rb_eArgError, "dump format error"); } + r_regist(v, arg); r_ivar(v, arg); - return r_regist(v, arg); } break; @@ -992,37 +1006,37 @@ r_object(arg) { char *buf; r_bytes(buf, arg); - return r_regist(rb_path2class(buf), arg); + v = r_regist(rb_path2class(buf), arg); } + break; case TYPE_CLASS: { - VALUE c; - char *buf; r_bytes(buf, arg); - c = rb_path2class(buf); - if (TYPE(c) != T_CLASS) { + v = rb_path2class(buf); + if (TYPE(v) != T_CLASS) { rb_raise(rb_eTypeError, "%s is not a class", buf); } - return r_regist(c, arg); + r_regist(v, arg); } + break; case TYPE_MODULE: { - VALUE m; - char *buf; r_bytes(buf, arg); - m = rb_path2class(buf); - if (TYPE(m) != T_MODULE) { + v = rb_path2class(buf); + if (TYPE(v) != T_MODULE) { rb_raise(rb_eTypeError, "%s is not a module", buf); } - return r_regist(m, arg); + r_regist(v, arg); } + break; case TYPE_SYMBOL: - return ID2SYM(r_symreal(arg)); + v = ID2SYM(r_symreal(arg)); + break; case TYPE_SYMLINK: return ID2SYM(r_symlink(arg)); @@ -1031,7 +1045,10 @@ r_object(arg) rb_raise(rb_eArgError, "dump format error(0x%x)", type); break; } - return Qnil; /* not reached */ + if (arg->proc) { + rb_funcall(arg->proc, rb_intern("yield"), 1, v); + } + return v; } static VALUE |