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

* eval.c, gc.c, iseq.c, node.h, vm_insnhelper.c, vm_insnhelper.h,

vm_method.c: rename omod and overlaid modules to refinements.

* eval.c (hidden_identity_hash_new): renamed from identity_hash_new.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37117 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
shugo 2012-10-08 14:02:46 +00:00
parent 7b6e6ede60
commit e028d3d905
11 changed files with 84 additions and 71 deletions

View file

@ -1,3 +1,10 @@
Mon Oct 8 23:02:19 2012 Shugo Maeda <shugo@ruby-lang.org>
* eval.c, gc.c, iseq.c, node.h, vm_insnhelper.c, vm_insnhelper.h,
vm_method.c: rename omod and overlaid modules to refinements.
* eval.c (hidden_identity_hash_new): renamed from identity_hash_new.
Sun Oct 7 04:50:00 2012 Zachary Scott <zzak@ruby-lang.org>
* lib/abbrev.rb: Documentation examples for Abbrev.

58
eval.c
View file

@ -1041,35 +1041,35 @@ void check_class_or_module(VALUE obj)
}
static VALUE
identity_hash_new()
hidden_identity_hash_new()
{
VALUE hash = rb_hash_new();
rb_funcall(hash, rb_intern("compare_by_identity"), 0);
RBASIC(hash)->klass = 0;
RBASIC(hash)->klass = 0; /* hide from ObjectSpace */
return hash;
}
void
rb_overlay_module(NODE *cref, VALUE klass, VALUE module)
rb_using_refinement(NODE *cref, VALUE klass, VALUE module)
{
VALUE iclass, c, superclass = klass;
check_class_or_module(klass);
Check_Type(module, T_MODULE);
if (NIL_P(cref->nd_omod)) {
cref->nd_omod = identity_hash_new();
if (NIL_P(cref->nd_refinements)) {
cref->nd_refinements = hidden_identity_hash_new();
}
else {
if (cref->flags & NODE_FL_CREF_OMOD_SHARED) {
cref->nd_omod = rb_hash_dup(cref->nd_omod);
cref->nd_refinements = rb_hash_dup(cref->nd_refinements);
cref->flags &= ~NODE_FL_CREF_OMOD_SHARED;
}
if (!NIL_P(c = rb_hash_lookup(cref->nd_omod, klass))) {
if (!NIL_P(c = rb_hash_lookup(cref->nd_refinements, klass))) {
superclass = c;
while (c && TYPE(c) == T_ICLASS) {
if (RBASIC(c)->klass == module) {
/* already overlaid module */
/* already used refinement */
return;
}
c = RCLASS_SUPER(c);
@ -1086,7 +1086,7 @@ rb_overlay_module(NODE *cref, VALUE klass, VALUE module)
RCLASS_REFINED_CLASS(c) = klass;
module = RCLASS_SUPER(module);
}
rb_hash_aset(cref->nd_omod, klass, iclass);
rb_hash_aset(cref->nd_refinements, klass, iclass);
rb_clear_cache_by_class(klass);
}
@ -1095,21 +1095,21 @@ using_module_i(VALUE klass, VALUE module, VALUE arg)
{
NODE *cref = (NODE *) arg;
rb_overlay_module(cref, klass, module);
rb_using_refinement(cref, klass, module);
return ST_CONTINUE;
}
void
rb_using_module(NODE *cref, VALUE module)
{
ID id_overlaid_modules;
VALUE overlaid_modules;
ID id_refinements;
VALUE refinements;
check_class_or_module(module);
CONST_ID(id_overlaid_modules, "__overlaid_modules__");
overlaid_modules = rb_attr_get(module, id_overlaid_modules);
if (NIL_P(overlaid_modules)) return;
rb_hash_foreach(overlaid_modules, using_module_i, (VALUE) cref);
CONST_ID(id_refinements, "__refinements__");
refinements = rb_attr_get(module, id_refinements);
if (NIL_P(refinements)) return;
rb_hash_foreach(refinements, using_module_i, (VALUE) cref);
}
/*
@ -1130,7 +1130,7 @@ rb_mod_using(VALUE self, VALUE module)
CONST_ID(id_using_modules, "__using_modules__");
using_modules = rb_attr_get(self, id_using_modules);
if (NIL_P(using_modules)) {
using_modules = identity_hash_new();
using_modules = hidden_identity_hash_new();
rb_ivar_set(self, id_using_modules, using_modules);
}
rb_hash_aset(using_modules, module, Qtrue);
@ -1170,8 +1170,8 @@ refinement_module_include(int argc, VALUE *argv, VALUE module)
while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq) &&
(cref = rb_vm_get_cref(cfp->iseq, cfp->ep)) &&
!NIL_P(cref->nd_omod) &&
!NIL_P(c = rb_hash_lookup(cref->nd_omod, klass))) {
!NIL_P(cref->nd_refinements) &&
!NIL_P(c = rb_hash_lookup(cref->nd_refinements, klass))) {
while (argc--) {
VALUE mod = argv[argc];
if (rb_class_inherited_p(module, mod)) {
@ -1200,17 +1200,17 @@ rb_mod_refine(VALUE module, VALUE klass)
{
NODE *cref = rb_vm_cref();
VALUE mod;
ID id_overlaid_modules, id_refined_class;
VALUE overlaid_modules;
ID id_refinements, id_refined_class;
VALUE refinements;
check_class_or_module(klass);
CONST_ID(id_overlaid_modules, "__overlaid_modules__");
overlaid_modules = rb_attr_get(module, id_overlaid_modules);
if (NIL_P(overlaid_modules)) {
overlaid_modules = identity_hash_new();
rb_ivar_set(module, id_overlaid_modules, overlaid_modules);
CONST_ID(id_refinements, "__refinements__");
refinements = rb_attr_get(module, id_refinements);
if (NIL_P(refinements)) {
refinements = hidden_identity_hash_new();
rb_ivar_set(module, id_refinements, refinements);
}
mod = rb_hash_lookup(overlaid_modules, klass);
mod = rb_hash_lookup(refinements, klass);
if (NIL_P(mod)) {
mod = rb_module_new();
CONST_ID(id_refined_class, "__refined_class__");
@ -1219,8 +1219,8 @@ rb_mod_refine(VALUE module, VALUE klass)
refinement_module_method_added, 1);
rb_define_singleton_method(mod, "include",
refinement_module_include, -1);
rb_overlay_module(cref, klass, mod);
rb_hash_aset(overlaid_modules, klass, mod);
rb_using_refinement(cref, klass, mod);
rb_hash_aset(refinements, klass, mod);
}
rb_mod_module_eval(0, NULL, mod);
return mod;

2
gc.c
View file

@ -2733,7 +2733,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr)
break;
case NODE_CREF:
gc_mark(objspace, obj->as.node.nd_omod);
gc_mark(objspace, obj->as.node.nd_refinements);
gc_mark(objspace, (VALUE)obj->as.node.u1.node);
ptr = (VALUE)obj->as.node.u3.node;
goto again;

View file

@ -1027,7 +1027,7 @@ invokesuper
if (me && me->def->type == VM_METHOD_TYPE_ISEQ &&
me->def->body.iseq == ip) {
klass = RCLASS_SUPER(klass);
me = rb_method_entry_get_with_omod(Qnil, klass, id, &klass);
me = rb_method_entry_get_with_refinements(Qnil, klass, id, &klass);
}
CALL_METHOD(num, blockptr, flag, id, me, recv, klass);

8
iseq.c
View file

@ -202,11 +202,11 @@ set_relation(rb_iseq_t *iseq, const VALUE parent)
if (type == ISEQ_TYPE_TOP) {
/* toplevel is private */
iseq->cref_stack = NEW_CREF(rb_cObject);
iseq->cref_stack->nd_omod = Qnil;
iseq->cref_stack->nd_refinements = Qnil;
iseq->cref_stack->nd_visi = NOEX_PRIVATE;
if (th->top_wrapper) {
NODE *cref = NEW_CREF(th->top_wrapper);
cref->nd_omod = Qnil;
cref->nd_refinements = Qnil;
cref->nd_visi = NOEX_PRIVATE;
cref->nd_next = iseq->cref_stack;
iseq->cref_stack = cref;
@ -214,7 +214,7 @@ set_relation(rb_iseq_t *iseq, const VALUE parent)
}
else if (type == ISEQ_TYPE_METHOD || type == ISEQ_TYPE_CLASS) {
iseq->cref_stack = NEW_CREF(0); /* place holder */
iseq->cref_stack->nd_omod = Qnil;
iseq->cref_stack->nd_refinements = Qnil;
}
else if (RTEST(parent)) {
rb_iseq_t *piseq;
@ -1657,7 +1657,7 @@ rb_iseq_clone(VALUE iseqval, VALUE newcbase)
}
if (newcbase) {
iseq1->cref_stack = NEW_CREF(newcbase);
iseq1->cref_stack->nd_omod = iseq0->cref_stack->nd_omod;
iseq1->cref_stack->nd_refinements = iseq0->cref_stack->nd_refinements;
iseq1->cref_stack->nd_visi = iseq0->cref_stack->nd_visi;
if (iseq0->cref_stack->nd_next) {
iseq1->cref_stack->nd_next = iseq0->cref_stack->nd_next;

View file

@ -91,8 +91,8 @@ void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc,
rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_flag_t noex);
rb_method_entry_t *rb_method_entry(VALUE klass, ID id, VALUE *define_class_ptr);
rb_method_entry_t *rb_method_entry_get_with_omod(VALUE omod, VALUE klass, ID id, VALUE *define_class_ptr);
rb_method_entry_t *rb_method_entry_get_without_cache(VALUE klass, VALUE omod, ID id, VALUE *define_class_ptr);
rb_method_entry_t *rb_method_entry_get_with_refinements(VALUE refinements, VALUE klass, ID id, VALUE *define_class_ptr);
rb_method_entry_t *rb_method_entry_get_without_cache(VALUE klass, VALUE refinements, ID id, VALUE *define_class_ptr);
rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_flag_t noex);
int rb_method_entry_arity(const rb_method_entry_t *me);

2
node.h
View file

@ -281,7 +281,7 @@ typedef struct RNode {
#define nd_set_line(n,l) \
RNODE(n)->flags=((RNODE(n)->flags&~(-1<<NODE_LSHIFT))|(((l)&NODE_LMASK)<<NODE_LSHIFT))
#define nd_omod nd_reserved
#define nd_refinements nd_reserved
#define nd_head u1.node
#define nd_alen u2.argc

View file

@ -385,7 +385,8 @@ rb_search_method_entry(VALUE recv, ID mid, VALUE *defined_class_ptr)
rb_id2name(mid), type, (void *)recv, flags, klass);
}
}
return rb_method_entry_get_with_omod(Qnil, klass, mid, defined_class_ptr);
return rb_method_entry_get_with_refinements(Qnil, klass, mid,
defined_class_ptr);
}
static inline int

View file

@ -1140,7 +1140,7 @@ vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr)
{
rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(th, th->cfp);
NODE *cref = NEW_CREF(klass);
cref->nd_omod = Qnil;
cref->nd_refinements = Qnil;
cref->nd_visi = noex;
if (blockptr) {
@ -1151,7 +1151,7 @@ vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr)
}
/* TODO: why cref->nd_next is 1? */
if (cref->nd_next && cref->nd_next != (void *) 1 &&
!NIL_P(cref->nd_next->nd_omod)) {
!NIL_P(cref->nd_next->nd_refinements)) {
COPY_CREF_OMOD(cref, cref->nd_next);
}

