From 3de67ca69de67a67e564458e66dc962064fd4f42 Mon Sep 17 00:00:00 2001 From: matz Date: Mon, 7 Jul 2003 08:28:19 +0000 Subject: [PATCH] * eval.c (rb_call_super): k->super maybe NULL if klass is Kernel. [ruby-dev:20519] * gc.c (obj_free): clear method cache when freeing class/module. * eval.c (rb_mod_remove_method): allow "remove_method" to accept multiple arguments. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4041 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 12 ++++++++++++ configure.in | 1 + eval.c | 35 +++++++++++++++++++++++------------ gc.c | 1 + intern.h | 1 + 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index eed43a6de5..1124f3ff24 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,18 @@ Sat Jul 5 00:22:59 2003 Yukihiro Matsumoto * node.h (NEW_NODE): cast arguments to rb_node_newnode(). +Mon Jul 7 01:34:49 2003 Yukihiro Matsumoto + + * eval.c (rb_call_super): k->super maybe NULL if klass is Kernel. + [ruby-dev:20519] + + * gc.c (obj_free): clear method cache when freeing class/module. + +Sat Jul 5 23:32:06 2003 Yukihiro Matsumoto + + * eval.c (rb_mod_remove_method): allow "remove_method" to accept + multiple arguments. + Fri Jul 4 21:48:44 2003 Nobuyoshi Nakada * ext/syck/rubyext.c, ext/syck/syck.c, ext/syck/syck.h, diff --git a/configure.in b/configure.in index cebfc766b0..f2d6635284 100644 --- a/configure.in +++ b/configure.in @@ -736,6 +736,7 @@ if test "$with_dln_a_out" != yes; then beos*) ;; cygwin*) ;; mingw*) ;; + aix*) ;; netbsd*) CCDLFLAGS=-fPIC;; *) CCDLFLAGS=-fPIC;; esac diff --git a/eval.c b/eval.c index dd9ccc98a9..605d4f8ea4 100644 --- a/eval.c +++ b/eval.c @@ -216,7 +216,7 @@ rb_clear_cache() } static void -rb_clear_cache_by_id(id) +rb_clear_cache_for_undef(klass, id) ID id; { struct cache_entry *ent, *end; @@ -224,14 +224,14 @@ rb_clear_cache_by_id(id) if (!ruby_running) return; ent = cache; end = ent + CACHE_SIZE; while (ent < end) { - if (ent->mid == id) { + if (ent->origin == klass && ent->mid == id) { ent->mid = 0; } ent++; } } -static void +void rb_clear_cache_by_class(klass) VALUE klass; { @@ -276,7 +276,7 @@ rb_add_method(klass, mid, node, noex) mid = ID_ALLOCATOR; } if (OBJ_FROZEN(klass)) rb_error_frozen("class/module"); - rb_clear_cache_by_id(mid); + rb_clear_cache_for_undef(klass, mid); body = NEW_METHOD(node, noex); st_insert(RCLASS(klass)->m_tbl, mid, (st_data_t)body); if (node && mid != ID_ALLOCATOR && ruby_running) { @@ -349,6 +349,7 @@ rb_get_method_body(klassp, idp, noexp) if (ruby_running) { /* store in cache */ + if (BUILTIN_TYPE(origin) == T_ICLASS) origin = RBASIC(origin)->klass; ent = cache + EXPR1(klass, id); ent->klass = klass; ent->noex = body->nd_noex; @@ -362,7 +363,6 @@ rb_get_method_body(klassp, idp, noexp) body = ent->method = body->nd_head; } else { - if (BUILTIN_TYPE(origin) == T_ICLASS) origin = RBASIC(origin)->klass; *klassp = origin; ent->origin = origin; ent->mid = ent->mid0 = id; @@ -407,7 +407,7 @@ remove_method(klass, mid) rb_name_error(mid, "method `%s' not defined in %s", rb_id2name(mid), rb_class2name(klass)); } - rb_clear_cache_by_id(mid); + rb_clear_cache_for_undef(klass, mid); if (FL_TEST(klass, FL_SINGLETON)) { rb_funcall(rb_iv_get(klass, "__attached__"), singleton_removed, 1, ID2SYM(mid)); } @@ -425,10 +425,16 @@ rb_remove_method(klass, name) } static VALUE -rb_mod_remove_method(mod, name) - VALUE mod, name; +rb_mod_remove_method(argc, argv, mod) + int argc; + VALUE *argv; + VALUE mod; { - remove_method(mod, rb_to_id(name)); + int i; + + for (i=0; ind_head; } - rb_clear_cache_by_id(name); + rb_clear_cache_for_undef(klass, name); st_insert(RCLASS(klass)->m_tbl, name, (st_data_t)NEW_METHOD(NEW_FBODY(body, def, origin), orig->nd_noex)); if (singleton) { @@ -5092,7 +5098,7 @@ rb_call(klass, recv, mid, argc, argv, scope) if ((noex & NOEX_PRIVATE) && scope == 0) return rb_undefined(recv, mid, argc, argv, CSTAT_PRIV); - /* self must be kind of a specified form for private method */ + /* self must be kind of a specified form for protected method */ if ((noex & NOEX_PROTECTED)) { VALUE defined_class = klass; @@ -5217,6 +5223,11 @@ rb_call_super(argc, argv) rb_class2name(CLASS_OF(self))); } } + if (RCLASS(k)->super == 0) { + rb_name_error(ruby_frame->last_func, + "super: no superclass method `%s'", + rb_id2name(ruby_frame->last_func)); + } klass = k; } @@ -6527,7 +6538,7 @@ Init_eval() rb_undef_method(rb_cClass, "module_function"); - rb_define_private_method(rb_cModule, "remove_method", rb_mod_remove_method, 1); + rb_define_private_method(rb_cModule, "remove_method", rb_mod_remove_method, -1); rb_define_private_method(rb_cModule, "undef_method", rb_mod_undef_method, -1); rb_define_private_method(rb_cModule, "alias_method", rb_mod_alias_method, 2); rb_define_private_method(rb_cModule, "define_method", rb_mod_define_method, -1); diff --git a/gc.c b/gc.c index 9c8ac774f2..b1afbb1db7 100644 --- a/gc.c +++ b/gc.c @@ -1057,6 +1057,7 @@ obj_free(obj) break; case T_MODULE: case T_CLASS: + rb_clear_cache_by_class((VALUE)obj); st_free_table(RANY(obj)->as.klass.m_tbl); if (RANY(obj)->as.object.iv_tbl) { st_free_table(RANY(obj)->as.object.iv_tbl); diff --git a/intern.h b/intern.h index e31e883f15..732c38d228 100644 --- a/intern.h +++ b/intern.h @@ -152,6 +152,7 @@ void rb_enable_super _((VALUE, const char*)); void rb_define_alloc_func _((VALUE, VALUE (*)(VALUE))); void rb_undef_alloc_func _((VALUE)); void rb_clear_cache _((void)); +void rb_clear_cache_by_class _((VALUE)); void rb_alias _((VALUE, ID, ID)); void rb_attr _((VALUE,ID,int,int,int)); int rb_method_boundp _((VALUE, ID, int));