1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* variable.c (rb_global_entry): reconstruct global variable

aliasing (sharing global_entry->var with other global_entry).

* variable.c (undef_getter): ditto.

* variable.c (undef_setter): ditto.

* variable.c (val_setter): ditto.

* variable.c (mark_global_entry): ditto.

* variable.c (rb_define_hooked_variable): ditto.

* variable.c (rb_f_trace_var): ditto.

* variable.c (remove_trace): ditto.

* variable.c (rb_f_untrace_var): ditto.

* variable.c (rb_gvar_get): ditto.

* variable.c (trace_en): ditto.

* variable.c (rb_gvar_set): ditto.

* variable.c (rb_gvar_defined): ditto.

* variable.c (rb_alias_variable): ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1797 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2001-10-22 16:20:14 +00:00
parent c4712cbc50
commit 96baf2c092
2 changed files with 113 additions and 100 deletions

View file

@ -1,3 +1,34 @@
Tue Oct 23 01:15:43 2001 K.Kosako <kosako@sofnec.co.jp>
* variable.c (rb_global_entry): reconstruct global variable
aliasing (sharing global_entry->var with other global_entry).
* variable.c (undef_getter): ditto.
* variable.c (undef_setter): ditto.
* variable.c (val_setter): ditto.
* variable.c (mark_global_entry): ditto.
* variable.c (rb_define_hooked_variable): ditto.
* variable.c (rb_f_trace_var): ditto.
* variable.c (remove_trace): ditto.
* variable.c (rb_f_untrace_var): ditto.
* variable.c (rb_gvar_get): ditto.
* variable.c (trace_en): ditto.
* variable.c (rb_gvar_set): ditto.
* variable.c (rb_gvar_defined): ditto.
* variable.c (rb_alias_variable): ditto.
Mon Oct 22 15:21:55 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* class.c (rb_mod_clone): should not copy class name, since clone
@ -51,7 +82,6 @@ Tue Oct 16 13:18:47 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* object.c (rb_mod_initialize): optional block with
Module.new. [new] (from 2001-10-10)
>>>>>>> 1.591
Tue Oct 16 00:07:06 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* parse.y (yylex): disallow alpha-numeric and mbchar for

View file

@ -291,8 +291,8 @@ struct trace_var {
struct trace_var *next;
};
struct global_entry {
ID id;
struct global_variable {
int counter;
void *data;
VALUE (*getter)();
void (*setter)();
@ -301,6 +301,11 @@ struct global_entry {
struct trace_var *trace;
};
struct global_entry {
struct global_variable *var;
ID id;
};
static VALUE undef_getter();
static void undef_setter();
static void undef_marker();
@ -313,9 +318,6 @@ static VALUE var_getter();
static void var_setter();
static void var_marker();
static VALUE alias_getter();
static void alias_setter();
struct global_entry*
rb_global_entry(id)
ID id;
@ -323,16 +325,20 @@ rb_global_entry(id)
struct global_entry *entry;
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->counter = 1;
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;
}
@ -348,17 +354,17 @@ 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;
}
static void
@ -375,13 +381,13 @@ 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;
}
static void
@ -425,53 +431,16 @@ readonly_setter(val, id, var)
rb_name_error(id, "can't set variable %s", rb_id2name(id));
}
static int
alias_fixup(entry1, entry2)
struct global_entry *entry1, *entry2;
{
if (entry2->getter != val_getter) return 0;
entry1->data = &entry2->data;
entry1->getter = var_getter;
if (entry2->setter == val_setter)
entry1->setter = var_setter;
else
entry1->setter = entry2->setter;
return 1;
}
static VALUE
alias_getter(id, data, entry)
ID id;
void *data;
struct global_entry *entry;
{
struct global_entry *entry2 = data;
VALUE val = (*entry2->getter)(id, entry2->data, entry2);
alias_fixup(entry, entry2);
return val;
}
static void
alias_setter(val, id, data, entry)
VALUE val;
ID id;
void *data;
struct global_entry *entry;
{
struct global_entry *entry2 = data;
(*entry2->setter)(val, id, entry2->data, entry2);
alias_fixup(entry, entry2);
}
static int
mark_global_entry(key, entry)
ID key;
struct global_entry *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);
trace = trace->next;
@ -508,14 +477,14 @@ rb_define_hooked_variable(name, var, getter, setter)
VALUE (*getter)();
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;
}
void
@ -573,20 +542,20 @@ rb_f_trace_var(argc, argv)
rb_name_error(id, "undefined global variable %s", rb_id2name(id));
}
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;
}
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;
@ -602,7 +571,7 @@ remove_trace(entry)
trace = next;
}
}
entry->trace = t.next;
var->trace = t.next;
}
VALUE
@ -621,7 +590,7 @@ rb_f_untrace_var(argc, argv)
rb_name_error(id, "undefined global variable %s", rb_id2name(id));
}
trace = entry->trace;
trace = entry->var->trace;
if (NIL_P(cmd)) {
VALUE ary = rb_ary_new();
@ -632,14 +601,14 @@ rb_f_untrace_var(argc, argv)
trace = next;
}
if (!entry->block_trace) remove_trace(entry);
if (!entry->var->block_trace) remove_trace(entry->var);
return ary;
}
else {
while (trace) {
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);
}
trace = trace->next;
@ -652,7 +621,8 @@ 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);
}
struct trace_data {
@ -674,11 +644,11 @@ trace_ev(data)
}
static VALUE
trace_en(entry)
struct global_entry *entry;
trace_en(var)
struct global_variable *var;
{
entry->block_trace = 0;
remove_trace(entry);
var->block_trace = 0;
remove_trace(var);
return Qnil; /* not reached */
}
@ -688,16 +658,17 @@ rb_gvar_set(entry, val)
VALUE 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;
}
@ -727,9 +698,7 @@ VALUE
rb_gvar_defined(entry)
struct global_entry *entry;
{
if (entry->getter == alias_getter && !alias_fixup(entry, entry->data))
entry = entry->data;
if (entry->getter == undef_getter) return Qfalse;
if (entry->var->getter == undef_getter) return Qfalse;
return Qtrue;
}
@ -769,20 +738,34 @@ rb_alias_variable(name1, name2)
if (rb_safe_level() >= 4)
rb_raise(rb_eSecurityError, "Insecure: can't alias global variable");
entry1 = rb_global_entry(name1);
entry2 = rb_global_entry(name2);
if (entry2->getter == undef_getter) {
entry1->data = entry2;
entry1->getter = alias_getter;
entry1->setter = alias_setter;
entry2 = rb_global_entry(name2);
if (!st_lookup(rb_global_tbl, name1, &entry1)) {
entry1 = ALLOC(struct global_entry);
st_add_direct(rb_global_tbl, name1, entry1);
entry1->id = name1;
}
else if (!alias_fixup(entry1, entry2)) {
entry1->data = entry2->data;
entry1->getter = entry2->getter;
entry1->setter = entry2->setter;
else if (entry1->var != entry2->var) {
struct global_variable *var = entry1->var;
if (var->block_trace) {
rb_raise(rb_eRuntimeError, "can't alias in tracer");
}
var->counter--;
if (var->counter == 0) {
struct trace_var *trace = var->trace;
while (trace) {
struct trace_var *next = trace->next;
free(trace);
trace = next;
}
free(var);
}
}
entry1->marker = undef_marker;
else {
return;
}
entry2->var->counter++;
entry1->var = entry2->var;
}
static int special_generic_ivar = 0;