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

ruby-changes:21044

From: nahi <ko1@a...>
Date: Sat, 27 Aug 2011 11:19:52 +0900 (JST)
Subject: [ruby-changes:21044] nahi:r33093 (trunk): * Revert r33078. It caused a Rails application NoMethodError.

nahi	2011-08-27 11:19:42 +0900 (Sat, 27 Aug 2011)

  New Revision: 33093

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

  Log:
    * Revert r33078. It caused a Rails application NoMethodError.
    
      /home/nahi/git/emptyApp/ruby/1.9.1/gems/rack-mount-0.6.14/lib/rack/mount/utils.rb:157: warning: toplevel constant ScanError referenced by Regin::Parser::ScanError
      /home/nahi/git/emptyApp/ruby/1.9.1/gems/rack-mount-0.6.14/lib/rack/mount/vendor/regin/regin/parser.rb:17:in `parse_regexp': undefined method `scan_str' for #<Regin::Parser:0x00000002344548> (NoMethodError)

  Modified files:
    trunk/ChangeLog
    trunk/test/ruby/test_autoload.rb
    trunk/variable.c
    trunk/vm_insnhelper.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 33092)
+++ ChangeLog	(revision 33093)
@@ -1,3 +1,10 @@
+Sat Aug 27 11:18:12 2011  Hiroshi Nakamura  <nahi@r...>
+
+	* Revert r33078. It caused a Rails application NoMethodError.
+
+	  /home/nahi/git/emptyApp/ruby/1.9.1/gems/rack-mount-0.6.14/lib/rack/mount/utils.rb:157: warning: toplevel constant ScanError referenced by Regin::Parser::ScanError
+	  /home/nahi/git/emptyApp/ruby/1.9.1/gems/rack-mount-0.6.14/lib/rack/mount/vendor/regin/regin/parser.rb:17:in `parse_regexp': undefined method `scan_str' for #<Regin::Parser:0x00000002344548> (NoMethodError)
+
 Sat Aug 27 08:44:58 2011  Eric Hodel  <drbrain@s...>
 
 	* lib/rdoc:  Import RDoc 3.9.4.  Typo and grammar fixes by Luke Gruber.
Index: variable.c
===================================================================
--- variable.c	(revision 33092)
+++ variable.c	(revision 33093)
@@ -1445,63 +1445,12 @@
 #define check_autoload_table(av) \
     (struct st_table *)rb_check_typeddata((av), &autoload_data_type)
 
-static VALUE
-autoload_data(VALUE mod, ID id)
-{
-    struct st_table *tbl;
-    st_data_t val;
-
-    if (!st_lookup(RCLASS_IV_TBL(mod), autoload, &val) ||
-	    !(tbl = check_autoload_table((VALUE)val)) || !st_lookup(tbl, (st_data_t)id, &val)) {
-	return 0;
-    }
-    return (VALUE)val;
-}
-
-struct autoload_data_i {
-    VALUE feature;
-    int safe_level;
-    VALUE thread;
-    VALUE value;
-};
-
-static void
-autoload_i_mark(void *ptr)
-{
-    struct autoload_data_i *p = ptr;
-    rb_gc_mark(p->feature);
-    rb_gc_mark(p->thread);
-    rb_gc_mark(p->value);
-}
-
-static void
-autoload_i_free(void *ptr)
-{
-    struct autoload_data_i *p = ptr;
-    xfree(p);
-}
-
-static size_t
-autoload_i_memsize(const void *ptr)
-{
-    return sizeof(struct autoload_data_i);
-}
-
-static const rb_data_type_t autoload_data_i_type = {
-    "autoload_i",
-    {autoload_i_mark, autoload_i_free, autoload_i_memsize,},
-};
-
-#define check_autoload_data(av) \
-    (struct autoload_data_i *)rb_check_typeddata((av), &autoload_data_i_type)
-
 void
 rb_autoload(VALUE mod, ID id, const char *file)
 {
     st_data_t av;
-    VALUE ad, fn;
+    VALUE fn;
     struct st_table *tbl;
-    struct autoload_data_i *ele;
 
     if (!rb_is_const_id(id)) {
 	rb_raise(rb_eNameError, "autoload must be constant name: %s", rb_id2name(id));
@@ -1524,20 +1473,13 @@
 	st_add_direct(tbl, (st_data_t)autoload, av);
 	DATA_PTR(av) = tbl = st_init_numtable();
     }
-    ad = TypedData_Wrap_Struct(0, &autoload_data_i_type, 0);
-    st_insert(tbl, (st_data_t)id, (st_data_t)ad);
-    DATA_PTR(ad) = ele = ALLOC(struct autoload_data_i);
-
     fn = rb_str_new2(file);
     FL_UNSET(fn, FL_TAINT);
     OBJ_FREEZE(fn);
-    ele->feature = fn;
-    ele->safe_level = rb_safe_level();
-    ele->thread = Qnil;
-    ele->value = Qundef;
+    st_insert(tbl, (st_data_t)id, (st_data_t)rb_node_newnode(NODE_MEMO, fn, rb_safe_level(), 0));
 }
 
