summaryrefslogtreecommitdiff
path: root/eval_method.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-03-01 03:36:33 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-03-01 03:36:33 +0000
commit207b8292ba0bf13b60a1ad745dcb438015d38bfc (patch)
treeddc687cf9e0df395e183df864c77ba2839172eaf /eval_method.c
parent32c4aa1d144f6895d0e4d2c62b384d22c3fb4860 (diff)
* eval_method.c (rb_get_method_body): ent->method may be freed by
GC. [ruby-dev:31819] * thread.c (remove_event_hook): should not access freed memory. [ruby-dev:31820] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15654 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval_method.c')
-rw-r--r--eval_method.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/eval_method.c b/eval_method.c
index f7043c0069..7ff683d219 100644
--- a/eval_method.c
+++ b/eval_method.c
@@ -11,6 +11,7 @@ struct cache_entry { /* method hash table. */
ID mid; /* method's id */
ID mid0; /* method's original id */
VALUE klass; /* receiver's class */
+ VALUE oklass; /* original's class */
NODE *method;
};
@@ -46,7 +47,7 @@ rb_clear_cache_for_undef(VALUE klass, ID id)
ent = cache;
end = ent + CACHE_SIZE;
while (ent < end) {
- if (ent->method && ent->method->nd_clss == klass && ent->mid == id) {
+ if (ent->oklass == klass && ent->mid == id) {
ent->mid = 0;
}
ent++;
@@ -84,8 +85,7 @@ rb_clear_cache_by_class(VALUE klass)
ent = cache;
end = ent + CACHE_SIZE;
while (ent < end) {
- if ((ent->klass == klass) ||
- (ent->method && ent->method->nd_clss == klass)) {
+ if (ent->klass == klass || ent->oklass == klass) {
ent->mid = 0;
}
ent++;
@@ -250,6 +250,7 @@ rb_get_method_body(VALUE klass, ID id, ID *idp)
ent->klass = klass;
ent->mid = ent->mid0 = id;
ent->method = 0;
+ ent->oklass = 0;
return 0;
}
@@ -263,6 +264,7 @@ rb_get_method_body(VALUE klass, ID id, ID *idp)
ent->mid = id;
ent->mid0 = fbody->nd_oid;
ent->method = body = method;
+ ent->oklass = method->nd_clss;
}
else {
body = method;