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

ruby-changes:38677

From: normal <ko1@a...>
Date: Thu, 4 Jun 2015 05:53:50 +0900 (JST)
Subject: [ruby-changes:38677] normal:r50758 (trunk): variable.c: remove generic ivar support for special constants

normal	2015-06-04 05:53:35 +0900 (Thu, 04 Jun 2015)

  New Revision: 50758

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

  Log:
    variable.c: remove generic ivar support for special constants
    
    Special constants are all frozen since [Feature #8923] and cannot
    support ivars.  Remove some unused code we had for supporting them.
    
    * variable.c (special_generic_ivar): remove flag
      (givar_i, rb_mark_generic_ivar_tbl): remove functions
      (rb_free_generic_ivar, rb_ivar_lookup, rb_ivar_delete,
       generic_ivar_set, rb_ivar_set, rb_ivar_defined,
       rb_copy_generic_ivar, rb_ivar_foreach, rb_ivar_count,
       rb_obj_remove_instance_variable):
       adjust for lack of ivar support in special constants
    * test/ruby/test_variable.rb: test ivars for special consts
    * internal.h: remove rb_mark_generic_ivar_tbl decl
    * gc.c (gc_mark_roots): remove rb_mark_generic_ivar_tbl call

  Modified files:
    trunk/ChangeLog
    trunk/gc.c
    trunk/internal.h
    trunk/test/ruby/test_variable.rb
    trunk/variable.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 50757)
