summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-05-14 06:22:31 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-05-14 06:22:31 +0000
commiteb6118992b77df9ddd3f95692d357e09b353c358 (patch)
tree75790afdc7305f70f15d2c9140a8a6d75c482c80 /eval.c
parentc5d6a1ba48306652bb96bf0bf081c8c66cb45ef5 (diff)
* eval.c (rb_clear_cache_by_class): new function.
* eval.c (set_method_visibility): should have clear cache forq updated visibility. * numeric.c (flo_to_s): default format precision to be "%.16g". * util.c (ruby_strtod): use own strtod(3) implementation to avoid locale hell. Due to this change "0xff".to_f no longer returns 255.0 * eval.c (avalue_to_yvalue): new function to distinguish yvalue (no-arg == Qundef) from svalue (no-arg == Qnil). * eval.c (rb_yield_0): use avalue_to_yvalue(). * eval.c (assign): warn if val == Qundef where it means rhs is void (e.g. yield without value or call without argument). * parse.y (value_expr): need not to warn for WHILE and UNTIL, since they can have return value (via valued break). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2457 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c62
1 files changed, 49 insertions, 13 deletions
diff --git a/eval.c b/eval.c
index 636648cb0e..628e16c969 100644
--- a/eval.c
+++ b/eval.c
@@ -217,6 +217,21 @@ rb_clear_cache_by_id(id)
}
}
+static void
+rb_clear_cache_by_class(klass)
+ VALUE klass;
+{
+ struct cache_entry *ent, *end;
+
+ ent = cache; end = ent + CACHE_SIZE;
+ while (ent < end) {
+ if (ent->origin == klass) {
+ ent->mid = 0;
+ }
+ ent++;
+ }
+}
+
void
rb_add_method(klass, mid, node, noex)
VALUE klass;
@@ -2112,10 +2127,27 @@ avalue_to_svalue(v)
}
static VALUE
+avalue_to_yvalue(v)
+ VALUE v;
+{
+ if (TYPE(v) != T_ARRAY) {
+ v = rb_ary_to_ary(v);
+ }
+ if (RARRAY(v)->len == 0) {
+ return Qundef;
+ }
+ if (RARRAY(v)->len == 1) {
+ return RARRAY(v)->ptr[0];
+ }
+ return v;
+}
+
+static VALUE
svalue_to_mvalue(v)
VALUE v;
{
- if (NIL_P(v)) return rb_ary_new2(0);
+ if (v == Qnil || v == Qundef)
+ return rb_ary_new2(0);
if (TYPE(v) == T_ARRAY) {
return v;
}
@@ -2511,10 +2543,10 @@ rb_eval(self, n)
case NODE_YIELD:
if (node->nd_stts) {
- result = avalue_to_svalue(rb_eval(self, node->nd_stts));
+ result = avalue_to_yvalue(rb_eval(self, node->nd_stts));
}
else {
- result = Qnil;
+ result = Qundef; /* no arg */
}
result = rb_yield_0(result, 0, 0, 0);
break;
@@ -3745,21 +3777,21 @@ rb_yield_0(val, self, klass, pcall)
RARRAY(val)->len);
}
}
+ else if (nd_type(block->var) == NODE_MASGN) {
+ massign(self, block->var, val, pcall);
+ }
else {
- if (nd_type(block->var) == NODE_MASGN) {
- massign(self, block->var, val, pcall);
- }
- else {
- if (pcall) val = avalue_to_svalue(val);
- assign(self, block->var, val, pcall);
+ if (pcall) {
+ val = avalue_to_yvalue(val);
}
+ assign(self, block->var, val, pcall);
}
}
POP_TAG();
if (state) goto pop_state;
}
else if (pcall) {
- val = avalue_to_svalue(val);
+ val = avalue_to_yvalue(val);
}
PUSH_ITER(block->iter);
@@ -3849,7 +3881,7 @@ static VALUE
rb_f_loop()
{
for (;;) {
- rb_yield_0(Qnil, 0, 0, 0);
+ rb_yield_0(Qundef, 0, 0, 0);
CHECK_INTS;
}
return Qnil; /* dummy */
@@ -3912,7 +3944,10 @@ assign(self, lhs, val, pcall)
VALUE val;
int pcall;
{
- if (val == Qundef) val = Qnil;
+ if (val == Qundef) {
+ rb_warning("assigning void value");
+ val = Qnil;
+ }
switch (nd_type(lhs)) {
case NODE_GASGN:
rb_gvar_set(lhs->nd_entry, val);
@@ -5623,6 +5658,7 @@ set_method_visibility(self, argc, argv, ex)
for (i=0; i<argc; i++) {
rb_export_method(self, rb_to_id(argv[i]), ex);
}
+ rb_clear_cache_by_class(self);
}
static VALUE
@@ -6470,7 +6506,7 @@ proc_invoke(proc, args, pcall, self)
ruby_frame->iter = ITER_CUR;
if (!pcall) {
- args = avalue_to_svalue(args);
+ args = avalue_to_yvalue(args);
}
PUSH_TAG(PROT_NONE);
state = EXEC_TAG();