[#14614] 大小文字を無視した比較で ' 帰 ' == ' 蟻 ' ? — "K.Umakoshi" <pegacorn@...>

こんにちは。

18 messages 2001/09/02
[#14615] Re: 大小文字を無視した比較で ' 帰 ' == ' 蟻 ' ? — matz@... (Yukihiro Matsumoto) 2001/09/02

まつもと ゆきひろです

[#14662] How to abondon saved uid privilege — nobu.nakada@...

なかだです。

60 messages 2001/09/05
[#14663] Re: How to abondon saved uid privilege — nagai@... 2001/09/05

永井@知能.九工大です.

[#14672] Re: How to abondon saved uid privilege — nobu.nakada@... 2001/09/05

なかだです。

[#14677] Re: How to abondon saved uid privilege — nagai@... 2001/09/05

永井@知能.九工大です.

[#14678] Re: How to abondon saved uid privilege — matz@... (Yukihiro Matsumoto) 2001/09/05

まつもと ゆきひろです

[#14680] Re: How to abondon saved uid privilege — nagai@... 2001/09/05

永井@知能.九工大です.

[#14685] Re: How to abondon saved uid privilege — Takahiro Kambe <taca@...> 2001/09/05

In message <20010905184635H.nagai@ai.kyutech.ac.jp>

[#14687] Re: How to abondon saved uid privilege — "Akinori MUSHA" <knu@...> 2001/09/05

 ちょっと脱線します。 :)

[#14688] Re: How to abondon saved uid privilege — Takahiro Kambe <taca@...> 2001/09/05

In message <86ofopevkv.wl@archon.local.idaemons.org>

[#14691] Re: How to abondon saved uid privilege — matz@... (Yukihiro Matsumoto) 2001/09/05

まつもと ゆきひろです

[#14693] Re: How to abondon saved uid privilege — Takahiro Kambe <taca@...> 2001/09/05

In message <999700675.662743.18683.nullmailer@ev.netlab.jp>

[#14703] Re: How to abondon saved uid privilege — nagai@... 2001/09/06

永井@知能.九工大です.

[#14707] Re: How to abondon saved uid privilege — Takahiro Kambe <taca@...> 2001/09/06

In message <20010906111828R.nagai@ai.kyutech.ac.jp>

[#14708] Re: How to abondon saved uid privilege — nagai@... 2001/09/06

永井@知能.九工大です.

[#14709] Re: How to abondon saved uid privilege — Takahiro Kambe <taca@...> 2001/09/06

In message <20010906132656Z.nagai@ai.kyutech.ac.jp>

[#14728] Re: How to abondon saved uid privilege — nagai@... 2001/09/06

永井@知能.九工大です.

[#14729] Re: How to abondon saved uid privilege — Takahiro Kambe <taca@...> 2001/09/06

In message <20010906174440D.nagai@ai.kyutech.ac.jp>

[#14732] Re: How to abondon saved uid privilege — nagai@... 2001/09/06

永井@知能.九工大です.

[#14774] Re: How to abondon saved uid privilege — nagai@... 2001/09/12

永井@知能.九工大です.

[#14841] Re: How to abondon saved uid privilege — nagai@... 2001/10/02

永井@知能.九工大です.

[#15026] setuid and seteuid — nagai@... 2001/11/02

永井@知能.九工大です.

[#15030] Re: setuid and seteuid — Tanaka Akira <akr@...17n.org> 2001/11/03

In article <20011102175733K.nagai@ai.kyutech.ac.jp>,

[#15032] Re: setuid and seteuid — nagai@... 2001/11/03

永井@知能.九工大です.

[#14743] [BUG] $_ on thread switching — nobu.nakada@...

なかだです。

24 messages 2001/09/07
[#14746] Re: [BUG] $_ on thread switching — nobu.nakada@... 2001/09/07

なかだです。

[#14747] Re: [BUG] $_ on thread switching — matz@... (Yukihiro Matsumoto) 2001/09/07

まつもと ゆきひろです

[#14748] Re: [BUG] $_ on thread switching — nobu.nakada@... 2001/09/08

なかだです。

[#14750] Re: [BUG] $_ on thread switching — matz@... (Yukihiro Matsumoto) 2001/09/08

まつもと ゆきひろです

[#14752] Re: [BUG] $_ on thread switching — nobu.nakada@... 2001/09/08

なかだです。

[#14753] Re: [BUG] $_ on thread switching — matz@... (Yukihiro Matsumoto) 2001/09/08

まつもと ゆきひろです

[#14755] Re: [BUG] $_ on thread switching — nobu.nakada@... 2001/09/08

なかだです。

[ruby-dev:14805] Re: [BUG] $_ on thread switching

From: nobu.nakada@...
Date: 2001-09-19 10:19:53 UTC
List: ruby-dev #14805
なかだです。

At Tue, 18 Sep 2001 12:43:10 +0900,
matz@ruby-lang.org (Yukihiro Matsumoto) wrote:
> | dyna_varsもたしか一度ちょっと考えたような気がしますが、なんで
> |やめたんだったか覚えてません。やっぱりそっちの方がいいでしょう
> |か。そうした場合、FLIPの方は適当にIDを割り振るようにするとか?
> 
> たぶん。FLIPについては現在cntを使っている部分を「適当なID」
> にすることで対応するのではないかと思います。

 だいたいうまく行くような感じ。相変わらずでかいパッチですいま
せんが。

 IDの種類にID_INTERNALというのを追加してます。それとrb_svar()
というのはローカル変数のインデックスから変数への参照を返す関数。
たぶん、SCOPE_SHAREDは不要になると思うんですがどうでしょう。

 想定してるテストケースはこんなの。

class TestScope < Rubicon::TestCase

  # $_ is a local variable but not be shared by threads.
  def wakeup(t)
    t.run
  end
  private :wakeup

  def test_scope_uscore_string
    sub = proc {|x| "#{x, $_ = $_, x; x}"}
    assert_equal("", sub.call("first"))
    assert_equal("first", sub.call("second"))
  end

  def test_threadscope_uscore
    # shares local scope
    t = Thread.start do
      $_ = "sub"
      loop do
	Thread.stop
	assert_equal("sub", $_)
      end
    end

    begin
      $_ = "main"
      # another thread may change?
      t.run
      assert_equal("main", $_)
    ensure
      t.kill
      t.join
    end
  end

  def test_threadscope_uscore_sub
    t = Thread.start do
      $_ = "sub"
      loop do
	Thread.stop
	assert_equal("sub", $_)
      end
    end

    begin
      $_ = "main"
      # another thread waked in function may change?
      wakeup(t)
      assert_equal("main", $_)
    ensure
      t.kill
      t.join
    end
  end

  def test_threadscope_uscore_main
    t = Thread.new(Thread.current) do |main|
      $_ = "sub"
      loop do
	assert_equal("sub", $_)
	Thread.stop
	wakeup(main)
      end
    end

    begin
      $_ = "main"
      # another thread waked in function may change while this thread
      # is absent this scope?
      wakeup(t)
      assert_equal("main", $_)
    ensure
      t.kill
      t.join
    end
  end

  def test_threadscope_uscore_proc
    sub = nil
    Thread.start do
      $_ = "sub"
      sub = proc {$_}
    end.join

    $_ = "main"
    assert_equal("main", $_)
    assert_equal("sub", sub.call)
    assert_equal("main", $_)
  end

  def test_threadscope_local
    sub = nil
    Thread.start do
      var = "sub"
      sub = proc {var}
    end.join

    var = "main"
    assert_equal("main", var)
    assert_equal("sub", sub.call)
    assert_equal("main", var)
  end

  def test_threadscope_shared
    sub = nil
    var = "main"
    Thread.start do
      sub = proc {
	tmp, var = var, "sub"
	tmp
      }
    end.join

    assert_equal("main", sub.call)
    assert_equal("sub", var)
  end
end

class TestFlip < Rubicon::TestCase
  def test_flip2_while
    result = []
    i = 0
    while i < 5
      result << (i if (i==1)..(i==3))
      i += 1
    end
    assert_equal([nil,1,2,3,nil], result)
  end

  def test_flip2_for
    result = []
    for i in (0...5)
      result << (i if (i==1)..(i==3))
    end
    assert_equal([nil,1,2,3,nil], result)
  end

  def test_flip2_proc
    sub = proc {|x| x if (x==1)..(x==3)}
    assert_nil(sub.call(0))
    assert_equal(1, sub.call(1))
    assert_equal(2, sub.call(2))
    assert_equal(3, sub.call(3))
    assert_nil(sub.call(3))
    assert_nil(sub.call(4))
  end

  def test_flip2_eval
    sub = eval("proc {|x| x if (x==1)..(x==3)}")
    assert_nil(sub.call(0))
    assert_equal(1, sub.call(1))
    assert_equal(2, sub.call(2))
    assert_equal(3, sub.call(3))
    assert_nil(sub.call(3))
    assert_nil(sub.call(4))
  end

  def test_flip2_string
    sub = proc {|x| "#{x if (x==1)..(x==3)}"}
    assert_equal("", sub.call(0))
    assert_equal("1", sub.call(1))
    assert_equal("2", sub.call(2))
    assert_equal("3", sub.call(3))
    assert_equal("", sub.call(3))
    assert_equal("", sub.call(4))
  end

  def test_flip2_thread
    sub = []
    2.times do |i|
      Thread.start do
	sub << proc do |x|
	  x if (x==1)...(x==3)
	end
      end.join
    end
    assert_nil(sub[0].call(0))
    assert_equal(1, sub[0].call(1))
    assert_nil(sub[1].call(2))
    assert_nil(sub[1].call(3))
    assert_equal(1, sub[1].call(1))
    assert_equal(3, sub[0].call(3))
    assert_nil(sub[0].call(3))
    assert_equal(3, sub[1].call(3))
  end
end


Index: eval.c
===================================================================
RCS file: /cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.204
diff -u -2 -p -r1.204 eval.c
--- eval.c	2001/09/19 06:54:10	1.204
+++ eval.c	2001/09/19 10:10:29
@@ -722,4 +722,22 @@ dvar_asgn_curr(id, value)
 }
 
+VALUE *
+rb_svar(cnt)
+    int cnt;
+{
+    struct RVarmap *vars = ruby_dyna_vars;
+    ID id;
+
+    if (!ruby_scope->local_tbl) return NULL;
+    if (cnt >= ruby_scope->local_tbl[0]) return NULL;
+    id = ruby_scope->local_tbl[cnt+1];
+    while (vars) {
+	if (vars->id == id) return &vars->val;
+	vars = vars->next;
+    }
+    if (ruby_scope->local_vars == 0) return NULL;
+    return &ruby_scope->local_vars[cnt];
+}
+
 struct iter {
     int iter;
@@ -2537,38 +2555,39 @@ rb_eval(self, n)
 
       case NODE_FLIP2:		/* like AWK */
-	if (ruby_scope->local_vars == 0) {
-	    rb_bug("unexpected local variable");
-	}
-	if (!RTEST(ruby_scope->local_vars[node->nd_cnt])) {
-	    if (RTEST(rb_eval(self, node->nd_beg))) {
-		ruby_scope->local_vars[node->nd_cnt] = 
-		    RTEST(rb_eval(self, node->nd_end))?Qfalse:Qtrue;
-		result = Qtrue;
+	{
+	    VALUE *flip = rb_svar(node->nd_cnt);
+	    if (!flip) rb_bug("unexpected local variable");
+	    if (!RTEST(*flip)) {
+		if (RTEST(rb_eval(self, node->nd_beg))) {
+		    *flip = RTEST(rb_eval(self, node->nd_end))?Qfalse:Qtrue;
+		    result = Qtrue;
+		}
+		else {
+		    result = Qfalse;
+		}
 	    }
 	    else {
-		result = Qfalse;
-	    }
-	}
-	else {
-	    if (RTEST(rb_eval(self, node->nd_end))) {
-		ruby_scope->local_vars[node->nd_cnt] = Qfalse;
+		if (RTEST(rb_eval(self, node->nd_end))) {
+		    *flip = Qfalse;
+		}
+		result = Qtrue;
 	    }
-	    result = Qtrue;
 	}
 	break;
 
       case NODE_FLIP3:		/* like SED */
-	if (ruby_scope->local_vars == 0) {
-	    rb_bug("unexpected local variable");
-	}
-	if (!RTEST(ruby_scope->local_vars[node->nd_cnt])) {
-	    result = RTEST(rb_eval(self, node->nd_beg)) ? Qtrue : Qfalse;
-	    ruby_scope->local_vars[node->nd_cnt] = result;
-	}
-	else {
-	    if (RTEST(rb_eval(self, node->nd_end))) {
-		ruby_scope->local_vars[node->nd_cnt] = Qfalse;
+	{
+	    VALUE *flip = rb_svar(node->nd_cnt);
+	    if (!flip) rb_bug("unexpected local variable");
+	    if (!RTEST(*flip)) {
+		result = RTEST(rb_eval(self, node->nd_beg)) ? Qtrue : Qfalse;
+		*flip = result;
+	    }
+	    else {
+		if (RTEST(rb_eval(self, node->nd_end))) {
+		    *flip = Qfalse;
+		}
+		result = Qtrue;
 	    }
-	    result = Qtrue;
 	}
 	break;
@@ -5853,6 +5872,8 @@ rb_f_local_variables()
 	n = *tbl++;
 	for (i=2; i<n; i++) {	/* skip first 2 ($_ and $~) */
-	    if (tbl[i] == 0) continue;  /* skip flip states */
-	    rb_ary_push(ary, rb_str_new2(rb_id2name(tbl[i])));
+	    ID id = tbl[i];
+	    if (id == 0 || rb_is_internal_id(id)) /* skip flip states */
+		continue;
+	    rb_ary_push(ary, rb_str_new2(rb_id2name(id)));
 	}
     }
@@ -6415,4 +6436,5 @@ proc_invoke(proc, args, pcall)
     volatile int safe = ruby_safe_level;
     volatile VALUE old_wrapper = ruby_wrapper;
+    struct RVarmap * volatile old_dvars = ruby_dyna_vars;
 
     if (rb_block_given_p() && ruby_frame->last_func) {
@@ -6426,4 +6448,5 @@ proc_invoke(proc, args, pcall)
 
     ruby_wrapper = data->wrapper;
+    ruby_dyna_vars = data->dyna_vars;
     /* PUSH BLOCK from data */
     old_block = ruby_block;
@@ -6451,4 +6474,5 @@ proc_invoke(proc, args, pcall)
     ruby_block = old_block;
     ruby_wrapper = old_wrapper;
+    ruby_dyna_vars = old_dvars;
     ruby_safe_level = safe;
 
@@ -8255,6 +8279,4 @@ int rb_thread_tick = THREAD_TICK;
 #endif
 
-#define SCOPE_SHARED  FL_USER1
-
 #if defined(HAVE_SETITIMER)
 static int thread_init = 0;
@@ -8322,5 +8344,4 @@ rb_thread_start_0(fn, arg, th_arg)
     }
     scope_dup(ruby_scope);
-    FL_SET(ruby_scope, SCOPE_SHARED);
 
     if (!th->next) {
@@ -8398,10 +8419,4 @@ rb_thread_create(fn, arg)
 }
 
-int
-rb_thread_scope_shared_p()
-{
-    return FL_TEST(ruby_scope, SCOPE_SHARED);
-}
-
 static VALUE
 rb_thread_yield(arg, th) 
@@ -8409,5 +8424,21 @@ rb_thread_yield(arg, th) 
     rb_thread_t th;
 {
+    ID *tbl;
+
     scope_dup(ruby_block->scope);
+
+    tbl = ruby_scope->local_tbl;
+    if (tbl) {
+	int n = *tbl++;
+	for (tbl += 2, n -= 2; n > 0; --n) { /* skip first 2 ($_ and $~) */
+	    ID id = *tbl++;
+	    if (id != 0 && rb_is_internal_id(id))  /* push flip states */
+		rb_dvar_push(id, Qfalse);
+	}
+    }
+    rb_dvar_push('_', Qnil);
+    rb_dvar_push('~', Qnil);
+    ruby_block->dyna_vars = ruby_dyna_vars;
+
     return rb_yield_0(mvalue_to_svalue(arg), 0, 0, Qtrue);
 }
Index: intern.h
===================================================================
RCS file: /cvs/ruby/src/ruby/intern.h,v
retrieving revision 1.64
diff -u -2 -p -r1.64 intern.h
--- intern.h	2001/09/05 22:31:07	1.64
+++ intern.h	2001/09/19 10:11:03
@@ -134,4 +134,5 @@ VALUE rb_dvar_ref _((ID));
 void rb_dvar_asgn _((ID, VALUE));
 void rb_dvar_push _((ID, VALUE));
+VALUE *rb_svar _((int));
 VALUE rb_eval_cmd _((VALUE, VALUE));
 int rb_respond_to _((VALUE, ID));
@@ -171,5 +172,4 @@ VALUE rb_thread_wakeup _((VALUE));
 VALUE rb_thread_run _((VALUE));
 VALUE rb_thread_create _((VALUE (*)(ANYARGS), void*));
-int rb_thread_scope_shared_p _((void));
 void rb_thread_interrupt _((void));
 void rb_thread_trap_eval _((VALUE, int));
Index: parse.y
===================================================================
RCS file: /cvs/ruby/src/ruby/parse.y,v
retrieving revision 1.120
diff -u -2 -p -r1.120 parse.y
--- parse.y	2001/09/19 06:54:10	1.120
+++ parse.y	2001/09/19 09:55:44
@@ -24,4 +24,5 @@
 #define ID_SCOPE_SHIFT 3
 #define ID_SCOPE_MASK 0x07
+#define ID_INTERNAL 0x00
 #define ID_LOCAL    0x01
 #define ID_INSTANCE 0x02
@@ -33,4 +34,5 @@
 
 #define is_notop_id(id) ((id)>LAST_TOKEN)
+#define is_internal_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_INTERNAL)
 #define is_local_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL)
 #define is_global_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_GLOBAL)
@@ -139,4 +141,5 @@ static int  local_cnt();
 static int  local_id();
 static ID  *local_tbl();
+static ID   internal_id();
 
 static struct RVarmap *dyna_push();
@@ -4627,5 +4630,5 @@ cond0(node)
 	if (type == NODE_DOT2) nd_set_type(node,NODE_FLIP2);
 	else if (type == NODE_DOT3) nd_set_type(node, NODE_FLIP3);
-	node->nd_cnt = local_append(0);
+	node->nd_cnt = local_append(internal_id());
 	warning_unless_e_option("range literal in condition");
 	break;
@@ -5004,9 +5007,16 @@ Init_sym()
 }
 
+static ID last_id = LAST_TOKEN;
+
+static ID
+internal_id()
+{
+    return ID_INTERNAL | (++last_id << ID_SCOPE_SHIFT);
+}
+
 ID
 rb_intern(name)
     const char *name;
 {
-    static ID last_id = LAST_TOKEN;
     const char *m = name;
     ID id;
@@ -5163,4 +5173,12 @@ rb_is_instance_id(id)
 }
 
+int
+rb_is_internal_id(id)
+    ID id;
+{
+    if (is_internal_id(id)) return Qtrue;
+    return Qfalse;
+}
+
 static void
 special_local_set(c, val)
@@ -5176,9 +5194,12 @@ special_local_set(c, val)
 }
 
+VALUE *rb_svar _((int cnt));
+
 VALUE
 rb_backref_get()
 {
-    if (ruby_scope->local_vars) {
-	return ruby_scope->local_vars[1];
+    VALUE *var = rb_svar(1);
+    if (var) {
+	return *var;
     }
     return Qnil;
@@ -5189,6 +5210,7 @@ rb_backref_set(val)
     VALUE val;
 {
-    if (ruby_scope->local_vars) {
-	ruby_scope->local_vars[1] = val;
+    VALUE *var = rb_svar(1);
+    if (var) {
+	*var = val;
     }
     else {
@@ -5200,6 +5222,7 @@ VALUE
 rb_lastline_get()
 {
-    if (ruby_scope->local_vars) {
-	return ruby_scope->local_vars[0];
+    VALUE *var = rb_svar(0);
+    if (var) {
+	return *var;
     }
     return Qnil;
@@ -5210,6 +5233,7 @@ rb_lastline_set(val)
     VALUE val;
 {
-    if (ruby_scope->local_vars) {
-	ruby_scope->local_vars[0] = val;
+    VALUE *var = rb_svar(0);
+    if (var) {
+	*var = val;
     }
     else {
Index: re.c
===================================================================
RCS file: /cvs/ruby/src/ruby/re.c,v
retrieving revision 1.45
diff -u -2 -p -r1.45 re.c
--- re.c	2001/09/05 06:54:53	1.45
+++ re.c	2001/09/19 10:10:10
@@ -646,10 +646,5 @@ rb_reg_search(re, str, pos, reverse)
     }
 
-    if (rb_thread_scope_shared_p()) {
-	match = Qnil;
-    }
-    else {
-	match = rb_backref_get();
-    }
+    match = rb_backref_get();
     if (NIL_P(match) || FL_TEST(match, MATCH_BUSY)) {
 	match = match_alloc();


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread