diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-10-17 05:28:02 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-10-17 05:28:02 +0000 |
commit | e725a1a6abf0e1157d377b77d59869aa349638f3 (patch) | |
tree | 7a21eaae28401006147b5afb214326fe616513cb /variable.c | |
parent | 7d9c2a6733144e1f10678c59018f540f61d4c6c0 (diff) |
* variable.c (alias_fixup): added. ad hoc support for ordinary
global variable aliasing. when original entry is set, make the
alias to refer directly as possible.
* variable.c (alias_getter, alias_setter): ditto.
* variable.c (rb_alias_variable): ditto. and no need to mark alias
variables.
* variable.c (rb_gvar_defined): refer the original entry of an alias.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1790 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'variable.c')
-rw-r--r-- | variable.c | 59 |
1 files changed, 55 insertions, 4 deletions
diff --git a/variable.c b/variable.c index a6260d7ea9..71f8585def 100644 --- a/variable.c +++ b/variable.c @@ -313,6 +313,9 @@ 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; @@ -423,6 +426,44 @@ readonly_setter(val, id, var) } 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; @@ -605,6 +646,7 @@ rb_f_untrace_var(argc, argv) } return Qnil; } + VALUE rb_gvar_get(entry) struct global_entry *entry; @@ -684,6 +726,8 @@ 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; return Qtrue; } @@ -727,10 +771,17 @@ 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; + if (entry2->getter == undef_getter) { + entry1->data = entry2; + entry1->getter = alias_getter; + entry1->setter = alias_setter; + } + else if (!alias_fixup(entry1, entry2)) { + entry1->data = entry2->data; + entry1->getter = entry2->getter; + entry1->setter = entry2->setter; + } + entry1->marker = undef_marker; } static int special_generic_ivar = 0; |