diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-09-29 05:15:33 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-09-29 05:15:33 +0000 |
commit | 30116ff8c286c91090722f4d6aada2cc47fcae7e (patch) | |
tree | 020bde425e972437d6945522f1d628236286e106 | |
parent | c0e71a8a97b907ab934d02d3cc4d9e55538a2e5f (diff) | |
download | ruby-30116ff8c286c91090722f4d6aada2cc47fcae7e.tar.gz |
* array.c (rb_ary_delete): comparison may change the capacity.
[ruby-dev:24348]
* array.c (rb_ary_fill): fill should honor length argument.
[ruby-dev:24346]
* array.c (rb_ary_replace): should not use ptr from shared array.
[ruby-dev:24345]
* ext/socket/socket.c (s_accept): don't retry for EWOULDBLOCK.
[ruby-talk:113807]
* array.c (flatten): element size might change during comparison.
[ruby-dev:24343]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6972 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | array.c | 20 | ||||
-rw-r--r-- | ext/socket/socket.c | 2 | ||||
-rw-r--r-- | hash.c | 136 | ||||
-rw-r--r-- | intern.h | 2 | ||||
-rw-r--r-- | marshal.c | 4 | ||||
-rw-r--r-- | object.c | 2 | ||||
-rw-r--r-- | variable.c | 22 |
8 files changed, 132 insertions, 76 deletions
@@ -22,16 +22,30 @@ Mon Sep 27 13:46:45 2004 Nobuyoshi Nakada <nobu@ruby-lang.org> * marshal.c (w_object, r_object0): use accessors. +Mon Sep 27 09:14:03 2004 Yukihiro Matsumoto <matz@ruby-lang.org> + + * array.c (rb_ary_delete): comparison may change the capacity. + [ruby-dev:24348] + + * array.c (rb_ary_fill): fill should honor length argument. + [ruby-dev:24346] + + * array.c (rb_ary_replace): should not use ptr from shared array. + [ruby-dev:24345] + + * ext/socket/socket.c (s_accept): don't retry for EWOULDBLOCK. + [ruby-talk:113807] + Sun Sep 26 08:05:10 2004 Tadayoshi Funaba <tadf@dotrb.org> * lib/date.rb: provides {Time,Date,DateTime}#to_{time,date,datetime}. * sample/cal.rb: uses getoptlong instead of getopts. -Sat Sep 25 04:04:52 2004 Nobuyoshi Nakada <nobu@ruby-lang.org> +Sat Sep 25 18:39:22 2004 Yukihiro Matsumoto <matz@ruby-lang.org> - * hash.c: iterator functions for hash_foreach() should return enum - st_retval. + * array.c (flatten): element size might change during comparison. + [ruby-dev:24343] Sat Sep 25 01:52:49 2004 Yukihiro Matsumoto <matz@ruby-lang.org> @@ -1961,8 +1961,7 @@ rb_ary_delete(ary, item) if (rb_equal(e, item)) continue; if (i1 != i2) { - if (RARRAY(ary)->len < i2) break; - RARRAY(ary)->ptr[i2] = e; + rb_ary_store(ary, i2, e); } i2++; } @@ -1973,12 +1972,13 @@ rb_ary_delete(ary, item) return Qnil; } - if (RARRAY(ary)->len > i2) + if (RARRAY(ary)->len > i2) { RARRAY(ary)->len = i2; - if (i2 * 2 < RARRAY(ary)->aux.capa && + if (i2 * 2 < RARRAY(ary)->aux.capa && RARRAY(ary)->aux.capa > ARY_DEFAULT_SIZE) { - REALLOC_N(RARRAY(ary)->ptr, VALUE, i2 * 2); - RARRAY(ary)->aux.capa = i2 * 2; + REALLOC_N(RARRAY(ary)->ptr, VALUE, i2 * 2); + RARRAY(ary)->aux.capa = i2 * 2; + } } return item; @@ -2276,8 +2276,8 @@ rb_ary_replace(copy, orig) shared = ary_make_shared(orig); if (RARRAY(copy)->ptr && !FL_TEST(copy, ELTS_SHARED)) free(RARRAY(copy)->ptr); - RARRAY(copy)->ptr = RARRAY(shared)->ptr; - RARRAY(copy)->len = RARRAY(shared)->len; + RARRAY(copy)->ptr = RARRAY(orig)->ptr; + RARRAY(copy)->len = RARRAY(orig)->len; RARRAY(copy)->aux.shared = shared; FL_SET(copy, ELTS_SHARED); @@ -2386,7 +2386,7 @@ rb_ary_fill(argc, argv, ary) VALUE v; long i; - for (i=beg; i<RARRAY(ary)->len; i++) { + for (i=beg; i<end; i++) { v = rb_yield(LONG2NUM(i)); if (i>=RARRAY(ary)->len) break; RARRAY(ary)->ptr[i] = v; @@ -2996,7 +2996,7 @@ flatten(ary, idx, ary2, memo) while (i < lim) { VALUE tmp; - tmp = rb_check_array_type(RARRAY(ary)->ptr[i]); + tmp = rb_check_array_type(rb_ary_elt(ary, i)); if (!NIL_P(tmp)) { n = flatten(ary, i, tmp, memo); i += n; lim += n; diff --git a/ext/socket/socket.c b/ext/socket/socket.c index ffa49fbc03..979eaa0af3 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -1250,6 +1250,8 @@ s_accept(klass, fd, sockaddr, len) rb_gc(); retry = 1; goto retry; + case EWOULDBLOCK: + break; default: if (!rb_io_wait_readable(fd)) break; retry = 0; @@ -104,9 +104,47 @@ static struct st_hash_type objhash = { rb_any_hash, }; +struct foreach_safe_arg { + st_table *tbl; + int (*func)(); + st_data_t arg; +}; + +static int +foreach_safe_i(key, value, arg, err) + st_data_t key, value; + struct foreach_safe_arg *arg; +{ + int status; + + if (err) { + rb_raise(rb_eRuntimeError, "hash modified during iteration"); + } + if (key == Qundef) return ST_CONTINUE; + status = (*arg->func)(key, value, arg->arg, err); + if (status == ST_CONTINUE) { + return ST_CHECK; + } + return status; +} + +void +st_foreach_safe(table, func, a) + st_table *table; + int (*func)(); + st_data_t a; +{ + struct foreach_safe_arg arg; + + arg.tbl = table; + arg.func = func; + arg.arg = a; + st_foreach(table, foreach_safe_i, (st_data_t)&arg); +} + struct hash_foreach_arg { VALUE hash; - enum st_retval (*func)(); + int (*func)(); VALUE arg; }; @@ -163,10 +201,10 @@ hash_foreach_call(arg) return Qnil; } -static int -hash_foreach(hash, func, farg) +void +rb_hash_foreach(hash, func, farg) VALUE hash; - enum st_retval (*func)(); + int (*func)(); VALUE farg; { struct hash_foreach_arg arg; @@ -175,7 +213,7 @@ hash_foreach(hash, func, farg) arg.hash = hash; arg.func = func; arg.arg = farg; - return rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash); + rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash); } static VALUE hash_alloc _((VALUE)); @@ -318,7 +356,7 @@ to_hash(hash) return rb_convert_type(hash, T_HASH, "Hash", "to_hash"); } -static enum st_retval +static int rb_hash_rehash_i(key, value, tbl) VALUE key, value; st_table *tbl; @@ -358,7 +396,7 @@ rb_hash_rehash(hash) } rb_hash_modify(hash); tbl = st_init_table_with_size(&objhash, RHASH(hash)->tbl->num_entries); - hash_foreach(hash, rb_hash_rehash_i, (st_data_t)tbl); + rb_hash_foreach(hash, rb_hash_rehash_i, (st_data_t)tbl); st_free_table(RHASH(hash)->tbl); RHASH(hash)->tbl = tbl; @@ -537,7 +575,7 @@ rb_hash_default_proc(hash) return Qnil; } -static enum st_retval +static int key_i(key, value, args) VALUE key, value; VALUE *args; @@ -570,7 +608,7 @@ rb_hash_key(hash, value) args[0] = value; args[1] = Qnil; - hash_foreach(hash, key_i, (st_data_t)args); + rb_hash_foreach(hash, key_i, (st_data_t)args); return args[1]; } @@ -628,7 +666,7 @@ struct shift_var { VALUE val; }; -static enum st_retval +static int shift_i(key, value, var) VALUE key, value; struct shift_var *var; @@ -662,7 +700,7 @@ rb_hash_shift(hash) rb_hash_modify(hash); var.stop = 0; - hash_foreach(hash, shift_i, (st_data_t)&var); + rb_hash_foreach(hash, shift_i, (st_data_t)&var); if (var.stop) { return rb_assoc_new(var.key, var.val); @@ -675,7 +713,7 @@ rb_hash_shift(hash) } } -static enum st_retval +static int delete_if_i(key, value, hash) VALUE key, value, hash; { @@ -703,7 +741,7 @@ rb_hash_delete_if(hash) VALUE hash; { rb_hash_modify(hash); - hash_foreach(hash, delete_if_i, hash); + rb_hash_foreach(hash, delete_if_i, hash); return hash; } @@ -742,7 +780,7 @@ rb_hash_reject(hash) return rb_hash_delete_if(rb_obj_dup(hash)); } -static enum st_retval +static int select_i(key, value, result) VALUE key, value, result; { @@ -798,11 +836,11 @@ rb_hash_select(hash) VALUE result; result = rb_ary_new(); - hash_foreach(hash, select_i, result); + rb_hash_foreach(hash, select_i, result); return result; } -static enum st_retval +static int clear_i(key, value, dummy) VALUE key, value, dummy; { @@ -828,7 +866,7 @@ rb_hash_clear(hash) rb_hash_modify(hash); if (RHASH(hash)->tbl->num_entries > 0) { - hash_foreach(hash, clear_i, 0); + rb_hash_foreach(hash, clear_i, 0); } return hash; @@ -866,7 +904,7 @@ rb_hash_aset(hash, key, val) return val; } -static enum st_retval +static int replace_i(key, val, hash) VALUE key, val, hash; { @@ -896,7 +934,7 @@ rb_hash_replace(hash, hash2) hash2 = to_hash(hash2); if (hash == hash2) return hash; rb_hash_clear(hash); - hash_foreach(hash2, replace_i, hash); + rb_hash_foreach(hash2, replace_i, hash); RHASH(hash)->ifnone = RHASH(hash2)->ifnone; if (FL_TEST(hash2, HASH_PROC_DEFAULT)) { FL_SET(hash, HASH_PROC_DEFAULT); @@ -948,7 +986,7 @@ rb_hash_empty_p(hash) return Qfalse; } -static enum st_retval +static int each_value_i(key, value) VALUE key, value; { @@ -977,11 +1015,11 @@ static VALUE rb_hash_each_value(hash) VALUE hash; { - hash_foreach(hash, each_value_i, 0); + rb_hash_foreach(hash, each_value_i, 0); return hash; } -static enum st_retval +static int each_key_i(key, value) VALUE key, value; { @@ -1009,11 +1047,11 @@ static VALUE rb_hash_each_key(hash) VALUE hash; { - hash_foreach(hash, each_key_i, 0); + rb_hash_foreach(hash, each_key_i, 0); return hash; } -static enum st_retval +static int each_pair_i(key, value) VALUE key, value; { @@ -1043,11 +1081,11 @@ static VALUE rb_hash_each_pair(hash) VALUE hash; { - hash_foreach(hash, each_pair_i, 0); + rb_hash_foreach(hash, each_pair_i, 0); return hash; } -static enum st_retval +static int each_i(key, value) VALUE key, value; { @@ -1080,11 +1118,11 @@ static VALUE rb_hash_each(hash) VALUE hash; { - hash_foreach(hash, each_i, 0); + rb_hash_foreach(hash, each_i, 0); return hash; } -static enum st_retval +static int to_a_i(key, value, ary) VALUE key, value, ary; { @@ -1111,7 +1149,7 @@ rb_hash_to_a(hash) VALUE ary; ary = rb_ary_new(); - hash_foreach(hash, to_a_i, ary); + rb_hash_foreach(hash, to_a_i, ary); if (OBJ_TAINTED(hash)) OBJ_TAINT(ary); return ary; @@ -1141,7 +1179,7 @@ rb_hash_sort(hash) return entries; } -static enum st_retval +static int inspect_i(key, value, str) VALUE key, value, str; { @@ -1169,7 +1207,7 @@ inspect_hash(hash) VALUE str; str = rb_str_buf_new2("{"); - hash_foreach(hash, inspect_i, str); + rb_hash_foreach(hash, inspect_i, str); rb_str_buf_cat2(str, "}"); OBJ_INFECT(str, hash); @@ -1235,7 +1273,7 @@ rb_hash_to_hash(hash) return hash; } -static enum st_retval +static int keys_i(key, value, ary) VALUE key, value, ary; { @@ -1263,12 +1301,12 @@ rb_hash_keys(hash) VALUE ary; ary = rb_ary_new(); - hash_foreach(hash, keys_i, ary); + rb_hash_foreach(hash, keys_i, ary); return ary; } -static enum st_retval +static int values_i(key, value, ary) VALUE key, value, ary; { @@ -1296,7 +1334,7 @@ rb_hash_values(hash) VALUE ary; ary = rb_ary_new(); - hash_foreach(hash, values_i, ary); + rb_hash_foreach(hash, values_i, ary); return ary; } @@ -1327,7 +1365,7 @@ rb_hash_has_key(hash, key) return Qfalse; } -static enum st_retval +static int rb_hash_search_value(key, value, data) VALUE key, value, *data; { @@ -1361,7 +1399,7 @@ rb_hash_has_value(hash, val) data[0] = Qfalse; data[1] = val; - hash_foreach(hash, rb_hash_search_value, (st_data_t)data); + rb_hash_foreach(hash, rb_hash_search_value, (st_data_t)data); return data[0]; } @@ -1370,7 +1408,7 @@ struct equal_data { st_table *tbl; }; -static enum st_retval +static int equal_i(key, val1, data) VALUE key, val1; struct equal_data *data; @@ -1413,7 +1451,7 @@ hash_equal(hash1, hash2, eql) data.tbl = RHASH(hash2)->tbl; data.result = Qtrue; - hash_foreach(hash1, equal_i, (st_data_t)&data); + rb_hash_foreach(hash1, equal_i, (st_data_t)&data); return data.result; } @@ -1460,7 +1498,7 @@ rb_hash_eql(hash1, hash2) return hash_equal(hash1, hash2, Qtrue); } -static enum st_retval +static int rb_hash_invert_i(key, value, hash) VALUE key, value; VALUE hash; @@ -1488,11 +1526,11 @@ rb_hash_invert(hash) { VALUE h = rb_hash_new(); - hash_foreach(hash, rb_hash_invert_i, h); + rb_hash_foreach(hash, rb_hash_invert_i, h); return h; } -static enum st_retval +static int rb_hash_update_i(key, value, hash) VALUE key, value; VALUE hash; @@ -1502,7 +1540,7 @@ rb_hash_update_i(key, value, hash) return ST_CONTINUE; } -static enum st_retval +static int rb_hash_update_block_i(key, value, hash) VALUE key, value; VALUE hash; @@ -1534,10 +1572,10 @@ rb_hash_update(hash1, hash2) { hash2 = to_hash(hash2); if (rb_block_given_p()) { - hash_foreach(hash2, rb_hash_update_block_i, hash1); + rb_hash_foreach(hash2, rb_hash_update_block_i, hash1); } else { - hash_foreach(hash2, rb_hash_update_i, hash1); + rb_hash_foreach(hash2, rb_hash_update_i, hash1); } return hash1; } @@ -2273,7 +2311,7 @@ env_invert() return rb_hash_invert(env_to_hash()); } -static enum st_retval +static int env_replace_i(key, val, keys) VALUE key, val, keys; { @@ -2295,7 +2333,7 @@ env_replace(env, hash) if (env == hash) return env; hash = to_hash(hash); - hash_foreach(hash, env_replace_i, keys); + rb_hash_foreach(hash, env_replace_i, keys); for (i=0; i<RARRAY(keys)->len; i++) { env_delete(env, RARRAY(keys)->ptr[i]); @@ -2303,7 +2341,7 @@ env_replace(env, hash) return env; } -static enum st_retval +static int env_update_i(key, val) VALUE key, val; { @@ -2322,7 +2360,7 @@ env_update(env, hash) { if (env == hash) return env; hash = to_hash(hash); - hash_foreach(hash, env_update_i, 0); + rb_hash_foreach(hash, env_update_i, 0); return env; } @@ -253,6 +253,8 @@ VALUE rb_gc_enable _((void)); VALUE rb_gc_disable _((void)); VALUE rb_gc_start _((void)); /* hash.c */ +void st_foreach _((struct st_table *, int (*)(), unsigned long)); +void rb_hash_foreach _((VALUE, int (*)(), VALUE)); VALUE rb_hash _((VALUE)); VALUE rb_hash_new _((void)); VALUE rb_hash_freeze _((VALUE)); @@ -437,7 +437,7 @@ w_ivar(tbl, arg) { if (tbl) { w_long(tbl->num_entries, arg->arg); - st_foreach(tbl, w_obj_each, (st_data_t)arg); + st_foreach_safe(tbl, w_obj_each, (st_data_t)arg); } else { w_long(0, arg->arg); @@ -621,7 +621,7 @@ w_object(obj, arg, limit) w_byte(TYPE_HASH_DEF, arg); } w_long(RHASH(obj)->tbl->num_entries, arg); - st_foreach(RHASH(obj)->tbl, hash_each, (st_data_t)&c_arg); + rb_hash_foreach(obj, hash_each, (st_data_t)&c_arg); if (!NIL_P(RHASH(obj)->ifnone)) { w_object(RHASH(obj)->ifnone, arg, limit); } @@ -378,7 +378,7 @@ static VALUE inspect_obj(obj, str) VALUE obj, str; { - st_foreach(ROBJECT(obj)->iv_tbl, inspect_i, str); + st_foreach_safe(ROBJECT(obj)->iv_tbl, inspect_i, str); rb_str_cat2(str, ">"); RSTRING(str)->ptr[0] = '#'; OBJ_INFECT(str, obj); diff --git a/variable.c b/variable.c index 6d4ccd2c53..553207eb67 100644 --- a/variable.c +++ b/variable.c @@ -124,10 +124,10 @@ find_class_path(klass) arg.track = rb_cObject; arg.prev = 0; if (RCLASS(rb_cObject)->iv_tbl) { - st_foreach(RCLASS(rb_cObject)->iv_tbl, fc_i, (st_data_t)&arg); + st_foreach_safe(RCLASS(rb_cObject)->iv_tbl, fc_i, (st_data_t)&arg); } if (arg.path == 0) { - st_foreach(rb_class_tbl, fc_i, (st_data_t)&arg); + st_foreach_safe(rb_class_tbl, fc_i, (st_data_t)&arg); } if (arg.path) { if (!ROBJECT(klass)->iv_tbl) { @@ -467,7 +467,7 @@ mark_global_entry(key, entry) void rb_gc_mark_global_tbl() { - st_foreach(rb_global_tbl, mark_global_entry, 0); + st_foreach_safe(rb_global_tbl, mark_global_entry, 0); } static ID @@ -777,7 +777,7 @@ rb_f_global_variables() char buf[4]; char *s = "&`'+123456789"; - st_foreach(rb_global_tbl, gvar_i, ary); + st_foreach_safe(rb_global_tbl, gvar_i, ary); if (!NIL_P(rb_backref_get())) { while (*s) { sprintf(buf, "$%c", *s++); @@ -948,7 +948,7 @@ givar_i(obj, tbl) st_table *tbl; { if (rb_special_const_p(obj)) { - st_foreach(tbl, givar_mark_i, 0); + st_foreach_safe(tbl, givar_mark_i, 0); } return ST_CONTINUE; } @@ -958,7 +958,7 @@ rb_mark_generic_ivar_tbl() { if (!generic_iv_tbl) return; if (special_generic_ivar == 0) return; - st_foreach(generic_iv_tbl, givar_i, 0); + st_foreach_safe(generic_iv_tbl, givar_i, 0); } void @@ -1120,7 +1120,7 @@ rb_obj_instance_variables(obj) case T_CLASS: case T_MODULE: if (ROBJECT(obj)->iv_tbl) { - st_foreach(ROBJECT(obj)->iv_tbl, ivar_i, ary); + st_foreach_safe(ROBJECT(obj)->iv_tbl, ivar_i, ary); } break; default: @@ -1129,7 +1129,7 @@ rb_obj_instance_variables(obj) st_table *tbl; if (st_lookup(generic_iv_tbl, obj, (st_data_t *)&tbl)) { - st_foreach(tbl, ivar_i, ary); + st_foreach_safe(tbl, ivar_i, ary); } } break; @@ -1513,7 +1513,7 @@ rb_mod_const_at(mod, data) tbl = st_init_numtable(); } if (RCLASS(mod)->iv_tbl) { - st_foreach(RCLASS(mod)->iv_tbl, sv_i, (st_data_t)tbl); + st_foreach_safe(RCLASS(mod)->iv_tbl, sv_i, (st_data_t)tbl); } return tbl; } @@ -1551,7 +1551,7 @@ rb_const_list(data) if (!tbl) return rb_ary_new2(0); ary = rb_ary_new2(tbl->num_entries); - st_foreach(tbl, list_i, ary); + st_foreach_safe(tbl, list_i, ary); st_free_table(tbl); return ary; @@ -1819,7 +1819,7 @@ rb_mod_class_variables(obj) VALUE ary = rb_ary_new(); if (RCLASS(obj)->iv_tbl) { - st_foreach(RCLASS(obj)->iv_tbl, cv_i, ary); + st_foreach_safe(RCLASS(obj)->iv_tbl, cv_i, ary); } return ary; } |