mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* eval.c (method_hash): new method. [ruby-talk:93968]
* eval.c (proc_eq): do not compare dyna_vars. * eval.c (proc_hash): new method. * eval.c (rb_yield_0): protect break/return from within orphan (or lambda) Proc object. * parse.y (yylex): should not allow symbol for invalid global variable (e.g. `:$-)`). [ruby-core:02518] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5879 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									e3b15cf111
								
							
						
					
					
						commit
						54a0407425
					
				
					 7 changed files with 125 additions and 13 deletions
				
			
		
							
								
								
									
										16
									
								
								ChangeLog
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								ChangeLog
									
										
									
									
									
								
							|  | @ -1,3 +1,14 @@ | |||
| Wed Mar  3 13:10:56 2004  Yukihiro Matsumoto  <matz@ruby-lang.org> | ||||
| 
 | ||||
| 	* eval.c (method_hash): new method. [ruby-talk:93968] | ||||
| 
 | ||||
| 	* eval.c (proc_eq): do not compare dyna_vars. | ||||
| 
 | ||||
| 	* eval.c (proc_hash): new method. | ||||
| 
 | ||||
| 	* eval.c (rb_yield_0): protect break/return from within orphan (or | ||||
| 	  lambda) Proc object. | ||||
| 
 | ||||
| Wed Mar  3 09:52:05 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org> | ||||
| 
 | ||||
| 	* lib/mkmf.rb ($topdir): use compile_dir only when not installed yet. | ||||
|  | @ -101,6 +112,11 @@ Sat Feb 28 10:31:03 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp> | |||
| 	* lib/erb.rb, test/erb/test_erb.rb: don't forget filename, | ||||
| 	  if both filename and safe_level given. [ruby-dev:23050] | ||||
| 
 | ||||
| Sat Feb 28 01:08:40 2004  Yukihiro Matsumoto  <matz@ruby-lang.org> | ||||
| 
 | ||||
| 	* parse.y (yylex): should not allow symbol for invalid global | ||||
| 	  variable (e.g. `:$-)`). [ruby-core:02518] | ||||
| 
 | ||||
| Fri Feb 27 20:37:09 2004  Yukihiro Matsumoto  <matz@ruby-lang.org> | ||||
| 
 | ||||
| 	* eval.c (proc_invoke): no orphan block check is needed when pcall | ||||
|  |  | |||
|  | @ -115,7 +115,7 @@ can be cast to retrieve the pointer to the struct.  The casting macro | |||
| will be of the form RXXXX for each data type; for instance, RARRAY(obj).  | ||||
| See "ruby.h". | ||||
| 
 | ||||
