mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* proc.c (rb_method_location): return attr's location if it is setup.
[Feature #2084] * NEWS: follow above. * vm_method.c (rb_add_method): save attr's location. * gc.c (mark_method_entry): mark attr's location. * method.h (rb_method_definition_t): add member to save attr's location. * vm_eval.c (vm_call0): follow above. * vm_insnhelper.c (vm_call_method): ditto. * vm_method.c (rb_method_definition_eq): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27016 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									5d8f695032
								
							
						
					
					
						commit
						c46f71399a
					
				
					 8 changed files with 71 additions and 12 deletions
				
			
		
							
								
								
									
										19
									
								
								ChangeLog
									
										
									
									
									
								
							
							
						
						
									
										19
									
								
								ChangeLog
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,22 @@
 | 
			
		|||
Mon Mar 22 20:32:22 2010  wanabe  <s.wanabe@gmail.com>
 | 
			
		||||
 | 
			
		||||
	* proc.c (rb_method_location): return attr's location if it is setup.
 | 
			
		||||
	  [Feature #2084]
 | 
			
		||||
 | 
			
		||||
	* NEWS: follow above.
 | 
			
		||||
 | 
			
		||||
	* vm_method.c (rb_add_method): save attr's location.
 | 
			
		||||
 | 
			
		||||
	* gc.c (mark_method_entry): mark attr's location.
 | 
			
		||||
 | 
			
		||||
	* method.h (rb_method_definition_t): add member to save attr's location.
 | 
			
		||||
 | 
			
		||||
	* vm_eval.c (vm_call0): follow above.
 | 
			
		||||
 | 
			
		||||
	* vm_insnhelper.c (vm_call_method): ditto.
 | 
			
		||||
 | 
			
		||||
	* vm_method.c (rb_method_definition_eq): ditto.
 | 
			
		||||
 | 
			
		||||
Mon Mar 22 19:31:06 2010  Tadayoshi Funaba  <tadf@dotrb.org>
 | 
			
		||||
 | 
			
		||||
	* lib/date.rb (Date#>>): fixed.  [ruby-core:28011]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										5
									
								
								NEWS
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								NEWS
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -96,6 +96,11 @@ with all sufficient information, see the ChangeLog file.
 | 
			
		|||
    * New method:
 | 
			
		||||
      * MatchData#==
 | 
			
		||||
 | 
			
		||||
  * Proc
 | 
			
		||||
    * extended method:
 | 
			
		||||
      * Proc#source_location returns location even if receiver is a method
 | 
			
		||||
        defined by attr_reader / attr_writer / attr_accessor.
 | 
			
		||||
 | 
			
		||||
  * Process
 | 
			
		||||
    * extended methods:
 | 
			
		||||
      * Process.spawn accepts [:child, FD] for a redirect target.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								gc.c
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								gc.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1423,6 +1423,10 @@ mark_method_entry(rb_objspace_t *objspace, const rb_method_entry_t *me, int lev)
 | 
			
		|||
      case VM_METHOD_TYPE_BMETHOD:
 | 
			
		||||
	gc_mark(objspace, def->body.proc, lev);
 | 
			
		||||
	break;
 | 
			
		||||
      case VM_METHOD_TYPE_ATTRSET:
 | 
			
		||||
      case VM_METHOD_TYPE_IVAR:
 | 
			
		||||
	gc_mark(objspace, def->body.attr.location, lev);
 | 
			
		||||
	break;
 | 
			
		||||
      default:
 | 
			
		||||
	break; /* ignore */
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										7
									
								
								method.h
									
										
									
									
									
								
							
							
						
						
									
										7
									
								
								method.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -49,6 +49,11 @@ typedef struct rb_method_cfunc_struct {
 | 
			
		|||
    int argc;
 | 
			
		||||
} rb_method_cfunc_t;
 | 
			
		||||
 | 
			
		||||
typedef struct rb_method_attr_struct {
 | 
			
		||||
    ID id;
 | 
			
		||||
    VALUE location;
 | 
			
		||||
} rb_method_attr_t;
 | 
			
		||||
 | 
			
		||||
typedef struct rb_iseq_struct rb_iseq_t;
 | 
			
		||||
 | 
			
		||||
typedef struct rb_method_definition_struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +62,7 @@ typedef struct rb_method_definition_struct {
 | 
			
		|||
    union {
 | 
			
		||||
	rb_iseq_t *iseq;            /* should be mark */
 | 
			
		||||
	rb_method_cfunc_t cfunc;
 | 
			
		||||
	ID attr_id;
 | 
			
		||||
	rb_method_attr_t attr;
 | 
			
		||||
	VALUE proc;                 /* should be mark */
 | 
			
		||||
	enum method_optimized_type {
 | 
			
		||||
	    OPTIMIZED_METHOD_TYPE_SEND,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										25
									
								
								proc.c
									
										
									
									
									
								
							
							
						
						
									
										25
									
								
								proc.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1634,15 +1634,18 @@ rb_obj_method_arity(VALUE obj, ID id)
 | 
			
		|||
    return rb_mod_method_arity(CLASS_OF(obj), id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
rb_iseq_t *
 | 
			
		||||
rb_method_get_iseq(VALUE method)
 | 
			
		||||
static inline rb_method_definition_t *
 | 
			
		||||
method_get_def(VALUE method)
 | 
			
		||||
{
 | 
			
		||||
    struct METHOD *data;
 | 
			
		||||
    rb_method_definition_t *def;
 | 
			
		||||
 | 
			
		||||
    TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
 | 
			
		||||
    def = data->me.def;
 | 
			
		||||
    return data->me.def;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static rb_iseq_t *
 | 
			
		||||
method_get_iseq(rb_method_definition_t *def)
 | 
			
		||||
{
 | 
			
		||||
    switch (def->type) {
 | 
			
		||||
      case VM_METHOD_TYPE_BMETHOD:
 | 
			
		||||
	return get_proc_iseq(def->body.proc, 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -1653,6 +1656,12 @@ rb_method_get_iseq(VALUE method)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
rb_iseq_t *
 | 
			
		||||
rb_method_get_iseq(VALUE method)
 | 
			
		||||
{
 | 
			
		||||
    return method_get_iseq(method_get_def(method));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * call-seq:
 | 
			
		||||
 *    meth.source_location  => [String, Fixnum]
 | 
			
		||||
| 
						 | 
				
			
			@ -1664,7 +1673,13 @@ rb_method_get_iseq(VALUE method)
 | 
			
		|||
VALUE
 | 
			
		||||
rb_method_location(VALUE method)
 | 
			
		||||
{
 | 
			
		||||
    return iseq_location(rb_method_get_iseq(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));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -89,14 +89,14 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
 | 
			
		|||
	if (argc != 1) {
 | 
			
		||||
	    rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
 | 
			
		||||
	}
 | 
			
		||||
	val = rb_ivar_set(recv, def->body.attr_id, argv[0]);
 | 
			
		||||
	val = rb_ivar_set(recv, def->body.attr.id, argv[0]);
 | 
			
		||||
	break;
 | 
			
		||||
      }
 | 
			
		||||
      case VM_METHOD_TYPE_IVAR: {
 | 
			
		||||
	if (argc != 0) {
 | 
			
		||||
	    rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
 | 
			
		||||
	}
 | 
			
		||||
	val = rb_attr_get(recv, def->body.attr_id);
 | 
			
		||||
	val = rb_attr_get(recv, def->body.attr.id);
 | 
			
		||||
	break;
 | 
			
		||||
      }
 | 
			
		||||
      case VM_METHOD_TYPE_BMETHOD: {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -504,7 +504,7 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp,
 | 
			
		|||
		if (num != 1) {
 | 
			
		||||
		    rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", num);
 | 
			
		||||
		}
 | 
			
		||||
		val = rb_ivar_set(recv, me->def->body.attr_id, *(cfp->sp - 1));
 | 
			
		||||
		val = rb_ivar_set(recv, me->def->body.attr.id, *(cfp->sp - 1));
 | 
			
		||||
		cfp->sp -= 2;
 | 
			
		||||
		break;
 | 
			
		||||
	      }
 | 
			
		||||
| 
						 | 
				
			
			@ -512,7 +512,7 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp,
 | 
			
		|||
		if (num != 0) {
 | 
			
		||||
		    rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", num);
 | 
			
		||||
		}
 | 
			
		||||
		val = rb_attr_get(recv, me->def->body.attr_id);
 | 
			
		||||
		val = rb_attr_get(recv, me->def->body.attr.id);
 | 
			
		||||
		cfp->sp -= 1;
 | 
			
		||||
		break;
 | 
			
		||||
	      }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										15
									
								
								vm_method.c
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								vm_method.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -260,6 +260,9 @@ method_added(VALUE klass, ID mid)
 | 
			
		|||
rb_method_entry_t *
 | 
			
		||||
rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_flag_t noex)
 | 
			
		||||
{
 | 
			
		||||
    rb_thread_t *th;
 | 
			
		||||
    rb_control_frame_t *cfp;
 | 
			
		||||
    int line;
 | 
			
		||||
    rb_method_entry_t *me = rb_add_method_def(klass, mid, type, 0, noex);
 | 
			
		||||
    rb_method_definition_t *def = ALLOC(rb_method_definition_t);
 | 
			
		||||
    me->def = def;
 | 
			
		||||
| 
						 | 
				
			
			@ -275,7 +278,15 @@ rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_
 | 
			
		|||
	break;
 | 
			
		||||
      case VM_METHOD_TYPE_ATTRSET:
 | 
			
		||||
      case VM_METHOD_TYPE_IVAR:
 | 
			
		||||
	def->body.attr_id = (ID)opts;
 | 
			
		||||
	def->body.attr.id = (ID)opts;
 | 
			
		||||
	th = GET_THREAD();
 | 
			
		||||
	cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
 | 
			
		||||
	if (cfp && (line = rb_vm_get_sourceline(cfp))) {
 | 
			
		||||
	    VALUE location = rb_ary_new3(2, cfp->iseq->filename, INT2FIX(line));
 | 
			
		||||
	    def->body.attr.location = rb_ary_freeze(location);
 | 
			
		||||
	} else {
 | 
			
		||||
	    def->body.attr.location = Qfalse;
 | 
			
		||||
	}
 | 
			
		||||
	break;
 | 
			
		||||
      case VM_METHOD_TYPE_BMETHOD:
 | 
			
		||||
	def->body.proc = (VALUE)opts;
 | 
			
		||||
| 
						 | 
				
			
			@ -838,7 +849,7 @@ rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_defini
 | 
			
		|||
	  d1->body.cfunc.argc == d2->body.cfunc.argc;
 | 
			
		||||
      case VM_METHOD_TYPE_ATTRSET:
 | 
			
		||||
      case VM_METHOD_TYPE_IVAR:
 | 
			
		||||
	return d1->body.attr_id == d2->body.attr_id;
 | 
			
		||||
	return d1->body.attr.id == d2->body.attr.id;
 | 
			
		||||
      case VM_METHOD_TYPE_BMETHOD:
 | 
			
		||||
	return RTEST(rb_equal(d1->body.proc, d2->body.proc));
 | 
			
		||||
      case VM_METHOD_TYPE_MISSING:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue