From 099e6e7817f2b07cbbf1548b38178086022b5cb3 Mon Sep 17 00:00:00 2001 From: normal Date: Mon, 22 Jun 2015 21:50:31 +0000 Subject: 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 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 --- ChangeLog | 6 ++++++ struct.c | 12 ++++++++++-- 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 + + * struct.c (struct_ivar_get): cache member definition in a subclass + Thanks to Sokolov Yura aka funny_falcon + in https://bugs.ruby-lang.org/issues/10585 + Tue Jun 23 04:58:06 2015 Eric Wong * 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); + } } } -- cgit v1.2.3