[#14922] alias $gvar — Koji Arai <JCA02266@...>

新井です。

19 messages 2001/10/14

[#15006] Re: eval.c (rb_stack_check): prohibit recursive raising error — WATANABE Hirofumi <eban@...>

わたなべです。

13 messages 2001/10/26
[#15008] Re: eval.c (rb_stack_check): prohibit recursive raising error — Shugo Maeda <shugo@...> 2001/10/26

前田です。

[ruby-dev:14967] Re: alias var and trace_var

From: nobu.nakada@...
Date: 2001-10-19 13:57:13 UTC
List: ruby-dev #14967
なかだです。

At Fri, 19 Oct 2001 16:51:07 +0900,
K.Kosako <kosako@sofnec.co.jp> wrote:
> >  半分くらいそう意図してたんですが(半分は何も考えてなかった)、
> > 共通にトレースしたほうがいいでしょうか。
> 
> 個人的にはトレースに漏れがあり得るということに
> 違和感があります。

 一応やってみました。global_entryを分割してますが、おそらくこ
れが一番確実だと思います。1.48のようにgetter/setterをいじくる方
向では、これ以上は無理があるでしょう。

 最新の1.48からではなく、その前の1.47からの差分です。


Index: variable.c
===================================================================
RCS file: /cvs/ruby/src/ruby/variable.c,v
retrieving revision 1.47
diff -u -2 -p -r1.47 variable.c
--- variable.c	2001/10/03 07:19:11	1.47
+++ variable.c	2001/10/19 13:54:11
@@ -292,6 +292,5 @@ struct trace_var {
 };
 
-struct global_entry {
-    ID id;
+struct global_variable {
     void *data;
     VALUE (*getter)();
@@ -302,4 +301,9 @@ struct global_entry {
 };
 
+struct global_entry {
+    struct global_variable *var;
+    ID id;
+};
+
 static VALUE undef_getter();
 static void  undef_setter();
@@ -321,14 +325,17 @@ rb_global_entry(id)
 
     if (!st_lookup(rb_global_tbl, id, &entry)) {
+	struct global_variable *var;
 	entry = ALLOC(struct global_entry);
 	st_add_direct(rb_global_tbl, id, entry);
+	var = ALLOC(struct global_variable);
 	entry->id = id;
-	entry->data = 0;
-	entry->getter = undef_getter;
-	entry->setter = undef_setter;
-	entry->marker = undef_marker;
+	entry->var = var;
+	var->data = 0;
+	var->getter = undef_getter;
+	var->setter = undef_setter;
+	var->marker = undef_marker;
 
-	entry->block_trace = 0;
-	entry->trace = 0;
+	var->block_trace = 0;
+	var->trace = 0;
     }
     return entry;
@@ -346,15 +353,15 @@ undef_getter(id)
 
 static void
-undef_setter(val, id, data, entry)
+undef_setter(val, id, data, var)
     VALUE val;
     ID id;
     void *data;
-    struct global_entry *entry;
+    struct global_variable *var;
 {
-    entry->getter = val_getter;
-    entry->setter = val_setter;
-    entry->marker = val_marker;
+    var->getter = val_getter;
+    var->setter = val_setter;
+    var->marker = val_marker;
 
-    entry->data = (void*)val;
+    var->data = (void*)val;
 }
 
@@ -373,11 +380,11 @@ val_getter(id, val)
 
 static void
-val_setter(val, id, data, entry)
+val_setter(val, id, data, var)
     VALUE val;
     ID id;
     void *data;
-    struct global_entry *entry;
+    struct global_variable *var;
 {
-    entry->data = (void*)val;
+    var->data = (void*)val;
 }
 
@@ -429,7 +436,8 @@ mark_global_entry(key, entry)
 {
     struct trace_var *trace;
+    struct global_variable *var = entry->var;
 
-    (*entry->marker)(entry->data);
-    trace = entry->trace;
+    (*var->marker)(var->data);
+    trace = var->trace;
     while (trace) {
 	if (trace->data) rb_gc_mark_maybe(trace->data);
@@ -468,12 +476,12 @@ rb_define_hooked_variable(name, var, get
     void  (*setter)();
 {
-    struct global_entry *entry;
+    struct global_variable *gvar;
     ID id = global_id(name);
 
-    entry = rb_global_entry(id);
-    entry->data = (void*)var;
-    entry->getter = getter?getter:var_getter;
-    entry->setter = setter?setter:var_setter;
-    entry->marker = var_marker;
+    gvar = rb_global_entry(id)->var;
+    gvar->data = (void*)var;
+    gvar->getter = getter?getter:var_getter;
+    gvar->setter = setter?setter:var_setter;
+    gvar->marker = var_marker;
 }
 
@@ -533,9 +541,9 @@ rb_f_trace_var(argc, argv)
     }
     trace = ALLOC(struct trace_var);
-    trace->next = entry->trace;
+    trace->next = entry->var->trace;
     trace->func = rb_trace_eval;
     trace->data = cmd;
     trace->removed = 0;
-    entry->trace = trace;
+    entry->var->trace = trace;
 
     return Qnil;
@@ -543,8 +551,8 @@ rb_f_trace_var(argc, argv)
 
 static void
-remove_trace(entry)
-    struct global_entry *entry;
+remove_trace(var)
+    struct global_variable *var;
 {
-    struct trace_var *trace = entry->trace;
+    struct trace_var *trace = var->trace;
     struct trace_var t;
     struct trace_var *next;
@@ -557,8 +565,10 @@ remove_trace(entry)
 	    trace->next = next->next;
 	    free(next);
+	}
+	else {
+	    trace = next;
 	}
-	trace = next;
     }
-    entry->trace = t.next;
+    var->trace = t.next;
 }
 
@@ -579,5 +589,5 @@ rb_f_untrace_var(argc, argv)
     }
 
-    trace = entry->trace;
+    trace = entry->var->trace;
     if (NIL_P(cmd)) {
 	VALUE ary = rb_ary_new();
@@ -589,7 +599,6 @@ rb_f_untrace_var(argc, argv)
 	    trace = next;
 	}
-	entry->trace = 0;
 
-	if (!entry->block_trace) remove_trace(entry);
+	if (!entry->var->block_trace) remove_trace(entry->var);
 	return ary;
     }
@@ -598,5 +607,5 @@ rb_f_untrace_var(argc, argv)
 	    if (trace->data == cmd) {
 		trace->removed = 1;
-		if (!entry->block_trace) remove_trace(entry);
+		if (!entry->var->block_trace) remove_trace(entry->var);
 		return rb_ary_new3(1, cmd);
 	    }
@@ -606,9 +615,11 @@ rb_f_untrace_var(argc, argv)
     return Qnil;
 }
+
 VALUE
 rb_gvar_get(entry)
     struct global_entry *entry;
 {
-    return (*entry->getter)(entry->id, entry->data, entry);
+    struct global_variable *var = entry->var;
+    return (*var->getter)(entry->id, var->data, var);
 }
 
@@ -633,8 +644,8 @@ trace_ev(data)
 static VALUE
 trace_en(entry)
-    struct global_entry *entry;
+    struct global_variable *var;
 {
-    entry->block_trace = 0;
-    remove_trace(entry);
+    var->block_trace = 0;
+    remove_trace(var);
     return Qnil;		/* not reached */
 }
@@ -646,14 +657,15 @@ rb_gvar_set(entry, val)
 {
     struct trace_data trace;
+    struct global_variable *var = entry->var;
 
     if (rb_safe_level() >= 4)
 	rb_raise(rb_eSecurityError, "Insecure: can't change global variable value");
-    (*entry->setter)(val, entry->id, entry->data, entry);
+    (*var->setter)(val, entry->id, var->data, var);
 
-    if (entry->trace && !entry->block_trace) {
-	entry->block_trace = 1;
-	trace.trace = entry->trace;
+    if (var->trace && !var->block_trace) {
+	var->block_trace = 1;
+	trace.trace = var->trace;
 	trace.val = val;
-	rb_ensure(trace_ev, (VALUE)&trace, trace_en, (VALUE)entry);
+	rb_ensure(trace_ev, (VALUE)&trace, trace_en, (VALUE)var);
     }
     return val;
@@ -685,5 +697,5 @@ rb_gvar_defined(entry)
     struct global_entry *entry;
 {
-    if (entry->getter == undef_getter) return Qfalse;
+    if (entry->var->getter == undef_getter) return Qfalse;
     return Qtrue;
 }
@@ -727,9 +739,5 @@ rb_alias_variable(name1, name2)
     entry1 = rb_global_entry(name1);
     entry2 = rb_global_entry(name2);
-
-    entry1->data   = entry2->data;
-    entry1->getter = entry2->getter;
-    entry1->setter = entry2->setter;
-    entry1->marker = entry2->marker;
+    entry1->var = entry2->var;
 }
 


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

In This Thread