summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-05-22 08:28:11 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-05-22 08:28:11 +0000
commit315cd8341823e129ba5df0f420443e9d06d62c6f (patch)
tree2184e205b25e90012772f2ca77d419ed56a61bff
parented6a2bd29f649369beb1b7935cf2625c60581c04 (diff)
* variable.c (rb_alias_variable): should not allow variable
aliasing if $SAFE >= 4. * parse.y (expr): "break" and "next" to take optional expression, which is used as a value for termination. [new, experimental] * eval.c (rb_eval): "break" can give value to terminating method. * eval.c (rb_eval): "break" and "next" to take optional expression. * eval.c (rb_yield_0): "next" can give value to terminating "yield". * eval.c (rb_iterate): "break" can give value to terminating method. * eval.c (proc_call): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1441 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog20
-rw-r--r--eval.c57
-rw-r--r--node.h4
-rw-r--r--parse.y49
-rw-r--r--variable.c2
-rw-r--r--version.h4
6 files changed, 88 insertions, 48 deletions
diff --git a/ChangeLog b/ChangeLog
index e45ab1b4b3..ca161b279b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+Tue May 22 17:10:35 2001 K.Kosako <kosako@sofnec.co.jp>
+
+ * variable.c (rb_alias_variable): should not allow variable
+ aliasing if $SAFE >= 4.
+
+Tue May 22 02:37:45 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * parse.y (expr): "break" and "next" to take optional expression,
+ which is used as a value for termination. [new, experimental]
+
+ * eval.c (rb_eval): "break" can give value to terminating method.
+
+ * eval.c (rb_eval): "break" and "next" to take optional expression.
+
+ * eval.c (rb_yield_0): "next" can give value to terminating "yield".
+
+ * eval.c (rb_iterate): "break" can give value to terminating method.
+
+ * eval.c (proc_call): ditto.
+
Mon May 21 13:15:25 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* bignum.c (rb_big2str): t should be protected from GC.
diff --git a/eval.c b/eval.c
index 6fa0cedec7..5116e90347 100644
--- a/eval.c
+++ b/eval.c
@@ -2288,7 +2288,7 @@ rb_eval(self, n)
}
else if (_block.tag->dst == state) {
state &= TAG_MASK;
- if (state == TAG_RETURN) {
+ if (state == TAG_RETURN || state == TAG_BREAK) {
result = prot_tag->retval;
}
}
@@ -2302,8 +2302,8 @@ rb_eval(self, n)
goto iter_retry;
case TAG_BREAK:
- result = Qnil;
break;
+
case TAG_RETURN:
return_value(result);
/* fall through */
@@ -2314,10 +2314,22 @@ rb_eval(self, n)
break;
case NODE_BREAK:
+ if (node->nd_stts) {
+ return_value(rb_eval(self, node->nd_stts));
+ }
+ else {
+ return_value(Qnil);
+ }
JUMP_TAG(TAG_BREAK);
break;
case NODE_NEXT:
+ if (node->nd_stts) {
+ return_value(rb_eval(self, node->nd_stts));
+ }
+ else {
+ return_value(Qnil);
+ }
JUMP_TAG(TAG_NEXT);
break;
@@ -3574,6 +3586,12 @@ rb_yield_0(val, self, klass, acheck)
RARRAY(val)->len);
}
}
+ else if (block->var == (NODE*)2) {
+ if (val != Qundef && TYPE(val) == T_ARRAY && RARRAY(val)->len != 0) {
+ rb_raise(rb_eArgError, "wrong # of arguments (%d for 0)",
+ RARRAY(val)->len);
+ }
+ }
else {
if (nd_type(block->var) == NODE_MASGN)
massign(self, block->var, val, acheck);
@@ -3614,7 +3632,7 @@ rb_yield_0(val, self, klass, acheck)
goto redo;
case TAG_NEXT:
state = 0;
- result = Qnil;
+ result = prot_tag->retval;
break;
case TAG_BREAK:
case TAG_RETURN:
@@ -3842,7 +3860,7 @@ rb_iterate(it_proc, data1, bl_proc, data2)
}
if (ruby_block->tag->dst == state) {
state &= TAG_MASK;
- if (state == TAG_RETURN) {
+ if (state == TAG_RETURN || state == TAG_BREAK) {
retval = prot_tag->retval;
}
}
@@ -3858,7 +3876,6 @@ rb_iterate(it_proc, data1, bl_proc, data2)
goto iter_retry;
case TAG_BREAK:
- retval = Qnil;
break;
case TAG_RETURN:
@@ -6343,21 +6360,22 @@ proc_call(proc, args)
ruby_block = old_block;
ruby_safe_level = safe;
- if (state) {
- switch (state) {
- case TAG_BREAK:
- break;
- case TAG_RETRY:
- rb_raise(rb_eLocalJumpError, "retry from proc-closure");
- break;
- case TAG_RETURN:
- if (orphan) { /* orphan procedure */
- rb_raise(rb_eLocalJumpError, "return from proc-closure");
- }
- /* fall through */
- default:
- JUMP_TAG(state);
+ switch (state) {
+ case 0:
+ break;
+ case TAG_BREAK:
+ result = prot_tag->retval;
+ break;
+ case TAG_RETRY:
+ rb_raise(rb_eLocalJumpError, "retry from proc-closure");
+ break;
+ case TAG_RETURN:
+ if (orphan) { /* orphan procedure */
+ rb_raise(rb_eLocalJumpError, "return from proc-closure");
}
+ /* fall through */
+ default:
+ JUMP_TAG(state);
}
return result;
}
@@ -6373,6 +6391,7 @@ proc_arity(proc)
Data_Get_Struct(proc, struct BLOCK, data);
if (data->var == 0) return INT2FIX(-1);
if (data->var == (NODE*)1) return INT2FIX(0);
+ if (data->var == (NODE*)2) return INT2FIX(0);
switch (nd_type(data->var)) {
default:
return INT2FIX(-1);
diff --git a/node.h b/node.h
index f64e368ad5..671dbeb520 100644
--- a/node.h
+++ b/node.h
@@ -248,8 +248,8 @@ typedef struct RNode {
#define NEW_UNTIL(c,b,n) rb_node_newnode(NODE_UNTIL,c,b,n)
#define NEW_FOR(v,i,b) rb_node_newnode(NODE_FOR,v,b,i)
#define NEW_ITER(v,i,b) rb_node_newnode(NODE_ITER,v,b,i)
-#define NEW_BREAK() rb_node_newnode(NODE_BREAK,0,0,0)
-#define NEW_NEXT() rb_node_newnode(NODE_NEXT,0,0,0)
+#define NEW_BREAK(s) rb_node_newnode(NODE_BREAK,s,0,0)
+#define NEW_NEXT(s) rb_node_newnode(NODE_NEXT,s,0,0)
#define NEW_REDO() rb_node_newnode(NODE_REDO,0,0,0)
#define NEW_RETRY() rb_node_newnode(NODE_RETRY,0,0,0)
#define NEW_BEGIN(b) rb_node_newnode(NODE_BEGIN,0,b,0)
diff --git a/parse.y b/parse.y
index 7e8d8b42a3..94df4497e2 100644
--- a/parse.y
+++ b/parse.y
@@ -426,21 +426,13 @@ expr : kRETURN ret_args
yyerror("return appeared outside of method");
$$ = NEW_RETURN($2);
}
- | kBREAK
+ | kBREAK ret_args
{
- $$ = NEW_BREAK();
+ $$ = NEW_BREAK($2);
}
- | kNEXT
- {
- $$ = NEW_NEXT();
- }
- | kREDO
- {
- $$ = NEW_REDO();
- }
- | kRETRY
+ | kNEXT ret_args
{
- $$ = NEW_RETRY();
+ $$ = NEW_NEXT($2);
}
| command_call
| expr kAND expr
@@ -1142,19 +1134,6 @@ primary : literal
{
$$ = NEW_HASH($2);
}
- | kRETURN '(' ret_args ')'
- {
- if (!compile_for_eval && !in_def && !in_single)
- yyerror("return appeared outside of method");
- value_expr($3);
- $$ = NEW_RETURN($3);
- }
- | kRETURN '(' ')'
- {
- if (!compile_for_eval && !in_def && !in_single)
- yyerror("return appeared outside of method");
- $$ = NEW_RETURN(0);
- }
| kRETURN
{
if (!compile_for_eval && !in_def && !in_single)
@@ -1359,6 +1338,22 @@ primary : literal
local_pop();
in_single--;
}
+ | kBREAK
+ {
+ $$ = NEW_BREAK(0);
+ }
+ | kNEXT
+ {
+ $$ = NEW_NEXT(0);
+ }
+ | kREDO
+ {
+ $$ = NEW_REDO();
+ }
+ | kRETRY
+ {
+ $$ = NEW_RETRY();
+ }
then : term
| kTHEN
@@ -1399,6 +1394,10 @@ opt_block_var : none
{
$$ = $2;
}
+ | '<' f_args '>'
+ {
+ $$ = (NODE*)2;
+ }
do_block : kDO_BLOCK
diff --git a/variable.c b/variable.c
index 16828a029d..4286f56086 100644
--- a/variable.c
+++ b/variable.c
@@ -700,6 +700,8 @@ rb_alias_variable(name1, name2)
{
struct global_entry *entry1, *entry2;
+ if (rb_safe_level() >= 4)
+ rb_raise(rb_eSecurityError, "Insecure: can't alias global variable");
entry1 = rb_global_entry(name1);
entry2 = rb_global_entry(name2);
diff --git a/version.h b/version.h
index 57dfb4663a..29813a6f6d 100644
--- a/version.h
+++ b/version.h
@@ -1,4 +1,4 @@
#define RUBY_VERSION "1.7.0"
-#define RUBY_RELEASE_DATE "2001-05-21"
+#define RUBY_RELEASE_DATE "2001-05-22"
#define RUBY_VERSION_CODE 170
-#define RUBY_RELEASE_CODE 20010521
+#define RUBY_RELEASE_CODE 20010522