ruby-changes:45608
From: nobu <ko1@a...>
Date: Wed, 22 Feb 2017 10:55:18 +0900 (JST)
Subject: [ruby-changes:45608] nobu:r57680 (trunk): object.c: refactor rb_obj_clone and rb_obj_clone2
nobu 2017-02-22 10:55:10 +0900 (Wed, 22 Feb 2017) New Revision: 57680 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=57680 Log: object.c: refactor rb_obj_clone and rb_obj_clone2 * object.c (rb_obj_clone2): extract option for clone, and split by whether the object is immutable or mutable. * object.c (rb_obj_clone): no arguments, return immutable object immediately. Modified files: trunk/object.c Index: object.c =================================================================== --- object.c (revision 57679) +++ object.c (revision 57680) @@ -297,6 +297,10 @@ init_copy(VALUE dest, VALUE obj) https://github.com/ruby/ruby/blob/trunk/object.c#L297 } } +static int freeze_opt(int argc, VALUE *argv); +static VALUE immutable_obj_clone(VALUE obj, int kwfreeze); +static VALUE mutable_obj_clone(VALUE obj, int kwfreeze); +PUREFUNC(static inline int special_object_p(VALUE obj)); static inline int special_object_p(VALUE obj) { @@ -339,32 +343,48 @@ special_object_p(VALUE obj) https://github.com/ruby/ruby/blob/trunk/object.c#L343 static VALUE rb_obj_clone2(int argc, VALUE *argv, VALUE obj) { + int kwfreeze = freeze_opt(argc, argv); + if (!special_object_p(obj)) + return mutable_obj_clone(obj, kwfreeze); + return immutable_obj_clone(obj, kwfreeze); +} + +static int +freeze_opt(int argc, VALUE *argv) +{ static ID keyword_ids[1]; VALUE opt; - VALUE kwargs[1]; - VALUE clone; - VALUE singleton; - VALUE kwfreeze = Qtrue; + VALUE kwfreeze; if (!keyword_ids[0]) { CONST_ID(keyword_ids[0], "freeze"); } rb_scan_args(argc, argv, "0:", &opt); if (!NIL_P(opt)) { - rb_get_kwargs(opt, keyword_ids, 0, 1, kwargs); - kwfreeze = kwargs[0]; - if (kwfreeze != Qundef && kwfreeze != Qtrue && kwfreeze != Qfalse) { + rb_get_kwargs(opt, keyword_ids, 0, 1, &kwfreeze); + if (kwfreeze == Qfalse) return FALSE; + if (kwfreeze != Qundef && kwfreeze != Qtrue) { rb_raise(rb_eArgError, "unexpected value for freeze: %"PRIsVALUE, rb_obj_class(kwfreeze)); } } + return TRUE; +} + +static VALUE +immutable_obj_clone(VALUE obj, int kwfreeze) +{ + if (!kwfreeze) + rb_raise(rb_eArgError, "can't unfreeze %"PRIsVALUE, + rb_obj_class(obj)); + return obj; +} + +static VALUE +mutable_obj_clone(VALUE obj, int kwfreeze) +{ + VALUE clone, singleton; - if (special_object_p(obj)) { - if (kwfreeze == Qfalse) - rb_raise(rb_eArgError, "can't unfreeze %"PRIsVALUE, - rb_obj_class(obj)); - return obj; - } clone = rb_obj_alloc(rb_obj_class(obj)); RBASIC(clone)->flags &= (FL_TAINT|FL_PROMOTED0|FL_PROMOTED1); RBASIC(clone)->flags |= RBASIC(obj)->flags & ~(FL_PROMOTED0|FL_PROMOTED1|FL_FREEZE|FL_FINALIZE); @@ -378,7 +398,7 @@ rb_obj_clone2(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/object.c#L398 init_copy(clone, obj); rb_funcall(clone, id_init_clone, 1, obj); - if (Qfalse != kwfreeze) { + if (kwfreeze) { RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE; } @@ -388,7 +408,8 @@ rb_obj_clone2(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/object.c#L408 VALUE rb_obj_clone(VALUE obj) { - return rb_obj_clone2(0, NULL, obj); + if (special_object_p(obj)) return obj; + return mutable_obj_clone(obj, Qtrue); } /* -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/