1
0
Fork 0
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:
matz 2004-03-03 04:55:35 +00:00
parent e3b15cf111
commit 54a0407425
7 changed files with 125 additions and 13 deletions

View file

@ -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

View file

@ -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
View file

@ -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);

View file

@ -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")

View file

@ -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
View file

@ -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);

View file

@ -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)