aboutsummaryrefslogtreecommitdiffstats
path: root/struct.c
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-06-22 21:50:31 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-06-22 21:50:31 +0000
commit099e6e7817f2b07cbbf1548b38178086022b5cb3 (patch)
treec1c63c15a0a9e59d21d0217fb91e177ea28d28dd /struct.c
parent8b71b4e5c5b79b2519203626b0cf933971f78117 (diff)
downloadruby-099e6e7817f2b07cbbf1548b38178086022b5cb3.tar.gz
struct.c: cache member definition in a subclass
Since getting Qnil is already error, it is safe to use rb_attr_get. * 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 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50999 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'struct.c')
-rw-r--r--struct.c12
1 files changed, 10 insertions, 2 deletions
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);
+ }
}
}