aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--struct.c12
2 files changed, 16 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 20ac38da3b..907d1d81db 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Tue Jun 23 06:37:10 2015 Eric Wong <e@80x24.org>
+
+ * struct.c (struct_ivar_get): cache member definition in a subclass
+ Thanks to Sokolov Yura aka funny_falcon <funny.falcon@gmail.com>
+ in https://bugs.ruby-lang.org/issues/10585
+
Tue Jun 23 04:58:06 2015 Eric Wong <e@80x24.org>
* benchmark/bm_vm2_struct_big_href_hi.rb: new benchmark
diff --git a/struct.c b/struct.c
index d616e67cb4..ff4501d03e 100644
--- a/struct.c
+++ b/struct.c
@@ -23,12 +23,20 @@ static VALUE struct_alloc(VALUE);
static inline VALUE
struct_ivar_get(VALUE c, ID id)
{
+ VALUE orig = c;
+ VALUE ivar = rb_attr_get(c, id);
+
+ if (!NIL_P(ivar))
+ return ivar;
+
for (;;) {
- if (rb_ivar_defined(c, id))
- return rb_ivar_get(c, id);
c = RCLASS_SUPER(c);
if (c == 0 || c == rb_cStruct)
return Qnil;
+ ivar = rb_attr_get(c, id);
+ if (!NIL_P(ivar)) {
+ return rb_ivar_set(orig, id, ivar);
+ }
}
}