ruby-changes:60430
From: S.H <ko1@a...>
Date: Tue, 17 Mar 2020 19:37:26 +0900 (JST)
Subject: [ruby-changes:60430] 290d608637 (master): support builtin for Kernel#clone
https://git.ruby-lang.org/ruby.git/commit/?id=290d608637 From 290d608637e37323bb6eeda1b1466519f16308a5 Mon Sep 17 00:00:00 2001 From: "S.H" <gamelinks007@g...> Date: Tue, 17 Mar 2020 19:37:07 +0900 Subject: support builtin for Kernel#clone diff --git a/.document b/.document index a5018a6..1cb2722 100644 --- a/.document +++ b/.document @@ -14,6 +14,7 @@ array.rb https://github.com/ruby/ruby/blob/trunk/.document#L14 ast.rb gc.rb io.rb +kernel.rb pack.rb trace_point.rb warning.rb diff --git a/benchmark/kernel_clone.yml b/benchmark/kernel_clone.yml new file mode 100644 index 0000000..069b23a --- /dev/null +++ b/benchmark/kernel_clone.yml @@ -0,0 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/benchmark/kernel_clone.yml#L1 +prelude: "object = Object.new" +benchmark: + clone: "object.clone" + clone_true: "object.clone(freeze: true)" + clone_false: "object.clone(freeze: false)" +loop_count: 10000 diff --git a/common.mk b/common.mk index 60e7204..8182eb7 100644 --- a/common.mk +++ b/common.mk @@ -1003,6 +1003,7 @@ BUILTIN_RB_SRCS = \ https://github.com/ruby/ruby/blob/trunk/common.mk#L1003 $(srcdir)/trace_point.rb \ $(srcdir)/warning.rb \ $(srcdir)/array.rb \ + $(srcdir)/kernel.rb \ $(srcdir)/prelude.rb \ $(srcdir)/gem_prelude.rb \ $(empty) @@ -2848,6 +2849,7 @@ miniinit.$(OBJEXT): {$(VPATH)}intern.h https://github.com/ruby/ruby/blob/trunk/common.mk#L2849 miniinit.$(OBJEXT): {$(VPATH)}internal.h miniinit.$(OBJEXT): {$(VPATH)}io.rb miniinit.$(OBJEXT): {$(VPATH)}iseq.h +miniinit.$(OBJEXT): {$(VPATH)}kernel.rb miniinit.$(OBJEXT): {$(VPATH)}method.h miniinit.$(OBJEXT): {$(VPATH)}mini_builtin.c miniinit.$(OBJEXT): {$(VPATH)}miniinit.c @@ -3101,6 +3103,7 @@ object.$(OBJEXT): $(top_srcdir)/internal/variable.h https://github.com/ruby/ruby/blob/trunk/common.mk#L3103 object.$(OBJEXT): $(top_srcdir)/internal/vm.h object.$(OBJEXT): $(top_srcdir)/internal/warnings.h object.$(OBJEXT): {$(VPATH)}assert.h +object.$(OBJEXT): {$(VPATH)}builtin.h object.$(OBJEXT): {$(VPATH)}config.h object.$(OBJEXT): {$(VPATH)}constant.h object.$(OBJEXT): {$(VPATH)}defines.h @@ -3109,6 +3112,7 @@ object.$(OBJEXT): {$(VPATH)}id.h https://github.com/ruby/ruby/blob/trunk/common.mk#L3112 object.$(OBJEXT): {$(VPATH)}id_table.h object.$(OBJEXT): {$(VPATH)}intern.h object.$(OBJEXT): {$(VPATH)}internal.h +object.$(OBJEXT): {$(VPATH)}kernel.rbinc object.$(OBJEXT): {$(VPATH)}missing.h object.$(OBJEXT): {$(VPATH)}object.c object.$(OBJEXT): {$(VPATH)}onigmo.h diff --git a/inits.c b/inits.c index 39cbe5f..dae5e1f 100644 --- a/inits.c +++ b/inits.c @@ -84,6 +84,7 @@ rb_call_inits(void) https://github.com/ruby/ruby/blob/trunk/inits.c#L84 BUILTIN(pack); BUILTIN(warning); BUILTIN(array); + BUILTIN(kernel); Init_builtin_prelude(); } #undef CALL diff --git a/kernel.rb b/kernel.rb new file mode 100644 index 0000000..46d9438 --- /dev/null +++ b/kernel.rb @@ -0,0 +1,29 @@ https://github.com/ruby/ruby/blob/trunk/kernel.rb#L1 +module Kernel + # + # call-seq: + # obj.clone(freeze: true) -> an_object + # + # Produces a shallow copy of <i>obj</i>---the instance variables of + # <i>obj</i> are copied, but not the objects they reference. + # #clone copies the frozen (unless +:freeze+ keyword argument is + # given with a false value) state of <i>obj</i>. See + # also the discussion under Object#dup. + # + # class Klass + # attr_accessor :str + # end + # s1 = Klass.new #=> #<Klass:0x401b3a38> + # s1.str = "Hello" #=> "Hello" + # s2 = s1.clone #=> #<Klass:0x401b3998 @str="Hello"> + # s2.str[1,4] = "i" #=> "i" + # s1.inspect #=> "#<Klass:0x401b3a38 @str=\"Hi\">" + # s2.inspect #=> "#<Klass:0x401b3998 @str=\"Hi\">" + # + # This method may have class-specific behavior. If so, that + # behavior will be documented under the #+initialize_copy+ method of + # the class. + # + def clone(freeze: true) + __builtin_rb_obj_clone2(freeze) + end +end diff --git a/object.c b/object.c index 496955e..0f5650e 100644 --- a/object.c +++ b/object.c @@ -36,6 +36,7 @@ https://github.com/ruby/ruby/blob/trunk/object.c#L36 #include "ruby/encoding.h" #include "ruby/st.h" #include "ruby/util.h" +#include "builtin.h" /*! * \defgroup object Core objects and their operations @@ -389,35 +390,21 @@ special_object_p(VALUE obj) https://github.com/ruby/ruby/blob/trunk/object.c#L390 } } -/* - * call-seq: - * obj.clone(freeze: true) -> an_object - * - * Produces a shallow copy of <i>obj</i>---the instance variables of - * <i>obj</i> are copied, but not the objects they reference. - * #clone copies the frozen (unless +:freeze+ keyword argument is - * given with a false value) state of <i>obj</i>. See - * also the discussion under Object#dup. - * - * class Klass - * attr_accessor :str - * end - * s1 = Klass.new #=> #<Klass:0x401b3a38> - * s1.str = "Hello" #=> "Hello" - * s2 = s1.clone #=> #<Klass:0x401b3998 @str="Hello"> - * s2.str[1,4] = "i" #=> "i" - * s1.inspect #=> "#<Klass:0x401b3a38 @str=\"Hi\">" - * s2.inspect #=> "#<Klass:0x401b3998 @str=\"Hi\">" - * - * This method may have class-specific behavior. If so, that - * behavior will be documented under the #+initialize_copy+ method of - * the class. - */ +static int +obj_freeze_opt(VALUE freeze) +{ + if (freeze == Qfalse) return FALSE; + + if (freeze != Qtrue) + rb_raise(rb_eArgError, "unexpected value for freeze: %"PRIsVALUE, rb_obj_class(freeze)); + + return TRUE; +} static VALUE -rb_obj_clone2(int argc, VALUE *argv, VALUE obj) +rb_obj_clone2(rb_execution_context_t *ec, VALUE obj, VALUE freeze) { - int kwfreeze = freeze_opt(argc, argv); + int kwfreeze = obj_freeze_opt(freeze); if (!special_object_p(obj)) return mutable_obj_clone(obj, kwfreeze); return immutable_obj_clone(obj, kwfreeze); @@ -437,6 +424,7 @@ freeze_opt(int argc, VALUE *argv) https://github.com/ruby/ruby/blob/trunk/object.c#L424 static ID keyword_ids[1]; VALUE opt; VALUE kwfreeze; + int ret = 1; if (!keyword_ids[0]) { CONST_ID(keyword_ids[0], "freeze"); @@ -444,13 +432,9 @@ freeze_opt(int argc, VALUE *argv) https://github.com/ruby/ruby/blob/trunk/object.c#L432 rb_scan_args(argc, argv, "0:", &opt); if (!NIL_P(opt)) { 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)); - } + ret = obj_freeze_opt(kwfreeze); } - return TRUE; + return ret; } static VALUE @@ -4612,7 +4596,6 @@ InitVM_Object(void) https://github.com/ruby/ruby/blob/trunk/object.c#L4596 rb_define_method(rb_mKernel, "class", rb_obj_class, 0); rb_define_method(rb_mKernel, "singleton_class", rb_obj_singleton_class, 0); - rb_define_method(rb_mKernel, "clone", rb_obj_clone2, -1); rb_define_method(rb_mKernel, "dup", rb_obj_dup, 0); rb_define_method(rb_mKernel, "itself", rb_obj_itself, 0); rb_define_method(rb_mKernel, "yield_self", rb_obj_yield_self, 0); @@ -4790,6 +4773,8 @@ InitVM_Object(void) https://github.com/ruby/ruby/blob/trunk/object.c#L4773 rb_deprecate_constant(rb_cObject, "FALSE"); } +#include "kernel.rbinc" + void Init_Object(void) { -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/