+++ ChangeLog	(revision 50758)
@@ -1,3 +1,16 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Jun  4 05:44:01 2015  Eric Wong  <e@8...>
+
+	* variable.c (special_generic_ivar): remove flag
+	  (givar_i, rb_mark_generic_ivar_tbl): remove functions
+	  (rb_free_generic_ivar, rb_ivar_lookup, rb_ivar_delete,
+	   generic_ivar_set, rb_ivar_set, rb_ivar_defined,
+	   rb_copy_generic_ivar, rb_ivar_foreach, rb_ivar_count,
+	   rb_obj_remove_instance_variable):
+	   adjust for lack of ivar support in special constants
+	* test/ruby/test_variable.rb: test ivars for special consts
+	* internal.h: remove rb_mark_generic_ivar_tbl decl
+	* gc.c (gc_mark_roots): remove rb_mark_generic_ivar_tbl call
+
 Thu Jun  4 05:13:34 2015  Koichi Sasada  <ko1@a...>
 
 	* vm_insnhelper.c (def_iseq_ptr): `iseqval' is not available any more.
Index: variable.c
===================================================================
--- variable.c	(revision 50757)
+++ variable.c	(revision 50758)
@@ -25,7 +25,6 @@ static void setup_const_entry(rb_const_e https://github.com/ruby/ruby/blob/trunk/variable.c#L25
 static int const_update(st_data_t *, st_data_t *, st_data_t, int);
 static st_table *generic_iv_tbl;
 static st_table *generic_iv_tbl_compat;
-static int special_generic_ivar;
 
 /* per-object */
 struct gen_ivtbl {
@@ -1182,23 +1181,6 @@ rb_mark_generic_ivar(VALUE obj) https://github.com/ruby/ruby/blob/trunk/variable.c#L1181
     }
 }
 
-static int
-givar_i(st_data_t k, st_data_t v, st_data_t a)
-{
-    VALUE obj = (VALUE)k;
-    if (rb_special_const_p(obj)) {
-	gen_ivtbl_mark((const struct gen_ivtbl *)v);
-    }
-    return ST_CONTINUE;
-}
-
-void
-rb_mark_generic_ivar_tbl(void)
-{
-    if (special_generic_ivar == 0) return;
-    st_foreach_safe(generic_iv_tbl, givar_i, 0);
-}
-
 void
 rb_free_generic_ivar(VALUE obj)
 {
@@ -1249,7 +1231,7 @@ rb_ivar_lookup(VALUE obj, ID id, VALUE u https://github.com/ruby/ruby/blob/trunk/variable.c#L1231
     long len;
     st_data_t index;
 
-    if (SPECIAL_CONST_P(obj)) goto generic;
+    if (SPECIAL_CONST_P(obj)) return undef;
     switch (BUILTIN_TYPE(obj)) {
       case T_OBJECT:
         len = ROBJECT_NUMIV(obj);
@@ -1268,8 +1250,7 @@ rb_ivar_lookup(VALUE obj, ID id, VALUE u https://github.com/ruby/ruby/blob/trunk/variable.c#L1250
 	    return (VALUE)index;
 	break;
       default:
-      generic:
-	if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))
+	if (FL_TEST(obj, FL_EXIVAR))
 	    return generic_ivar_get(obj, id, undef);
 	break;
     }
@@ -1303,7 +1284,7 @@ rb_ivar_delete(VALUE obj, ID id, VALUE u https://github.com/ruby/ruby/blob/trunk/variable.c#L1284
     long len;
     st_data_t index;
 
-    if (SPECIAL_CONST_P(obj)) goto generic;
+    rb_check_frozen(obj);
     switch (BUILTIN_TYPE(obj)) {
       case T_OBJECT:
         len = ROBJECT_NUMIV(obj);
@@ -1323,8 +1304,7 @@ rb_ivar_delete(VALUE obj, ID id, VALUE u https://github.com/ruby/ruby/blob/trunk/variable.c#L1304
 	    return (VALUE)index;
 	break;
       default:
-      generic:
-	if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))
+	if (FL_TEST(obj, FL_EXIVAR))
 	    return generic_ivar_delete(obj, id, undef);
 	break;
     }
@@ -1369,11 +1349,6 @@ generic_ivar_set(VALUE obj, ID id, VALUE https://github.com/ruby/ruby/blob/trunk/variable.c#L1349
 {
     struct ivar_update ivup;
 
-    if (rb_special_const_p(obj)) {
-	if (rb_obj_frozen_p(obj)) rb_error_frozen("object");
-	special_generic_ivar = 1;
-    }
-
     ivup.extended = 0;
     ivup.u.iv_index_tbl = iv_index_tbl_make(obj);
     iv_index_tbl_extend(&ivup, id);
@@ -1392,7 +1367,7 @@ rb_ivar_set(VALUE obj, ID id, VALUE val) https://github.com/ruby/ruby/blob/trunk/variable.c#L1367
     long i, len;
 
     rb_check_frozen(obj);
-    if (SPECIAL_CONST_P(obj)) goto generic;
+
     switch (BUILTIN_TYPE(obj)) {
       case T_OBJECT:
         ivup.extended = 0;
@@ -1436,7 +1411,6 @@ rb_ivar_set(VALUE obj, ID id, VALUE val) https://github.com/ruby/ruby/blob/trunk/variable.c#L1411
 	rb_st_insert_id_and_value(obj, RCLASS_IV_TBL(obj), (st_data_t)id, val);
         break;
       default:
-      generic:
 	generic_ivar_set(obj, id, val);
 	break;
     }
@@ -1449,7 +1423,8 @@ rb_ivar_defined(VALUE obj, ID id) https://github.com/ruby/ruby/blob/trunk/variable.c#L1423
     VALUE val;
     struct st_table *iv_index_tbl;
     st_data_t index;
-    if (SPECIAL_CONST_P(obj)) goto generic;
+
+    if (SPECIAL_CONST_P(obj)) return Qfalse;
     switch (BUILTIN_TYPE(obj)) {
       case T_OBJECT:
         iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
@@ -1466,8 +1441,7 @@ rb_ivar_defined(VALUE obj, ID id) https://github.com/ruby/ruby/blob/trunk/variable.c#L1441
 	    return Qtrue;
 	break;
       default:
-      generic:
-	if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))
+	if (FL_TEST(obj, FL_EXIVAR))
 	    return generic_ivar_defined(obj, id);
 	break;
     }
@@ -1577,10 +1551,7 @@ rb_copy_generic_ivar(VALUE clone, VALUE https://github.com/ruby/ruby/blob/trunk/variable.c#L1551
 {
     struct gen_ivtbl *ivtbl;
 
-    if (rb_special_const_p(clone)) {
-	if (rb_obj_frozen_p(clone)) rb_error_frozen("object");
-	special_generic_ivar = 1;
-    }
+    rb_check_frozen(clone);
 
     if (!FL_TEST(obj, FL_EXIVAR)) {
       clear:
@@ -1620,7 +1591,7 @@ rb_copy_generic_ivar(VALUE clone, VALUE https://github.com/ruby/ruby/blob/trunk/variable.c#L1591
 void
 rb_ivar_foreach(VALUE obj, int (*func)(ANYARGS), st_data_t arg)
 {
-    if (SPECIAL_CONST_P(obj)) goto generic;
+    if (SPECIAL_CONST_P(obj)) return;
     switch (BUILTIN_TYPE(obj)) {
       case T_OBJECT:
         obj_ivar_each(obj, func, arg);
@@ -1632,8 +1603,7 @@ rb_ivar_foreach(VALUE obj, int (*func)(A https://github.com/ruby/ruby/blob/trunk/variable.c#L1603
 	}
 	break;
       default:
-      generic:
-	if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
+	if (FL_TEST(obj, FL_EXIVAR)) {
 	    gen_ivar_each(obj, func, arg);
 	}
 	break;
@@ -1644,7 +1614,9 @@ st_index_t https://github.com/ruby/ruby/blob/trunk/variable.c#L1614
 rb_ivar_count(VALUE obj)
 {
     st_table *tbl;
-    if (SPECIAL_CONST_P(obj)) goto generic;
+
+    if (SPECIAL_CONST_P(obj)) return 0;
+
     switch (BUILTIN_TYPE(obj)) {
       case T_OBJECT:
 	if ((tbl = ROBJECT_IV_INDEX_TBL(obj)) != 0) {
@@ -1665,8 +1637,7 @@ rb_ivar_count(VALUE obj) https://github.com/ruby/ruby/blob/trunk/variable.c#L1637
 	}
 	break;
       default:
-      generic:
-	if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
+	if (FL_TEST(obj, FL_EXIVAR)) {
 	    struct gen_ivtbl *ivtbl;
 
 	    if (gen_ivtbl_get(obj, &ivtbl)) {
@@ -1764,7 +1735,6 @@ rb_obj_remove_instance_variable(VALUE ob https://github.com/ruby/ruby/blob/trunk/variable.c#L1735
 		      QUOTE_ID(id));
     }
 
-    if (SPECIAL_CONST_P(obj)) goto generic;
     switch (BUILTIN_TYPE(obj)) {
       case T_OBJECT:
         iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
@@ -1785,8 +1755,7 @@ rb_obj_remove_instance_variable(VALUE ob https://github.com/ruby/ruby/blob/trunk/variable.c#L1755
 	}
 	break;
       default:
-      generic:
-	if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
+	if (FL_TEST(obj, FL_EXIVAR)) {
 	    v = val;
 	    if (generic_ivar_remove(obj, (st_data_t)id, &v)) {
 		return (VALUE)v;
Index: gc.c
===================================================================
--- gc.c	(revision 50757)
+++ gc.c	(revision 50758)
@@ -4579,10 +4579,6 @@ gc_mark_roots(rb_objspace_t *objspace, c https://github.com/ruby/ruby/blob/trunk/gc.c#L4579
     MARK_CHECKPOINT("global_tbl");
     rb_gc_mark_global_tbl();
 
-    /* mark generic instance variables for special constants */
-    MARK_CHECKPOINT("generic_ivars");
-    rb_mark_generic_ivar_tbl();
-
     if (stress_to_class) rb_gc_mark(stress_to_class);
 
     MARK_CHECKPOINT("finish");
Index: internal.h
===================================================================
--- internal.h	(revision 50757)
+++ internal.h	(revision 50758)
@@ -1284,7 +1284,6 @@ extern unsigned long ruby_scan_digits(co https://github.com/ruby/ruby/blob/trunk/internal.h#L1284
 /* variable.c (export) */
 void rb_gc_mark_global_tbl(void);
 void rb_mark_generic_ivar(VALUE);
-void rb_mark_generic_ivar_tbl(void);
 VALUE rb_const_missing(VALUE klass, VALUE name);
 
 int rb_st_insert_id_and_value(VALUE obj, st_table *tbl, ID key, VALUE value);
Index: test/ruby/test_variable.rb
===================================================================
--- test/ruby/test_variable.rb	(revision 50757)
+++ test/ruby/test_variable.rb	(revision 50758)
@@ -118,4 +118,22 @@ class TestVariable < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/ruby/test_variable.rb#L118
       }
     }
   end
+
+  def test_special_constant_ivars
+    [ true, false, :symbol, "dsym#{rand(9999)}".to_sym, 1, 1.0 ].each do |v|
+      assert_empty v.instance_variables
+      msg = "can't modify frozen #{v.class}"
+
+      assert_raise_with_message(RuntimeError, msg) do
+        v.instance_variable_set(:@foo, :bar)
+      end
+
+      assert_nil v.instance_variable_get(:@foo)
+      refute v.instance_variable_defined?(:@foo)
+
+      assert_raise_with_message(RuntimeError, msg) do
+        v.remove_instance_variable(:@foo)
+      end
+    end
+  end
 end

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

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