diff options
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | array.c | 42 | ||||
-rw-r--r-- | eval.c | 4 | ||||
-rw-r--r-- | ext/tk/tkutil.c | 43 | ||||
-rw-r--r-- | gc.c | 16 | ||||
-rw-r--r-- | intern.h | 2 | ||||
-rw-r--r-- | parse.y | 48 | ||||
-rw-r--r-- | re.c | 53 | ||||
-rw-r--r-- | ruby.c | 5 | ||||
-rw-r--r-- | string.c | 5 | ||||
-rw-r--r-- | struct.c | 113 |
11 files changed, 196 insertions, 155 deletions
@@ -1,3 +1,20 @@ +Fri Sep 24 08:29:45 2004 Yukihiro Matsumoto <[email protected]> + + * parse.y (rb_parser_append_print): should handle prelude. + + * parse.y (rb_parser_while_loop): ditto. + + * array.c (rb_ary_subseq): original object might be modified after + sharing data creation. [ruby-dev:24327] + + * array.c (rb_ary_replace): ditto. + + * array.c (ary_make_shared): freeze shared array. [ruby-dev:24325] + + * struct.c (struct_members): always check struct size and size of + members list in the class. [ruby-dev:24320] + Thu Sep 23 19:48:14 2004 Minero Aoki <[email protected]> * ext/ripper/Makefile.dev: removed. @@ -16,6 +33,9 @@ Thu Sep 23 19:48:14 2004 Minero Aoki <[email protected]> Thu Sep 23 09:29:14 2004 Yukihiro Matsumoto <[email protected]> + * string.c (rb_str_sub_bang): check if string is not modified + during iteration. [ruby-dev:24315] + * hash.c (rb_hash_rehash): replace st_foreach() by its deep checking counterpart. [ruby-dev:24310] @@ -237,7 +237,7 @@ rb_values_new2(n, elts) return val; } -static void +static VALUE ary_make_shared(ary) VALUE ary; { @@ -250,6 +250,11 @@ ary_make_shared(ary) shared->aux.capa = RARRAY(ary)->aux.capa; RARRAY(ary)->aux.shared = (VALUE)shared; FL_SET(ary, ELTS_SHARED); + OBJ_FREEZE(shared); + return (VALUE)shared; + } + else { + return RARRAY(ary)->aux.shared; } } @@ -744,7 +749,8 @@ rb_ary_subseq(ary, beg, len) VALUE ary; long beg, len; { - VALUE klass, ary2; + VALUE klass, ary2, shared; + VALUE *ptr; if (beg > RARRAY(ary)->len) return Qnil; if (beg < 0 || len < 0) return Qnil; @@ -757,11 +763,12 @@ rb_ary_subseq(ary, beg, len) klass = rb_obj_class(ary); if (len == 0) return ary_new(klass, 0); - ary_make_shared(ary); + shared = ary_make_shared(ary); + ptr = RARRAY(ary)->ptr; ary2 = ary_alloc(klass); - RARRAY(ary2)->ptr = RARRAY(ary)->ptr + beg; + RARRAY(ary2)->ptr = ptr + beg; RARRAY(ary2)->len = len; - RARRAY(ary2)->aux.shared = RARRAY(ary)->aux.shared; + RARRAY(ary2)->aux.shared = shared; FL_SET(ary2, ELTS_SHARED); return ary2; @@ -1675,7 +1682,6 @@ sort_1(a, b, data) VALUE retval = rb_yield_values(2, *a, *b); int n; - ary_sort_check(data); n = rb_cmpint(retval, *a, *b); ary_sort_check(data); return n; @@ -1700,7 +1706,6 @@ sort_2(ap, bp, data) } retval = rb_funcall(a, id_cmp, 1, b); - ary_sort_check(data); n = rb_cmpint(retval, a, b); ary_sort_check(data); @@ -2263,15 +2268,17 @@ static VALUE rb_ary_replace(copy, orig) VALUE copy, orig; { + VALUE shared; + rb_ary_modify(copy); orig = to_ary(orig); if (copy == orig) return copy; - ary_make_shared(orig); + shared = ary_make_shared(orig); if (RARRAY(copy)->ptr && !FL_TEST(copy, ELTS_SHARED)) free(RARRAY(copy)->ptr); - RARRAY(copy)->ptr = RARRAY(orig)->ptr; - RARRAY(copy)->len = RARRAY(orig)->len; - RARRAY(copy)->aux.shared = RARRAY(orig)->aux.shared; + RARRAY(copy)->ptr = RARRAY(shared)->ptr; + RARRAY(copy)->len = RARRAY(shared)->len; + RARRAY(copy)->aux.shared = shared; FL_SET(copy, ELTS_SHARED); return copy; @@ -2987,8 +2994,11 @@ flatten(ary, idx, ary2, memo) rb_ary_push(memo, id); rb_ary_update(ary, idx, 1, ary2); while (i < lim) { - if (TYPE(RARRAY(ary)->ptr[i]) == T_ARRAY) { - n = flatten(ary, i, RARRAY(ary)->ptr[i], memo); + VALUE tmp; + + tmp = rb_check_array_type(RARRAY(ary)->ptr[i]); + if (!NIL_P(tmp)) { + n = flatten(ary, i, tmp, memo); i += n; lim += n; } i++; @@ -3023,12 +3033,14 @@ rb_ary_flatten_bang(ary) rb_ary_modify(ary); while (i<RARRAY(ary)->len) { VALUE ary2 = RARRAY(ary)->ptr[i]; + VALUE tmp; - if (TYPE(ary2) == T_ARRAY) { + tmp = rb_check_array_type(ary2); + if (!NIL_P(tmp)) { if (NIL_P(memo)) { memo = rb_ary_new(); } - i += flatten(ary, i, ary2, memo); + i += flatten(ary, i, tmp, memo); mod = 1; } i++; @@ -642,8 +642,6 @@ rb_attr(klass, id, read, write, ex) } } -extern int ruby_in_compile; - VALUE ruby_errinfo = Qnil; extern int ruby_nerrs; @@ -2451,7 +2449,6 @@ call_trace_func(event, node, self, id, klass) if (!trace_func) return; if (tracing) return; - if (ruby_in_compile) return; if (id == ID_ALLOCATOR) return; if (!(node_save = ruby_current_node)) { @@ -10379,7 +10376,6 @@ rb_thread_wait_fd(fd) int fd; { if (rb_thread_critical) return; - if (ruby_in_compile) return; if (curr_thread == curr_thread->next) return; if (curr_thread->status == THREAD_TO_KILL) return; diff --git a/ext/tk/tkutil.c b/ext/tk/tkutil.c index 0595207fe3..c0dc48e59b 100644 --- a/ext/tk/tkutil.c +++ b/ext/tk/tkutil.c @@ -197,15 +197,26 @@ fromUTF8_toDefaultEnc(str, self) } +static void +hash_check(err) + int err; +{ + if (err) { + rb_raise(rb_eRuntimeError, "hash modified"); + } +} + static int -to_strkey(key, value, hash) +to_strkey(key, value, hash, err) VALUE key; VALUE value; VALUE hash; + int err; { + hash_check(err); if (key == Qundef) return ST_CONTINUE; rb_hash_aset(hash, rb_funcall(key, ID_to_s, 0, 0), value); - return ST_CONTINUE; + return ST_CHECK; } static VALUE @@ -216,9 +227,7 @@ tk_symbolkey2str(self, keys) volatile VALUE new_keys = rb_hash_new(); if NIL_P(keys) return new_keys; - if (TYPE(keys) != T_HASH) { - rb_raise(rb_eArgError, "Hash is expected"); - } + keys = rb_convert_type(keys, T_HASH, "Hash", "to_hash"); st_foreach(RHASH(keys)->tbl, to_strkey, new_keys); return new_keys; } @@ -437,12 +446,16 @@ assoc2kv_enc(assoc, ary, self) } static int -push_kv(key, val, args) +push_kv(key, val, args, err) VALUE key; VALUE val; VALUE args; + int err; { - volatile VALUE ary = RARRAY(args)->ptr[0]; + volatile VALUE ary; + + hash_check(err); + ary = RARRAY(args)->ptr[0]; if (key == Qundef) return ST_CONTINUE; #if 0 @@ -451,12 +464,12 @@ push_kv(key, val, args) #endif RARRAY(ary)->ptr[RARRAY(ary)->len++] = key2keyname(key); - if (val == TK_None) return ST_CONTINUE; + if (val == TK_None) return ST_CHECK; RARRAY(ary)->ptr[RARRAY(ary)->len++] = get_eval_string_core(val, Qnil, RARRAY(args)->ptr[1]); - return ST_CONTINUE; + return ST_CHECK; } static VALUE @@ -483,12 +496,16 @@ hash2kv(hash, ary, self) } static int -push_kv_enc(key, val, args) +push_kv_enc(key, val, args, err) VALUE key; VALUE val; VALUE args; + int err; { - volatile VALUE ary = RARRAY(args)->ptr[0]; + volatile VALUE ary; + + hash_check(err); + ary = RARRAY(args)->ptr[0]; if (key == Qundef) return ST_CONTINUE; #if 0 @@ -500,12 +517,12 @@ push_kv_enc(key, val, args) #endif RARRAY(ary)->ptr[RARRAY(ary)->len++] = key2keyname(key); - if (val == TK_None) return ST_CONTINUE; + if (val == TK_None) return ST_CHECK; RARRAY(ary)->ptr[RARRAY(ary)->len++] = get_eval_string_core(val, Qtrue, RARRAY(args)->ptr[1]); - return ST_CONTINUE; + return ST_CHECK; } static VALUE @@ -178,7 +178,6 @@ ruby_xfree(x) RUBY_CRITICAL(free(x)); } -extern int ruby_in_compile; static int dont_gc; static int during_gc; static int need_call_final = 0; @@ -1001,19 +1000,6 @@ gc_sweep() int i, j; unsigned long live = 0; - if (ruby_in_compile && ruby_parser_stack_on_heap()) { - /* should not reclaim nodes during compilation - if yacc's semantic stack is not allocated on machine stack */ - for (i = 0; i < heaps_used; i++) { - p = heaps[i].slot; pend = p + heaps[i].limit; - while (p < pend) { - if (!(p->as.basic.flags&FL_MARK) && BUILTIN_TYPE(p) == T_NODE) - gc_mark((VALUE)p, 0); - p++; - } - } - } - mark_source_filename(ruby_sourcefile); st_foreach(source_filenames, sweep_source_filename, 0); @@ -1080,7 +1066,7 @@ gc_sweep() if (final_list) { RVALUE *tmp; - if (rb_prohibit_interrupt || ruby_in_compile) { + if (rb_prohibit_interrupt) { deferred_final_list = final_list; return; } @@ -326,7 +326,6 @@ double rb_str_to_dbl _((VALUE, int)); RUBY_EXTERN int ruby_sourceline; RUBY_EXTERN char *ruby_sourcefile; ID rb_id_attrset _((ID)); -int ruby_parser_stack_on_heap _((void)); void rb_gc_mark_parser _((void)); int rb_is_const_id _((ID)); int rb_is_instance_id _((ID)); @@ -370,6 +369,7 @@ VALUE rb_reg_match_pre _((VALUE)); VALUE rb_reg_match_post _((VALUE)); VALUE rb_reg_match_last _((VALUE)); VALUE rb_reg_new _((const char*, long, int)); +VALUE rb_reg_compile _((const char*, long, int)); VALUE rb_reg_match _((VALUE, VALUE)); VALUE rb_reg_match2 _((VALUE)); int rb_reg_options _((VALUE)); @@ -141,7 +141,6 @@ struct parser_params { int parser_lex_gets_ptr; VALUE (*parser_lex_gets) _((struct parser_params*,VALUE)); #ifdef RIPPER - int parser_ruby_in_compile; int parser_ruby__end__seen; int parser_ruby_sourceline; VALUE parser_ruby_sourcefile; @@ -185,7 +184,6 @@ static int parser_yyerror _((struct parser_params*, const char*)); #define lex_gets_ptr (parser->parser_lex_gets_ptr) #define lex_gets (parser->parser_lex_gets) #ifdef RIPPER -#define ruby_in_compile (parser->parser_ruby_in_compile) #define ruby__end__seen (parser->parser_ruby__end__seen) #define ruby_sourceline (parser->parser_ruby_sourceline) #define ruby_sourcefile (parser->parser_ruby_sourcefile) @@ -3388,16 +3386,16 @@ regexp : tREGEXP_BEG xstring_contents tREGEXP_END int options = $3; NODE *node = $2; if (!node) { - node = NEW_LIT(rb_reg_new("", 0, options & ~RE_OPTION_ONCE)); + node = NEW_LIT(rb_reg_compile("", 0, options & ~RE_OPTION_ONCE)); } else switch (nd_type(node)) { case NODE_STR: { VALUE src = node->nd_lit; nd_set_type(node, NODE_LIT); - node->nd_lit = rb_reg_new(RSTRING(src)->ptr, - RSTRING(src)->len, - options & ~RE_OPTION_ONCE); + node->nd_lit = rb_reg_compile(RSTRING(src)->ptr, + RSTRING(src)->len, + options & ~RE_OPTION_ONCE); } break; default: @@ -4292,7 +4290,6 @@ parser_yyerror(parser, msg) } #ifndef RIPPER -int ruby_in_compile = 0; int ruby__end__seen; static VALUE ruby_debug_lines; @@ -4306,7 +4303,6 @@ yycompile(parser, f, line) NODE *node = 0; struct RVarmap *vp, *vars = ruby_dyna_vars; - ruby_in_compile = 1; if (!compile_for_eval && rb_safe_level() == 0 && rb_const_defined(rb_cObject, rb_intern("SCRIPT_LINES__"))) { VALUE hash, fname; @@ -4334,7 +4330,6 @@ yycompile(parser, f, line) n = yyparse((void*)parser); ruby_debug_lines = 0; compile_for_eval = 0; - ruby_in_compile = 0; vp = ruby_dyna_vars; ruby_dyna_vars = vars; @@ -7727,16 +7722,6 @@ dyna_init(node, pre) return block_append(var, node); } -int -ruby_parser_stack_on_heap() -{ -#if defined(YYBISON) && !defined(C_ALLOCA) - return Qfalse; -#else - return Qtrue; -#endif -} - void rb_gc_mark_parser() { @@ -7747,9 +7732,19 @@ NODE* rb_parser_append_print(node) NODE *node; { - return block_append(node, + NODE *prelude = (nd_type(node) == NODE_PRELUDE) ? node : 0; + + if (prelude) { + node = node->nd_body; + } + node = block_append(node, NEW_FCALL(rb_intern("print"), NEW_ARRAY(NEW_GVAR(rb_intern("$_"))))); + if (prelude) { + prelude->nd_body = node; + return prelude; + } + return node; } NODE * @@ -7757,6 +7752,11 @@ rb_parser_while_loop(node, chop, split) NODE *node; int chop, split; { + NODE *prelude = (nd_type(node) == NODE_PRELUDE) ? node : 0; + + if (prelude) { + node = node->nd_body; + } if (split) { node = block_append(NEW_GASGN(rb_intern("$F"), NEW_CALL(NEW_GVAR(rb_intern("$_")), @@ -7767,7 +7767,12 @@ rb_parser_while_loop(node, chop, split) node = block_append(NEW_CALL(NEW_GVAR(rb_intern("$_")), rb_intern("chop!"), 0), node); } - return NEW_OPT_N(node); + node = NEW_OPT_N(node); + if (prelude) { + prelude->nd_body = node; + return prelude; + } + return node; } static struct { @@ -8513,7 +8518,6 @@ ripper_initialize(argc, argv, self) parser_initialize(parser); parser->parser_ruby_sourcefile = fname; parser->parser_ruby_sourceline = NIL_P(lineno) ? 0 : NUM2INT(lineno) - 1; - parser->parser_ruby_in_compile = Qtrue; parser->parser_ruby__end__seen = 0; return Qnil; @@ -266,8 +266,6 @@ rb_reg_check(re) } } -extern int ruby_in_compile; - static void rb_reg_expr_str(str, s, len) VALUE str; @@ -520,15 +518,16 @@ rb_reg_to_s(re) } static void -rb_reg_raise(s, len, err, re) +rb_reg_raise(s, len, err, re, ce) const char *s; long len; const char *err; VALUE re; + int ce; { VALUE desc = rb_reg_desc(s, len, re); - if (ruby_in_compile) + if (ce) rb_compile_error("%s: %s", err, RSTRING(desc)->ptr); else rb_raise(rb_eRegexpError, "%s: %s", err, RSTRING(desc)->ptr); @@ -617,10 +616,11 @@ rb_reg_kcode_m(re) } static Regexp* -make_regexp(s, len, flags) +make_regexp(s, len, flags, ce) const char *s; long len; int flags; + int ce; { Regexp *rp; char err[ONIG_MAX_ERROR_MESSAGE_LEN]; @@ -636,7 +636,7 @@ make_regexp(s, len, flags) r = re_alloc_pattern(&rp); if (r) { re_error_code_to_str((UChar* )err, r); - rb_reg_raise(s, len, err, 0); + rb_reg_raise(s, len, err, 0, ce); } if (flags) { @@ -645,7 +645,7 @@ make_regexp(s, len, flags) r = re_compile_pattern(s, len, rp, err); if (r != 0) { - rb_reg_raise(s, len, err, 0); + rb_reg_raise(s, len, err, 0, ce); } return rp; } @@ -854,7 +854,7 @@ rb_reg_prepare_re(re) rb_reg_check(re); r = re_recompile_pattern(RREGEXP(re)->str, RREGEXP(re)->len, RREGEXP(re)->ptr, err); if (r != 0) { - rb_reg_raise(RREGEXP(re)->str, RREGEXP(re)->len, err, re); + rb_reg_raise(RREGEXP(re)->str, RREGEXP(re)->len, err, re, Qfalse); } } } @@ -921,15 +921,15 @@ rb_reg_search(re, str, pos, reverse) kcode_reset_option(); if (result < 0) { - if (result == ONIG_MISMATCH) { - rb_backref_set(Qnil); - return result; - } - else { - char err[ONIG_MAX_ERROR_MESSAGE_LEN]; - re_error_code_to_str((UChar* )err, result); - rb_reg_raise(RREGEXP(re)->str, RREGEXP(re)->len, err, 0); - } + if (result == ONIG_MISMATCH) { + rb_backref_set(Qnil); + return result; + } + else { + char err[ONIG_MAX_ERROR_MESSAGE_LEN]; + re_error_code_to_str((UChar* )err, result); + rb_reg_raise(RREGEXP(re)->str, RREGEXP(re)->len, err, 0, Qfalse); + } } match = rb_backref_get(); @@ -1322,7 +1322,7 @@ match_string(match) VALUE rb_cRegexp; static void -rb_reg_initialize(obj, s, len, options) +rb_reg_initialize(obj, s, len, options, ce) VALUE obj; const char *s; long len; @@ -1333,6 +1333,7 @@ rb_reg_initialize(obj, s, len, options) /* CODE_EUC = 32 */ /* CODE_SJIS = 48 */ /* CODE_UTF8 = 64 */ + int ce; /* call rb_compile_error() */ { struct RRegexp *re = RREGEXP(obj); @@ -1367,7 +1368,7 @@ rb_reg_initialize(obj, s, len, options) options |= RE_OPTION_IGNORECASE; FL_SET(re, REG_CASESTATE); } - re->ptr = make_regexp(s, len, options & 0xf); + re->ptr = make_regexp(s, len, options & 0xf, ce); re->str = ALLOC_N(char, len+1); memcpy(re->str, s, len); re->str[len] = '\0'; @@ -1400,7 +1401,19 @@ rb_reg_new(s, len, options) { VALUE re = rb_reg_s_alloc(rb_cRegexp); - rb_reg_initialize(re, s, len, options); + rb_reg_initialize(re, s, len, options, Qfalse); + return (VALUE)re; +} + +VALUE +rb_reg_compile(s, len, options) + const char *s; + long len; + int options; +{ + VALUE re = rb_reg_s_alloc(rb_cRegexp); + + rb_reg_initialize(re, s, len, options, Qtrue); return (VALUE)re; } @@ -341,7 +341,6 @@ static void require_libraries() { extern NODE *ruby_eval_tree; - extern NODE *ruby_eval_tree_begin; NODE *save[3]; struct req_list *list = req_list_head.next; struct req_list *tmp; @@ -916,10 +915,6 @@ load_file(fname, script) else if (f != rb_stdin) { rb_io_close(f); } - - if (ruby_parser_stack_on_heap()) { - rb_gc(); - } } void @@ -1927,8 +1927,13 @@ rb_str_sub_bang(argc, argv, str) regs = RMATCH(match)->regs; if (iter) { + char *p = RSTRING(str)->ptr; long len = RSTRING(str)->len; + rb_match_busy(match); repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match))); + if (RSTRING(str)->ptr != p || RSTRING(str)->len != len) { + rb_raise(rb_eRuntimeError, "string modified"); + } rb_backref_set(match); } else { @@ -34,18 +34,31 @@ rb_struct_iv_get(c, name) } static VALUE +struct_members(s) + VALUE s; +{ + VALUE members = rb_struct_iv_get(rb_obj_class(s), "__members__"); + + if (NIL_P(members)) { + rb_bug("non-initialized struct"); + } + if (RSTRUCT(s)->len != RARRAY(members)->len) { + rb_raise(rb_eTypeError, "struct size differs (%d required %d given)", + RARRAY(members)->len, RSTRUCT(s)->len); + } + return members; +} + +static VALUE rb_struct_s_members(obj) VALUE obj; { - VALUE member, ary; + VALUE members, ary; VALUE *p, *pend; - member = rb_struct_iv_get(obj, "__member__"); - if (NIL_P(member)) { - rb_bug("uninitialized struct"); - } - ary = rb_ary_new2(RARRAY(member)->len); - p = RARRAY(member)->ptr; pend = p + RARRAY(member)->len; + members = struct_members(obj); + ary = rb_ary_new2(RARRAY(members)->len); + p = RARRAY(members)->ptr; pend = p + RARRAY(members)->len; while (p < pend) { rb_ary_push(ary, rb_str_new2(rb_id2name(SYM2ID(*p)))); p++; @@ -78,16 +91,13 @@ rb_struct_getmember(obj, id) VALUE obj; ID id; { - VALUE member, slot; + VALUE members, slot; long i; - member = rb_struct_iv_get(rb_obj_class(obj), "__member__"); - if (NIL_P(member)) { - rb_bug("uninitialized struct"); - } + members = struct_members(obj); slot = ID2SYM(id); - for (i=0; i<RARRAY(member)->len; i++) { - if (RARRAY(member)->ptr[i] == slot) { + for (i=0; i<RARRAY(members)->len; i++) { + if (RARRAY(members)->ptr[i] == slot) { return RSTRUCT(obj)->ptr[i]; } } @@ -139,16 +149,13 @@ static VALUE rb_struct_set(obj, val) VALUE obj, val; { - VALUE member, slot; + VALUE members, slot; long i; - member = rb_struct_iv_get(rb_obj_class(obj), "__member__"); - if (NIL_P(member)) { - rb_bug("uninitialized struct"); - } + members = struct_members(obj); rb_struct_modify(obj); - for (i=0; i<RARRAY(member)->len; i++) { - slot = RARRAY(member)->ptr[i]; + for (i=0; i<RARRAY(members)->len; i++) { + slot = RARRAY(members)->ptr[i]; if (rb_id_attrset(SYM2ID(slot)) == rb_frame_last_func()) { return RSTRUCT(obj)->ptr[i] = val; } @@ -159,13 +166,14 @@ rb_struct_set(obj, val) } static VALUE -make_struct(name, member, klass) - VALUE name, member, klass; +make_struct(name, members, klass) + VALUE name, members, klass; { VALUE nstr; ID id; long i; + OBJ_FREEZE(members); if (NIL_P(name)) { nstr = rb_class_new(klass); rb_make_metaclass(nstr, RBASIC(klass)->klass); @@ -183,15 +191,15 @@ make_struct(name, member, klass) } nstr = rb_define_class_under(klass, cname, klass); } - rb_iv_set(nstr, "__size__", LONG2NUM(RARRAY(member)->len)); - rb_iv_set(nstr, "__member__", member); + rb_iv_set(nstr, "__size__", LONG2NUM(RARRAY(members)->len)); + rb_iv_set(nstr, "__members__", members); rb_define_alloc_func(nstr, struct_alloc); rb_define_singleton_method(nstr, "new", rb_class_new_instance, -1); rb_define_singleton_method(nstr, "[]", rb_class_new_instance, -1); rb_define_singleton_method(nstr, "members", rb_struct_s_members, 0); - for (i=0; i< RARRAY(member)->len; i++) { - ID id = SYM2ID(RARRAY(member)->ptr[i]); + for (i=0; i< RARRAY(members)->len; i++) { + ID id = SYM2ID(RARRAY(members)->ptr[i]); if (i<10) { rb_define_method_id(nstr, id, ref_func[i], 0); } @@ -434,15 +442,12 @@ static VALUE rb_struct_each_pair(s) VALUE s; { - VALUE member; + VALUE members; long i; - member = rb_struct_iv_get(rb_obj_class(s), "__member__"); - if (NIL_P(member)) { - rb_bug("non-initialized struct"); - } + members = struct_members(s); for (i=0; i<RSTRUCT(s)->len; i++) { - rb_yield_values(2, RARRAY(member)->ptr[i], RSTRUCT(s)->ptr[i]); + rb_yield_values(2, rb_ary_entry(members, i), RSTRUCT(s)->ptr[i]); } return s; } @@ -452,18 +457,10 @@ inspect_struct(s) VALUE s; { char *cname = rb_class2name(rb_obj_class(s)); - VALUE str, member; + VALUE str, members; long i; - member = rb_struct_iv_get(rb_obj_class(s), "__member__"); - if (NIL_P(member)) { - rb_bug("non-initialized struct"); - } - if (RSTRUCT(s)->len != RARRAY(member)->len) { - rb_raise(rb_eTypeError, "struct size differs (%d required %d given)", - RARRAY(member)->len, RSTRUCT(s)->len); - } - + members = struct_members(s); str = rb_str_buf_new2("#<struct "); rb_str_cat2(str, cname); rb_str_cat2(str, " "); @@ -474,7 +471,7 @@ inspect_struct(s) if (i > 0) { rb_str_cat2(str, ", "); } - slot = RARRAY(member)->ptr[i]; + slot = RARRAY(members)->ptr[i]; p = rb_id2name(SYM2ID(slot)); rb_str_cat2(str, p); rb_str_cat2(str, "="); @@ -551,17 +548,13 @@ rb_struct_aref_id(s, id) VALUE s; ID id; { - VALUE member; + VALUE members; long i, len; - member = rb_struct_iv_get(rb_obj_class(s), "__member__"); - if (NIL_P(member)) { - rb_bug("non-initialized struct"); - } - - len = RARRAY(member)->len; + members = struct_members(s); + len = RARRAY(members)->len; for (i=0; i<len; i++) { - if (SYM2ID(RARRAY(member)->ptr[i]) == id) { + if (SYM2ID(RARRAY(members)->ptr[i]) == id) { return RSTRUCT(s)->ptr[i]; } } @@ -614,18 +607,18 @@ rb_struct_aset_id(s, id, val) VALUE s, val; ID id; { - VALUE member; + VALUE members; long i, len; - member = rb_struct_iv_get(rb_obj_class(s), "__member__"); - if (NIL_P(member)) { - rb_bug("non-initialized struct"); - } - + members = struct_members(s); rb_struct_modify(s); - len = RARRAY(member)->len; + len = RARRAY(members)->len; + if (RSTRUCT(s)->len != RARRAY(members)->len) { + rb_raise(rb_eTypeError, "struct size differs (%d required %d given)", + RARRAY(members)->len, RSTRUCT(s)->len); + } for (i=0; i<len; i++) { - if (SYM2ID(RARRAY(member)->ptr[i]) == id) { + if (SYM2ID(RARRAY(members)->ptr[i]) == id) { RSTRUCT(s)->ptr[i] = val; return val; } |