aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--method.h4
-rw-r--r--proc.c38
-rw-r--r--vm_method.c11
4 files changed, 54 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index da0722a65e..abb8fb34ab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Wed Feb 6 13:35:20 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * proc.c (rb_method_entry_location, rb_{mod,obj}_method_location): new
+ functions to obtain source location of method definition.
+
+ * vm_method.c (rb_obj_respond_to): show the location of old style
+ respond_to? method.
+
Wed Feb 6 13:03:00 2013 Zachary Scott <zachary@zacharyscott.net>
* doc/security.rdoc: Add link to CVEs on ruby-lang.org/en/security
diff --git a/method.h b/method.h
index e1612cbb9b..b99674a913 100644
--- a/method.h
+++ b/method.h
@@ -126,6 +126,10 @@ int rb_method_entry_arity(const rb_method_entry_t *me);
int rb_method_entry_eq(const rb_method_entry_t *m1, const rb_method_entry_t *m2);
st_index_t rb_hash_method_entry(st_index_t hash, const rb_method_entry_t *me);
+VALUE rb_method_entry_location(rb_method_entry_t *me);
+VALUE rb_mod_method_location(VALUE mod, ID id);
+VALUE rb_obj_method_location(VALUE obj, ID id);
+
void rb_mark_method_entry(const rb_method_entry_t *me);
void rb_free_method_entry(rb_method_entry_t *me);
void rb_sweep_method_entry(void *vm);
diff --git a/proc.c b/proc.c
index 47c565134a..21fd22d95e 100644
--- a/proc.c
+++ b/proc.c
@@ -1844,6 +1844,37 @@ rb_method_get_iseq(VALUE method)
return method_get_iseq(method_get_def(method));
}
+static VALUE
+method_def_location(rb_method_definition_t *def)
+{
+ if (def->type == VM_METHOD_TYPE_ATTRSET || def->type == VM_METHOD_TYPE_IVAR) {
+ if (!def->body.attr.location)
+ return Qnil;
+ return rb_ary_dup(def->body.attr.location);
+ }
+ return iseq_location(method_get_iseq(def));
+}
+
+VALUE
+rb_method_entry_location(rb_method_entry_t *me)
+{
+ if (!me || !me->def) return Qnil;
+ return method_def_location(me->def);
+}
+
+VALUE
+rb_mod_method_location(VALUE mod, ID id)
+{
+ rb_method_entry_t *me = original_method_entry(mod, id);
+ return rb_method_entry_location(me);
+}
+
+VALUE
+rb_obj_method_location(VALUE obj, ID id)
+{
+ return rb_mod_method_location(CLASS_OF(obj), id);
+}
+
/*
* call-seq:
* meth.source_location -> [String, Fixnum]
@@ -1856,12 +1887,7 @@ VALUE
rb_method_location(VALUE method)
{
rb_method_definition_t *def = method_get_def(method);
- if (def->type == VM_METHOD_TYPE_ATTRSET || def->type == VM_METHOD_TYPE_IVAR) {
- if (!def->body.attr.location)
- return Qnil;
- return rb_ary_dup(def->body.attr.location);
- }
- return iseq_location(method_get_iseq(def));
+ return method_def_location(def);
}
/*
diff --git a/vm_method.c b/vm_method.c
index f2c361f521..a82ba5faea 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -1529,13 +1529,22 @@ rb_obj_respond_to(VALUE obj, ID id, int priv)
if (rb_obj_method_arity(obj, idRespond_to) != 1) {
argc = 2;
}
- else {
+ else if (!NIL_P(ruby_verbose)) {
VALUE klass = CLASS_OF(obj);
+ VALUE location = rb_mod_method_location(klass, idRespond_to);
rb_warn("%"PRIsVALUE"%c""respond_to?(:%"PRIsVALUE") is"
" old fashion which takes only one parameter",
(FL_TEST(klass, FL_SINGLETON) ? obj : klass),
(FL_TEST(klass, FL_SINGLETON) ? '.' : '#'),
QUOTE_ID(id));
+ if (!NIL_P(location)) {
+ VALUE path = RARRAY_PTR(location)[0];
+ VALUE line = RARRAY_PTR(location)[1];
+ if (!NIL_P(path)) {
+ rb_compile_warn(RSTRING_PTR(path), NUM2INT(line),
+ "respond_to? is defined here");
+ }
+ }
}
}
return RTEST(rb_funcall2(obj, idRespond_to, argc, args));