-static void
+static NODE*
 autoload_delete(VALUE mod, ID id)
 {
     st_data_t val, load = 0, n = id;
@@ -1556,6 +1498,8 @@
 	    st_delete(RCLASS_IV_TBL(mod), &n, &val);
 	}
     }
+
+    return (NODE *)load;
 }
 
 static VALUE
@@ -1572,18 +1516,22 @@
     return safe;
 }
 
-static VALUE
-check_autoload_required(VALUE mod, ID id, const char **loadingpath)
+static NODE *
+autoload_node(VALUE mod, ID id, const char **loadingpath)
 {
-    VALUE file, load;
-    struct autoload_data_i *ele;
+    VALUE file;
+    struct st_table *tbl;
+    st_data_t val;
+    NODE *load;
     const char *loading;
     int safe;
 
-    if (!(load = autoload_data(mod, id)) || !(ele = check_autoload_data(load))) {
+    if (!st_lookup(RCLASS_IV_TBL(mod), autoload, &val) ||
+	!(tbl = check_autoload_table((VALUE)val)) || !st_lookup(tbl, (st_data_t)id, &val)) {
 	return 0;
     }
-    file = ele->feature;
+    load = (NODE *)val;
+    file = load->nd_lit;
     Check_Type(file, T_STRING);
     if (!RSTRING_PTR(file) || !*RSTRING_PTR(file)) {
 	rb_raise(rb_eArgError, "empty file name");
@@ -1602,7 +1550,7 @@
 }
 
 static int
-autoload_defined_p(VALUE mod, ID id)
+autoload_node_id(VALUE mod, ID id)
 {
     struct st_table *tbl = RCLASS_CONST_TBL(mod);
     st_data_t val;
@@ -1613,109 +1561,42 @@
     return 1;
 }
 
-int
-rb_autoloading_value(VALUE mod, ID id, VALUE* value)
-{
-    VALUE load;
-    struct autoload_data_i *ele;
-
-    if (!(load = autoload_data(mod, id)) || !(ele = check_autoload_data(load))) {
-	return 0;
-    }
-    if (ele->thread == rb_thread_current()) {
-	if (ele->value != Qundef) {
-    	    if (value) {
-    		*value = ele->value;
-    	    }
-	    return 1;
-	}
-    }
-    return 0;
-}
-
-struct autoload_const_set_args {
-    VALUE mod;
-    ID id;
-    VALUE value;
-};
-
-static void
-autoload_const_set(struct autoload_const_set_args* args)
-{
-    autoload_delete(args->mod, args->id);
-    rb_const_set(args->mod, args->id, args->value);
-}
-
-static VALUE
-autoload_require(struct autoload_data_i *ele)
-{
-    return rb_require_safe(ele->feature, ele->safe_level);
-}
-
 VALUE
 rb_autoload_load(VALUE mod, ID id)
 {
-    VALUE load, result;
+    VALUE file;
+    NODE *load;
     const char *loading = 0, *src;
-    struct autoload_data_i *ele;
-    int state = 0;
 
-    if (!autoload_defined_p(mod, id)) return Qfalse;
-    load = check_autoload_required(mod, id, &loading);
+    if (!autoload_node_id(mod, id)) return Qfalse;
+    load = autoload_node(mod, id, &loading);
     if (!load) return Qfalse;
     src = rb_sourcefile();
     if (src && loading && strcmp(src, loading) == 0) return Qfalse;
-
-    /* set ele->thread for a marker of autoloading thread */
-    if (!(ele = check_autoload_data(load))) {
-	return Qfalse;
-    }
-    if (ele->thread == Qnil) {
-	ele->thread = rb_thread_current();
-    }
-    /* autoload_data_i can be deleted by another thread while require */
-    RB_GC_GUARD(load);
-    result = rb_protect((VALUE(*)(VALUE))autoload_require, (VALUE)ele, &state);
-    if (ele->thread == rb_thread_current()) {
-	ele->thread = Qnil;
-    }
-    if (state) rb_jump_tag(state);
-
-    if (RTEST(result)) {
-	/* At the last, move a value defined in autoload to constant table */
-	if (ele->value != Qundef) {
-	    int safe_backup;
-	    struct autoload_const_set_args args;
-	    args.mod = mod;
-	    args.id = id;
-	    args.value = ele->value;
-	    safe_backup = rb_safe_level();
-	    rb_set_safe_level_force(ele->safe_level);
-	    rb_ensure((VALUE(*)(VALUE))autoload_const_set, (VALUE)&args, reset_safe, (VALUE)safe_backup);
-	}
-    }
-    return result;
+    file = load->nd_lit;
+    return rb_require_safe(file, (int)load->nd_nth);
 }
 
 VALUE
 rb_autoload_p(VALUE mod, ID id)
 {
-    VALUE load;
-    struct autoload_data_i *ele;
+    VALUE file;
+    NODE *load;
+    const char *loading = 0;
 
-    while (!autoload_defined_p(mod, id)) {
+    while (!autoload_node_id(mod, id)) {
 	mod = RCLASS_SUPER(mod);
 	if (!mod) return Qnil;
     }
-    load = check_autoload_required(mod, id, 0);
+    load = autoload_node(mod, id, &loading);
     if (!load) return Qnil;
-    return (ele = check_autoload_data(load)) ? ele->feature : Qnil;
+    return load && (file = load->nd_lit) ? file : Qnil;
 }
 
 static VALUE
 rb_const_get_0(VALUE klass, ID id, int exclude, int recurse, int visibility)
 {
-    VALUE value, tmp, av;
+    VALUE value, tmp;
     int mod_retry = 0;
 
     tmp = klass;
@@ -1732,7 +1613,6 @@
 	    if (value == Qundef) {
 		if (am == tmp) break;
 		am = tmp;
-		if (rb_autoloading_value(tmp, id, &av)) return av;
 		rb_autoload_load(tmp, id);
 		continue;
 	    }
@@ -1963,7 +1843,7 @@
 	    if (visibility && ce->flag == CONST_PRIVATE) {
 		return (int)Qfalse;
 	    }
-	    if (ce->value == Qundef && !check_autoload_required(tmp, id, 0) && !rb_autoloading_value(tmp, id, 0))
+	    if (ce->value == Qundef && !autoload_node(tmp, id, 0))
 		return (int)Qfalse;
 	    return (int)Qtrue;
 	}
@@ -2042,20 +1922,8 @@
 
 	if (st_lookup(RCLASS_CONST_TBL(klass), (st_data_t)id, &value)) {
 	    rb_const_entry_t *ce = (rb_const_entry_t*)value;
-	    if (ce->value == Qundef) {
-		VALUE load;
-		struct autoload_data_i *ele;
-
-		load = autoload_data(klass, id);
-		/* for autoloading thread, keep the defined value to autoloading storage */
-		if (load && (ele = check_autoload_data(load)) && (ele->thread == rb_thread_current())) {
-		    rb_vm_change_state();
-		    ele->value = val;
-		    return;
-		}
-		/* otherwise, allow to override */
+	    if (ce->value == Qundef)
 		autoload_delete(klass, id);
-	    }
 	    else {
 		visibility = ce->flag;
 		rb_warn("already initialized constant %s", rb_id2name(id));
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 33092)
+++ vm_insnhelper.c	(revision 33093)
@@ -1178,7 +1178,7 @@
 	    cref = cref->nd_next;
 
 	    if (!NIL_P(klass)) {
-		VALUE av, am = 0;
+		VALUE am = 0;
 		st_data_t data;
 	      search_continue:
 		if (RCLASS_CONST_TBL(klass) &&
@@ -1188,7 +1188,6 @@
 			if (am == klass) break;
 			am = klass;
 			if (is_defined) return 1;
-			if (rb_autoloading_value(klass, id, &av)) return av;
 			rb_autoload_load(klass, id);
 			goto search_continue;
 		    }
Index: test/ruby/test_autoload.rb
===================================================================
--- test/ruby/test_autoload.rb	(revision 33092)
+++ test/ruby/test_autoload.rb	(revision 33093)
@@ -1,6 +1,4 @@
 require 'test/unit'
-require 'tempfile'
-require 'thread'
 require_relative 'envutil'
 
 class TestAutoload < Test::Unit::TestCase
@@ -55,112 +53,4 @@
       assert_equal(tmpfile, b.autoload?(:X), bug4565)
     }
   end
-
-  def test_require_explicit
-    file = Tempfile.open(['autoload', '.rb'])
-    file.puts 'class Object; AutoloadTest = 1; end'
-    file.close
-    add_autoload(file.path)
-    begin
-      assert_nothing_raised do
-        assert(require file.path)
-        assert_equal(1, ::AutoloadTest)
-      end
-    ensure
-      remove_autoload_constant
-    end
-  end
-
-  def test_threaded_accessing_constant
-    file = Tempfile.open(['autoload', '.rb'])
-    file.puts 'sleep 0.5; class AutoloadTest; X = 1; end'
-    file.close
-    add_autoload(file.path)
-    begin
-      assert_nothing_raised do
-        t1 = Thread.new { ::AutoloadTest::X }
-        t2 = Thread.new { ::AutoloadTest::X }
-        [t1, t2].each(&:join)
-      end
-    ensure
-      remove_autoload_constant
-    end
-  end
-
-  def test_threaded_accessing_inner_constant
-    file = Tempfile.open(['autoload', '.rb'])
-    file.puts 'class AutoloadTest; sleep 0.5; X = 1; end'
-    file.close
-    add_autoload(file.path)
-    begin
-      assert_nothing_raised do
-        t1 = Thread.new { ::AutoloadTest::X }
-        t2 = Thread.new { ::AutoloadTest::X }
-        [t1, t2].each(&:join)
-      end
-    ensure
-      remove_autoload_constant
-    end
-  end
-
-  def test_nameerror_when_autoload_did_not_define_the_constant
-    file = Tempfile.open(['autoload', '.rb'])
-    file.puts ''
-    file.close
-    add_autoload(file.path)
-    begin
-      assert_raise(NameError) do
-        AutoloadTest
-      end
-    ensure
-      remove_autoload_constant
-    end
-  end
-
-  def test_override_autoload
-    file = Tempfile.open(['autoload', '.rb'])
-    file.puts ''
-    file.close
-    add_autoload(file.path)
-    begin
-      eval %q(class AutoloadTest; end)
-      assert_equal(Class, AutoloadTest.class)
-    ensure
-      remove_autoload_constant
-    end
-  end
-
-  def test_override_while_autoloading
-    file = Tempfile.open(['autoload', '.rb'])
-    file.puts 'class AutoloadTest; sleep 0.5; end'
-    file.close
-    add_autoload(file.path)
-    begin
-      # while autoloading...
-      t = Thread.new { AutoloadTest }
-      sleep 0.1
-      # override it
-      eval %q(AutoloadTest = 1)
-      t.join
-      assert_equal(1, AutoloadTest)
-    ensure
-      remove_autoload_constant
-    end
-  end
-
-  def add_autoload(path)
-    eval <<-END
-      class ::Object
-        autoload :AutoloadTest, #{path.dump}
-      end
-    END
-  end
-
-  def remove_autoload_constant
-    eval <<-END
-      class ::Object
-        remove_const(:AutoloadTest)
-      end
-    END
-  end
 end

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

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