[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]