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

ruby-changes:50608

From: naruse <ko1@a...>
Date: Thu, 15 Mar 2018 16:36:00 +0900 (JST)
Subject: [ruby-changes:50608] naruse:r62761 (ruby_2_5): merge revision(s) 62394, 62395: [Backport #14469]

naruse	2018-03-15 16:35:54 +0900 (Thu, 15 Mar 2018)

  New Revision: 62761

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62761

  Log:
    merge revision(s) 62394,62395: [Backport #14469]
    
    vm_insnhelper.c: rb_autoloading_value flag
    
    * vm_insnhelper.c (vm_get_ev_const): add flag argument of
      `rb_autoloading_value`.
    
    * constant.h (rb_autoloading_value): moved the declaration from
      vm_core.h for `rb_const_flag_t`.  [ruby-core:85516] [Bug #14469]
    
    variable.c: flags at autoloading
    
    * variable.c (const_tbl_update): flags by deprecate_constant /
      private_constant set during autoloading should be preserved
      after required.  [ruby-core:85516] [Bug #14469]

  Modified directories:
    branches/ruby_2_5/
  Modified files:
    branches/ruby_2_5/constant.h
    branches/ruby_2_5/test/ruby/test_autoload.rb
    branches/ruby_2_5/variable.c
    branches/ruby_2_5/version.h
    branches/ruby_2_5/vm_core.h
    branches/ruby_2_5/vm_insnhelper.c
Index: ruby_2_5/constant.h
===================================================================
--- ruby_2_5/constant.h	(revision 62760)
+++ ruby_2_5/constant.h	(revision 62761)
@@ -46,5 +46,6 @@ int rb_public_const_defined(VALUE klass, https://github.com/ruby/ruby/blob/trunk/ruby_2_5/constant.h#L46
 int rb_public_const_defined_at(VALUE klass, ID id);
 int rb_public_const_defined_from(VALUE klass, ID id);
 rb_const_entry_t *rb_const_lookup(VALUE klass, ID id);
+int rb_autoloading_value(VALUE mod, ID id, VALUE *value, rb_const_flag_t *flag);
 
 #endif /* CONSTANT_H */
Index: ruby_2_5/vm_insnhelper.c
===================================================================
--- ruby_2_5/vm_insnhelper.c	(revision 62760)
+++ ruby_2_5/vm_insnhelper.c	(revision 62761)
@@ -837,7 +837,7 @@ vm_get_ev_const(rb_execution_context_t * https://github.com/ruby/ruby/blob/trunk/ruby_2_5/vm_insnhelper.c#L837
 			if (am == klass) break;
 			am = klass;
 			if (is_defined) return 1;
-			if (rb_autoloading_value(klass, id, &av)) return av;
+			if (rb_autoloading_value(klass, id, &av, NULL)) return av;
 			rb_autoload_load(klass, id);
 			goto search_continue;
 		    }
Index: ruby_2_5/version.h
===================================================================
--- ruby_2_5/version.h	(revision 62760)
+++ ruby_2_5/version.h	(revision 62761)
@@ -1,10 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_5/version.h#L1
 #define RUBY_VERSION "2.5.0"
-#define RUBY_RELEASE_DATE "2018-03-02"
-#define RUBY_PATCHLEVEL 39
+#define RUBY_RELEASE_DATE "2018-03-15"
+#define RUBY_PATCHLEVEL 40
 
 #define RUBY_RELEASE_YEAR 2018
 #define RUBY_RELEASE_MONTH 3
-#define RUBY_RELEASE_DAY 2
+#define RUBY_RELEASE_DAY 15
 
 #include "ruby/version.h"
 
Index: ruby_2_5/test/ruby/test_autoload.rb
===================================================================
--- ruby_2_5/test/ruby/test_autoload.rb	(revision 62760)
+++ ruby_2_5/test/ruby/test_autoload.rb	(revision 62761)
@@ -245,6 +245,46 @@ p Foo::Bar https://github.com/ruby/ruby/blob/trunk/ruby_2_5/test/ruby/test_autoload.rb#L245
     assert_ruby_status([script], '', '[ruby-core:81016] [Bug #13526]')
   end
 
+  def test_autoload_private_constant
+    Dir.mktmpdir('autoload') do |tmpdir|
+      File.write(tmpdir+"/zzz.rb", "#{<<~"begin;"}\n#{<<~'end;'}")
+      begin;
+        class AutoloadTest
+          ZZZ = :ZZZ
+          private_constant :ZZZ
+        end
+      end;
+      assert_separately(%W[-I #{tmpdir}], "#{<<-"begin;"}\n#{<<-'end;'}")
+      bug = '[ruby-core:85516] [Bug #14469]'
+      begin;
+        class AutoloadTest
+          autoload :ZZZ, "zzz.rb"
+        end
+        assert_raise(NameError, bug) {AutoloadTest::ZZZ}
+      end;
+    end
+  end
+
+  def test_autoload_deprecate_constant
+    Dir.mktmpdir('autoload') do |tmpdir|
+      File.write(tmpdir+"/zzz.rb", "#{<<~"begin;"}\n#{<<~'end;'}")
+      begin;
+        class AutoloadTest
+          ZZZ = :ZZZ
+          deprecate_constant :ZZZ
+        end
+      end;
+      assert_separately(%W[-I #{tmpdir}], "#{<<-"begin;"}\n#{<<-'end;'}")
+      bug = '[ruby-core:85516] [Bug #14469]'
+      begin;
+        class AutoloadTest
+          autoload :ZZZ, "zzz.rb"
+        end
+        assert_warning(/ZZZ is deprecated/, bug) {AutoloadTest::ZZZ}
+      end;
+    end
+  end
+
   def add_autoload(path)
     (@autoload_paths ||= []) << path
     ::Object.class_eval {autoload(:AutoloadTest, path)}
Index: ruby_2_5/variable.c
===================================================================
--- ruby_2_5/variable.c	(revision 62760)
+++ ruby_2_5/variable.c	(revision 62761)
@@ -1856,6 +1856,7 @@ struct autoload_state { https://github.com/ruby/ruby/blob/trunk/ruby_2_5/variable.c#L1856
 struct autoload_data_i {
     VALUE feature;
     int safe_level;
+    rb_const_flag_t flag;
     VALUE value;
     struct autoload_state *state; /* points to on-stack struct */
 };
@@ -1938,6 +1939,7 @@ rb_autoload_str(VALUE mod, ID id, VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_5/variable.c#L1939
     ele->safe_level = rb_safe_level();
     ele->value = Qundef;
     ele->state = 0;
+    ele->flag = CONST_PUBLIC;
     st_insert(tbl, (st_data_t)id, (st_data_t)ad);
 }
 
@@ -2013,7 +2015,7 @@ check_autoload_required(VALUE mod, ID id https://github.com/ruby/ruby/blob/trunk/ruby_2_5/variable.c#L2015
 }
 
 int
-rb_autoloading_value(VALUE mod, ID id, VALUE* value)
+rb_autoloading_value(VALUE mod, ID id, VALUE* value, rb_const_flag_t *flag)
 {
     VALUE load;
     struct autoload_data_i *ele;
@@ -2026,6 +2028,9 @@ rb_autoloading_value(VALUE mod, ID id, V https://github.com/ruby/ruby/blob/trunk/ruby_2_5/variable.c#L2028
 	    if (value) {
 		*value = ele->value;
 	    }
+	    if (flag) {
+		*flag = ele->flag;
+	    }
 	    return 1;
 	}
     }
@@ -2040,13 +2045,14 @@ autoload_defined_p(VALUE mod, ID id) https://github.com/ruby/ruby/blob/trunk/ruby_2_5/variable.c#L2045
     if (!ce || ce->value != Qundef) {
 	return 0;
     }
-    return !rb_autoloading_value(mod, id, NULL);
+    return !rb_autoloading_value(mod, id, NULL, NULL);
 }
 
 struct autoload_const_set_args {
     VALUE mod;
     ID id;
     VALUE value;
+    rb_const_flag_t flag;
 };
 
 static void const_tbl_update(struct autoload_const_set_args *);
@@ -2093,6 +2099,7 @@ autoload_reset(VALUE arg) https://github.com/ruby/ruby/blob/trunk/ruby_2_5/variable.c#L2099
 	args.mod = state->mod;
 	args.id = state->id;
 	args.value = state->ele->value;
+	args.flag = state->ele->flag;
 	safe_backup = rb_safe_level();
 	rb_set_safe_level_force(state->ele->safe_level);
 	rb_ensure(autoload_const_set, (VALUE)&args,
@@ -2239,6 +2246,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_5/variable.c#L2246
 rb_const_search(VALUE klass, ID id, int exclude, int recurse, int visibility)
 {
     VALUE value, tmp, av;
+    rb_const_flag_t flag;
     int mod_retry = 0;
 
     tmp = klass;
@@ -2257,7 +2265,7 @@ rb_const_search(VALUE klass, ID id, int https://github.com/ruby/ruby/blob/trunk/ruby_2_5/variable.c#L2265
 	    if (value == Qundef) {
 		if (am == tmp) break;
 		am = tmp;
-		if (rb_autoloading_value(tmp, id, &av)) return av;
+		if (rb_autoloading_value(tmp, id, &av, &flag)) return av;
 		rb_autoload_load(tmp, id);
 		continue;
 	    }
@@ -2513,7 +2521,7 @@ rb_const_defined_0(VALUE klass, ID id, i https://github.com/ruby/ruby/blob/trunk/ruby_2_5/variable.c#L2521
 		return (int)Qfalse;
 	    }
 	    if (ce->value == Qundef && !check_autoload_required(tmp, id, 0) &&
-		    !rb_autoloading_value(tmp, id, 0))
+		!rb_autoloading_value(tmp, id, NULL, NULL))
 		return (int)Qfalse;
 
 	    if (exclude && tmp == rb_cObject && klass != rb_cObject) {
@@ -2599,6 +2607,7 @@ rb_const_set(VALUE klass, ID id, VALUE v https://github.com/ruby/ruby/blob/trunk/ruby_2_5/variable.c#L2607
 	args.mod = klass;
 	args.id = id;
 	args.value = val;
+	args.flag = CONST_PUBLIC;
 	const_tbl_update(&args);
     }
     /*
@@ -2630,6 +2639,21 @@ rb_const_set(VALUE klass, ID id, VALUE v https://github.com/ruby/ruby/blob/trunk/ruby_2_5/variable.c#L2639
     }
 }
 
+static struct autoload_data_i *
+current_autoload_data(VALUE mod, ID id)
+{
+    struct autoload_data_i *ele;
+    VALUE load = autoload_data(mod, id);
+    if (!load) return 0;
+    ele = check_autoload_data(load);
+    if (!ele) return 0;
+    /* for autoloading thread, keep the defined value to autoloading storage */
+    if (ele->state && (ele->state->thread == rb_thread_current())) {
+	return ele;
+    }
+    return 0;
+}
+
 static void
 const_tbl_update(struct autoload_const_set_args *args)
 {
@@ -2638,19 +2662,15 @@ const_tbl_update(struct autoload_const_s https://github.com/ruby/ruby/blob/trunk/ruby_2_5/variable.c#L2662
     VALUE val = args->value;
     ID id = args->id;
     struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
-    rb_const_flag_t visibility = CONST_PUBLIC;
+    rb_const_flag_t visibility = args->flag;
     rb_const_entry_t *ce;
 
     if (rb_id_table_lookup(tbl, id, &value)) {
 	ce = (rb_const_entry_t *)value;
 	if (ce->value == Qundef) {
-	    VALUE load;
-	    struct autoload_data_i *ele;
+	    struct autoload_data_i *ele = current_autoload_data(klass, id);
 
-	    load = autoload_data(klass, id);
-	    /* for autoloading thread, keep the defined value to autoloading storage */
-	    if (load && (ele = check_autoload_data(load)) && ele->state &&
-			(ele->state->thread == rb_thread_current())) {
+	    if (ele) {
 		rb_clear_constant_cache();
 
 		ele->value = val; /* autoload_i is non-WB-protected */
@@ -2739,6 +2759,13 @@ set_const_visibility(VALUE mod, int argc https://github.com/ruby/ruby/blob/trunk/ruby_2_5/variable.c#L2759
 	if ((ce = rb_const_lookup(mod, id))) {
 	    ce->flag &= ~mask;
 	    ce->flag |= flag;
+	    if (ce->value == Qundef) {
+		struct autoload_data_i *ele = current_autoload_data(mod, id);
+		if (ele) {
+		    ele->flag &= ~mask;
+		    ele->flag |= flag;
+		}
+	    }
 	}
 	else {
 	    if (i > 0) {
Index: ruby_2_5/vm_core.h
===================================================================
--- ruby_2_5/vm_core.h	(revision 62760)
+++ ruby_2_5/vm_core.h	(revision 62761)
@@ -1561,8 +1561,6 @@ void rb_vm_register_special_exception_st https://github.com/ruby/ruby/blob/trunk/ruby_2_5/vm_core.h#L1561
 
 void rb_gc_mark_machine_stack(const rb_execution_context_t *ec);
 
-int rb_autoloading_value(VALUE mod, ID id, VALUE* value);
-
 void rb_vm_rewrite_cref(rb_cref_t *node, VALUE old_klass, VALUE new_klass, rb_cref_t **new_cref_ptr);
 
 const rb_callable_method_entry_t *rb_vm_frame_method_entry(const rb_control_frame_t *cfp);
Index: ruby_2_5
===================================================================
--- ruby_2_5	(revision 62760)
+++ ruby_2_5	(revision 62761)

Property changes on: ruby_2_5
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /trunk:r62394-62395

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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