| For example, `RSTRING(size)->len' is the way to get the size of the | ||||
| For example, `RSTRING(str)->len' is the way to get the size of the | ||||
| Ruby String object.  The allocated region can be accessed by | ||||
| `RSTRING(str)->ptr'.  For arrays, use `RARRAY(ary)->len' and | ||||
| `RARRAY(ary)->ptr' respectively. | ||||
|  |  | |||
							
								
								
									
										77
									
								
								eval.c
									
										
									
									
									
								
							
							
						
						
									
										77
									
								
								eval.c
									
										
									
									
									
								
							|  | @ -993,10 +993,11 @@ static NODE *compile _((VALUE, char*, int)); | |||
| 
 | ||||
| static VALUE rb_yield_0 _((VALUE, VALUE, VALUE, int, int)); | ||||
| 
 | ||||
| #define YIELD_LAMBDA_CALL 1 | ||||
| #define YIELD_PUBLIC_DEF  2 | ||||
| #define YIELD_FUNC_AVALUE 1 | ||||
| #define YIELD_FUNC_SVALUE 2 | ||||
| #define YIELD_LAMBDA_CALL  1 | ||||
| #define YIELD_BLOCK_ORPHAN 2 | ||||
| #define YIELD_PUBLIC_DEF   4 | ||||
| #define YIELD_FUNC_AVALUE  1 | ||||
| #define YIELD_FUNC_SVALUE  2 | ||||
| 
 | ||||
| static VALUE rb_call _((VALUE,VALUE,ID,int,const VALUE*,int)); | ||||
| static VALUE module_setup _((VALUE,NODE*)); | ||||
|  | @ -1257,6 +1258,7 @@ ruby_init() | |||
|     } | ||||
|     POP_SCOPE(); | ||||
|     ruby_scope = top_scope; | ||||
|     top_scope->flags &= ~SCOPE_NOSTACK; | ||||
|     ruby_running = 1; | ||||
| } | ||||
| 
 | ||||
|  | @ -4652,7 +4654,7 @@ rb_yield_0(val, self, klass, flags, avalue) | |||
|     ruby_current_node = node; | ||||
| 
 | ||||
|     PUSH_ITER(block->iter); | ||||
|     PUSH_TAG(lambda ? PROT_NONE : PROT_YIELD); | ||||
|     PUSH_TAG((flags & YIELD_BLOCK_ORPHAN) ? PROT_NONE : PROT_YIELD); | ||||
|     if ((state = EXEC_TAG()) == 0) { | ||||
|       redo: | ||||
| 	if (nd_type(node) == NODE_CFUNC || nd_type(node) == NODE_IFUNC) { | ||||
|  | @ -4684,9 +4686,10 @@ rb_yield_0(val, self, klass, flags, avalue) | |||
| 	    state = 0; | ||||
| 	    result = prot_tag->retval; | ||||
| 	    break; | ||||
| 	  case TAG_RETURN: | ||||
| 	    if (!lambda) | ||||
| 	  case TAG_BREAK: | ||||
| 	    if (TAG_DST()) { | ||||
| 		result = prot_tag->retval; | ||||
| 	    } | ||||
| 	    break; | ||||
| 	  default: | ||||
| 	    break; | ||||
|  | @ -6999,6 +7002,9 @@ rb_mod_modfunc(argc, argv, module) | |||
| 	id = rb_to_id(argv[i]); | ||||
| 	for (;;) { | ||||
| 	    body = search_method(m, id, &m); | ||||
| 	    if (body == 0) { | ||||
| 		body = search_method(rb_cObject, id, &m); | ||||
| 	    } | ||||
| 	    if (body == 0 || body->nd_body == 0) { | ||||
| 		rb_bug("undefined method `%s'; can't happen", rb_id2name(id)); | ||||
| 	    } | ||||
|  | @ -7983,6 +7989,7 @@ proc_invoke(proc, args, self, klass) | |||
|     Data_Get_Struct(proc, struct BLOCK, data); | ||||
|     pcall = (data->flags & BLOCK_LAMBDA) ? YIELD_LAMBDA_CALL : 0; | ||||
|     orphan = pcall ? 0 : block_orphan(data); | ||||
|     if (orphan || pcall) pcall |= YIELD_BLOCK_ORPHAN; | ||||
|     if (!pcall && RARRAY(args)->len == 1) { | ||||
| 	avalue = Qfalse; | ||||
| 	args = RARRAY(args)->ptr[0]; | ||||
|  | @ -8122,6 +8129,7 @@ proc_arity(proc) | |||
| 	} | ||||
| 	return INT2FIX(-1); | ||||
|     } | ||||
|     if (!(data->flags & BLOCK_LAMBDA)) return INT2FIX(-1); | ||||
|     if (data->var == (NODE*)1) return INT2FIX(0); | ||||
|     if (data->var == (NODE*)2) return INT2FIX(0); | ||||
|     switch (nd_type(data->var)) { | ||||
|  | @ -8162,10 +8170,34 @@ proc_eq(self, other) | |||
|     if (data->body != data2->body) return Qfalse; | ||||
|     if (data->var != data2->var) return Qfalse; | ||||
|     if (data->frame.uniq != data2->frame.uniq) return Qfalse; | ||||
|     if (data->dyna_vars != data2->dyna_vars) return Qfalse; | ||||
|     if (data->flags != data2->flags) return Qfalse; | ||||
| 
 | ||||
|     return Qtrue; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * call-seq: | ||||
|  *   prc.hash   =>  integer | ||||
|  * | ||||
|  * Return hash value corresponding to proc body. | ||||
|  */ | ||||
| 
 | ||||
| static VALUE | ||||
| proc_hash(self, other) | ||||
|     VALUE self; | ||||
| { | ||||
|     struct BLOCK *data; | ||||
|     long hash; | ||||
| 
 | ||||
|     Data_Get_Struct(self, struct BLOCK, data); | ||||
|     hash = (long)data->body; | ||||
|     hash ^= (long)data->var; | ||||
|     hash ^= data->frame.uniq << 16; | ||||
|     hash ^= data->flags; | ||||
| 
 | ||||
|     return INT2FIX(hash); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * call-seq: | ||||
|  *   prc.to_s   => string | ||||
|  | @ -8459,6 +8491,29 @@ method_eq(method, other) | |||
|     return Qtrue; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * call-seq: | ||||
|  *    meth.hash   => integer | ||||
|  * | ||||
|  * Return a hash value corresponding to the method object. | ||||
|  */ | ||||
| 
 | ||||
| static VALUE | ||||
| method_hash(method) | ||||
|     VALUE method; | ||||
| { | ||||
|     struct METHOD *m; | ||||
|     long hash; | ||||
| 
 | ||||
|     Data_Get_Struct(method, struct METHOD, m); | ||||
|     hash = (long)m->klass; | ||||
|     hash ^= (long)m->rklass; | ||||
|     hash ^= (long)m->recv; | ||||
|     hash ^= (long)m->body; | ||||
| 
 | ||||
|     return INT2FIX(hash); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  *  call-seq: | ||||
|  *     meth.unbind    => unbound_method | ||||
|  | @ -9092,6 +9147,8 @@ Init_Proc() | |||
|     rb_define_method(rb_cProc, "arity", proc_arity, 0); | ||||
|     rb_define_method(rb_cProc, "[]", proc_call, -2); | ||||
|     rb_define_method(rb_cProc, "==", proc_eq, 1); | ||||
|     rb_define_method(rb_cProc, "eql?", proc_eq, 1); | ||||
|     rb_define_method(rb_cProc, "hash", proc_hash, 0); | ||||
|     rb_define_method(rb_cProc, "to_s", proc_to_s, 0); | ||||
|     rb_define_method(rb_cProc, "to_proc", proc_to_self, 0); | ||||
|     rb_define_method(rb_cProc, "binding", proc_binding, 0); | ||||
|  | @ -9103,6 +9160,8 @@ Init_Proc() | |||
|     rb_undef_alloc_func(rb_cMethod); | ||||
|     rb_undef_method(CLASS_OF(rb_cMethod), "new"); | ||||
|     rb_define_method(rb_cMethod, "==", method_eq, 1); | ||||
|     rb_define_method(rb_cMethod, "eql?", method_eq, 1); | ||||
|     rb_define_method(rb_cMethod, "hash", method_hash, 0); | ||||
|     rb_define_method(rb_cMethod, "clone", method_clone, 0); | ||||
|     rb_define_method(rb_cMethod, "call", method_call, -1); | ||||
|     rb_define_method(rb_cMethod, "[]", method_call, -1); | ||||
|  | @ -9117,6 +9176,8 @@ Init_Proc() | |||
|     rb_undef_alloc_func(rb_cUnboundMethod); | ||||
|     rb_undef_method(CLASS_OF(rb_cUnboundMethod), "new"); | ||||
|     rb_define_method(rb_cUnboundMethod, "==", method_eq, 1); | ||||
|     rb_define_method(rb_cUnboundMethod, "eql?", method_eq, 1); | ||||
|     rb_define_method(rb_cUnboundMethod, "hash", method_hash, 0); | ||||
|     rb_define_method(rb_cUnboundMethod, "clone", method_clone, 0); | ||||
|     rb_define_method(rb_cUnboundMethod, "arity", method_arity, 0); | ||||
|     rb_define_method(rb_cUnboundMethod, "inspect", method_inspect, 0); | ||||
|  |  | |||
|  | @ -561,8 +561,10 @@ The variable ruby-indent-level controls the amount of indentation. | |||
| (defun ruby-indent-size (pos nest) | ||||
|   (+ pos (* (or nest 1) ruby-indent-level))) | ||||
| 
 | ||||
| ;;; maybe obsolete | ||||
| (defconst ruby-assign-re "\\s *\\(&&\\|||\\|<<\\|>>\\|[-+*/%&|^]\\)?=\\s *") | ||||
| 
 | ||||
| ;;; maybe obsolete | ||||
| (defun ruby-beginning-of-arg (start end) | ||||
|   (save-restriction | ||||
|     (narrow-to-region start (1+ end)) | ||||
|  | @ -586,6 +588,7 @@ The variable ruby-indent-level controls the amount of indentation. | |||
| 	       (if beg (setq beg nil arg (point)))) | ||||
| 	      ((looking-at ruby-operator-re) | ||||
| 	       (goto-char (match-end 0)) | ||||
| 	       (echo "foo %s %s" arg beg) | ||||
| 	       (if beg (setq beg nil arg (match-end 0)))) | ||||
| 	      ((not (eq (char-syntax (char-after)) ?\()) | ||||
| 	       (setq start (point))))) | ||||
|  | @ -731,7 +734,9 @@ The variable ruby-indent-level controls the amount of indentation. | |||
| 		      (not (bobp))) | ||||
| 		     (save-excursion | ||||
| 		       (widen) | ||||
| 		       (ruby-beginning-of-arg (or begin parse-start) (point)) | ||||
| 		       (goto-char (or begin parse-start)) | ||||
| 		       (skip-syntax-forward " ") | ||||
| ;;		       (ruby-beginning-of-arg (or begin parse-start) (point)) | ||||
| 		       (current-column))) | ||||
| 		    (t | ||||
| 		     (+ indent ruby-indent-level)))))))) | ||||
|  | @ -832,7 +837,9 @@ An end of a defun is found by moving forward from the beginning of one." | |||
| 		     (skip-chars-forward ",.:;|&^~=!?\\+\\-\\*") | ||||
| 		     (looking-at "\\s(")) | ||||
| 		   (goto-char (scan-sexps (point) 1))) | ||||
| 		  ((looking-at ruby-block-beg-re) | ||||
| 		  ((and (looking-at ruby-block-beg-re) | ||||
| 			(not (eq (char-before (point)) ?.)) | ||||
| 			(not (eq (char-before (point)) ?:))) | ||||
| 		   (ruby-end-of-block) | ||||
| 		   (forward-word 1)) | ||||
| 		  ((looking-at "\\(\\$\\|@@?\\)?\\sw") | ||||
|  |  | |||
							
								
								
									
										5
									
								
								parse.y
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								parse.y
									
										
									
									
									
								
							|  | @ -4244,7 +4244,10 @@ yylex() | |||
| 	    tokadd(c); | ||||
| 	    tokfix(); | ||||
| 	    yylval.id = rb_intern(tok()); | ||||
| 	    /* xxx shouldn't check if valid option variable */ | ||||
| 	    if (!is_global_id(yylval.id)) { | ||||
| 		rb_compile_error("invalid global variable `%s'", rb_id2name(yylval.id)); | ||||
| 		return 0; | ||||
| 	    } | ||||
| 	    return tGVAR; | ||||
| 
 | ||||
| 	  case '&':		/* $&: last match */ | ||||
|  |  | |||
							
								
								
									
										11
									
								
								ruby.c
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								ruby.c
									
										
									
									
									
								
							|  | @ -1048,6 +1048,16 @@ verbose_setter(val, id, variable) | |||
|     ruby_verbose = RTEST(val) ? Qtrue : val; | ||||
| } | ||||
| 
 | ||||
| static VALUE | ||||
| opt_W_getter(val, id) | ||||
|     VALUE val; | ||||
|     ID id; | ||||
| { | ||||
|     if (ruby_verbose == Qnil) return INT2FIX(0); | ||||
|     if (ruby_verbose == Qfalse) return INT2FIX(1); | ||||
|     if (ruby_verbose == Qtrue) return INT2FIX(2); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| ruby_prog_init() | ||||
| { | ||||
|  | @ -1057,6 +1067,7 @@ ruby_prog_init() | |||
|     rb_define_hooked_variable("$VERBOSE", &ruby_verbose, 0, verbose_setter); | ||||
|     rb_define_hooked_variable("$-v", &ruby_verbose, 0, verbose_setter); | ||||
|     rb_define_hooked_variable("$-w", &ruby_verbose, 0, verbose_setter); | ||||
|     rb_define_virtual_variable("$-W", opt_W_getter, 0); | ||||
|     rb_define_variable("$DEBUG", &ruby_debug); | ||||
|     rb_define_variable("$-d", &ruby_debug); | ||||
|     rb_define_readonly_variable("$-p", &do_print); | ||||
|  |  | |||
|  | @ -1120,6 +1120,20 @@ end | |||
| ljump_test(false, get_block{break}) | ||||
| ljump_test(true, lambda{break}) | ||||
| 
 | ||||
| def exit_value_test(&block) | ||||
|   block.call | ||||
| rescue LocalJumpError | ||||
|   $!.exit_value | ||||
| end | ||||
| 
 | ||||
| test_ok(45, exit_value_test{break 45}) | ||||
| 
 | ||||
| test_ok(55, begin | ||||
|               get_block{break 55}.call | ||||
|             rescue LocalJumpError | ||||
|               $!.exit_value | ||||
|             end) | ||||
| 
 | ||||
| test_ok(block.arity == -1) | ||||
| test_ok(lambda.arity == -1) | ||||
| test_ok(lambda{||}.arity == 0) | ||||
|  | @ -1140,7 +1154,7 @@ test_ok(return_in_lambda()) | |||
| 
 | ||||
| def marity_test(m) | ||||
|   method = method(m) | ||||
|   test_ok(method.arity == method.to_proc.arity) | ||||
|   test_ok(method.arity == method.to_proc.arity, 2) | ||||
| end | ||||
| marity_test(:test_ok) | ||||
| marity_test(:marity_test) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 matz
						matz