View file

@ -171,8 +171,8 @@ enum vm_regan_acttype {
/**********************************************************/
#define COPY_CREF_OMOD(c1, c2) do { \
(c1)->nd_omod = (c2)->nd_omod; \
if (!NIL_P((c2)->nd_omod)) { \
(c1)->nd_refinements = (c2)->nd_refinements; \
if (!NIL_P((c2)->nd_refinements)) { \
(c1)->flags |= NODE_FL_CREF_OMOD_SHARED; \
(c2)->flags |= NODE_FL_CREF_OMOD_SHARED; \
} \

View file

@ -21,7 +21,7 @@ struct cache_entry { /* method hash table. */
VALUE filled_version; /* filled state version */
ID mid; /* method's id */
VALUE klass; /* receiver's class */
VALUE omod; /* overlay modules */
VALUE refinements; /* refinements */
rb_method_entry_t *me;
VALUE defined_class;
};
@ -405,16 +405,17 @@ lookup_method_table(VALUE klass, ID id, st_data_t *body)
}
static inline rb_method_entry_t*
search_method_with_omod(VALUE klass, ID id, VALUE omod, VALUE *defined_class_ptr)
search_method_with_refinements(VALUE klass, ID id, VALUE refinements,
VALUE *defined_class_ptr)
{
st_data_t body;
VALUE iclass, skipped_class = Qnil;
for (body = 0; klass; klass = RCLASS_SUPER(klass)) {
if (klass != skipped_class) {
iclass = rb_hash_lookup(omod, klass);
iclass = rb_hash_lookup(refinements, klass);
if (NIL_P(iclass) && BUILTIN_TYPE(klass) == T_ICLASS) {
iclass = rb_hash_lookup(omod, RBASIC(klass)->klass);
iclass = rb_hash_lookup(refinements, RBASIC(klass)->klass);
if (!NIL_P(iclass))
iclass = copy_refinement_iclass(iclass, klass);
}
@ -432,7 +433,7 @@ search_method_with_omod(VALUE klass, ID id, VALUE omod, VALUE *defined_class_ptr
}
static inline rb_method_entry_t*
search_method_without_omod(VALUE klass, ID id, VALUE *defined_class_ptr)
search_method_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
{
st_data_t body;
@ -446,13 +447,14 @@ search_method_without_omod(VALUE klass, ID id, VALUE *defined_class_ptr)
}
static rb_method_entry_t*
search_method(VALUE klass, ID id, VALUE omod, VALUE *defined_class_ptr)
search_method(VALUE klass, ID id, VALUE refinements, VALUE *defined_class_ptr)
{
if (NIL_P(omod)) {
return search_method_without_omod(klass, id, defined_class_ptr);
if (NIL_P(refinements)) {
return search_method_without_refinements(klass, id, defined_class_ptr);
}
else {
return search_method_with_omod(klass, id, omod, defined_class_ptr);
return search_method_with_refinements(klass, id, refinements,
defined_class_ptr);
}
}
@ -463,18 +465,19 @@ search_method(VALUE klass, ID id, VALUE omod, VALUE *defined_class_ptr)
* rb_method_entry() simply.
*/
rb_method_entry_t *
rb_method_entry_get_without_cache(VALUE klass, VALUE omod, ID id,
rb_method_entry_get_without_cache(VALUE klass, VALUE refinements, ID id,
VALUE *defined_class_ptr)
{
VALUE defined_class;
rb_method_entry_t *me = search_method(klass, id, omod, &defined_class);
rb_method_entry_t *me = search_method(klass, id, refinements,
&defined_class);
if (ruby_running) {
struct cache_entry *ent;
ent = cache + EXPR1(klass, omod, id);
ent = cache + EXPR1(klass, refinements, id);
ent->filled_version = GET_VM_STATE_VERSION();
ent->klass = klass;
ent->omod = omod;
ent->refinements = refinements;
ent->defined_class = defined_class;
if (UNDEFINED_METHOD_ENTRY_P(me)) {
@ -494,22 +497,23 @@ rb_method_entry_get_without_cache(VALUE klass, VALUE omod, ID id,
}
rb_method_entry_t *
rb_method_entry_get_with_omod(VALUE omod, VALUE klass, ID id,
rb_method_entry_get_with_refinements(VALUE refinements, VALUE klass, ID id,
VALUE *defined_class_ptr)
{
#if OPT_GLOBAL_METHOD_CACHE
struct cache_entry *ent;
ent = cache + EXPR1(klass, omod, id);
ent = cache + EXPR1(klass, refinements, id);
if (ent->filled_version == GET_VM_STATE_VERSION() &&
ent->mid == id && ent->klass == klass && ent->omod == omod) {
ent->mid == id && ent->klass == klass &&
ent->refinements == refinements) {
if (defined_class_ptr)
*defined_class_ptr = ent->defined_class;
return ent->me;
}
#endif
return rb_method_entry_get_without_cache(klass, omod, id,
return rb_method_entry_get_without_cache(klass, refinements, id,
defined_class_ptr);
}
@ -517,12 +521,13 @@ rb_method_entry_t *
rb_method_entry(VALUE klass, ID id, VALUE *defined_class_ptr)
{
NODE *cref = rb_vm_cref();
VALUE omod = Qnil;
VALUE refinements = Qnil;
if (cref && !NIL_P(cref->nd_omod)) {
omod = cref->nd_omod;
if (cref && !NIL_P(cref->nd_refinements)) {
refinements = cref->nd_refinements;
}
return rb_method_entry_get_with_omod(omod, klass, id, defined_class_ptr);
return rb_method_entry_get_with_refinements(refinements, klass, id,
defined_class_ptr);
}
static void
@ -712,8 +717,8 @@ rb_undef(VALUE klass, ID id)
{
rb_method_entry_t *me;
NODE *cref = rb_vm_cref();
VALUE omod = Qnil;
void rb_overlay_module(NODE *cref, VALUE klass, VALUE module);
VALUE refinements = Qnil;
void rb_using_refinement(NODE *cref, VALUE klass, VALUE module);
if (NIL_P(klass)) {
rb_raise(rb_eTypeError, "no class to undef method");
@ -729,10 +734,10 @@ rb_undef(VALUE klass, ID id)
rb_warn("undefining `%s' may cause serious problems", rb_id2name(id));
}
if (cref && !NIL_P(cref->nd_omod)) {
omod = cref->nd_omod;
if (cref && !NIL_P(cref->nd_refinements)) {
refinements = cref->nd_refinements;
}
me = search_method(klass, id, omod, 0);
me = search_method(klass, id, refinements, 0);
if (UNDEFINED_METHOD_ENTRY_P(me)) {
const char *s0 = " class";
@ -755,7 +760,7 @@ rb_undef(VALUE klass, ID id)
if (!RTEST(rb_class_inherited_p(klass, me->klass))) {
VALUE mod = rb_module_new();
rb_overlay_module(cref, klass, mod);
rb_using_refinement(cref, klass, mod);
klass = mod;
}
rb_add_method(klass, id, VM_METHOD_TYPE_UNDEF, 0, NOEX_PUBLIC);