Navigation Menu

Skip to content

Commit

Permalink
when changing the visibility of a method that is included in classes,…
Browse files Browse the repository at this point in the history
… make sure the new flags are recursively applied

git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@2942 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information
lrz committed Nov 3, 2009
1 parent 277a9ee commit 846054c
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 22 deletions.
13 changes: 8 additions & 5 deletions vm.cpp
Expand Up @@ -2188,7 +2188,7 @@ rb_vm_define_attr(Class klass, const char *name, bool read, bool write)


static rb_vm_method_node_t * static rb_vm_method_node_t *
__rb_vm_define_method(Class klass, SEL sel, IMP objc_imp, IMP ruby_imp, __rb_vm_define_method(Class klass, SEL sel, IMP objc_imp, IMP ruby_imp,
const rb_vm_arity_t &arity, int flags, bool direct) const rb_vm_arity_t &arity, int flags, bool direct)
{ {
assert(klass != NULL); assert(klass != NULL);


Expand Down Expand Up @@ -2251,13 +2251,16 @@ rb_vm_define_method(Class klass, SEL sel, IMP imp, NODE *node, bool direct)
extern "C" extern "C"
rb_vm_method_node_t * rb_vm_method_node_t *
rb_vm_define_method2(Class klass, SEL sel, rb_vm_method_node_t *node, rb_vm_define_method2(Class klass, SEL sel, rb_vm_method_node_t *node,
bool direct) long flags, bool direct)
{ {
assert(node != NULL); assert(node != NULL);


long flags = node->flags;
flags &= ~VM_METHOD_PRIVATE; if (flags == -1) {
flags &= ~VM_METHOD_PROTECTED; flags = node->flags;
flags &= ~VM_METHOD_PRIVATE;
flags &= ~VM_METHOD_PROTECTED;
}


return __rb_vm_define_method(klass, sel, node->objc_imp, node->ruby_imp, return __rb_vm_define_method(klass, sel, node->objc_imp, node->ruby_imp,
node->arity, flags, direct); node->arity, flags, direct);
Expand Down
2 changes: 1 addition & 1 deletion vm.h
Expand Up @@ -279,7 +279,7 @@ bool rb_vm_is_ruby_method(Method m);
rb_vm_method_node_t *rb_vm_define_method(Class klass, SEL sel, IMP imp, rb_vm_method_node_t *rb_vm_define_method(Class klass, SEL sel, IMP imp,
NODE *node, bool direct); NODE *node, bool direct);
rb_vm_method_node_t *rb_vm_define_method2(Class klass, SEL sel, rb_vm_method_node_t *rb_vm_define_method2(Class klass, SEL sel,
rb_vm_method_node_t *node, bool direct); rb_vm_method_node_t *node, long flags, bool direct);
void rb_vm_define_method3(Class klass, SEL sel, rb_vm_block_t *node); void rb_vm_define_method3(Class klass, SEL sel, rb_vm_block_t *node);
bool rb_vm_resolve_method(Class klass, SEL sel); bool rb_vm_resolve_method(Class klass, SEL sel);
void *rb_vm_undefined_imp(void *rcv, SEL sel); void *rb_vm_undefined_imp(void *rcv, SEL sel);
Expand Down
35 changes: 19 additions & 16 deletions vm_method.c
Expand Up @@ -224,29 +224,32 @@ rb_export_method(VALUE klass, ID name, ID noex)
sel_getName(sel)); sel_getName(sel));
} }


long flags = 0;
switch (noex) {
case NOEX_PRIVATE:
flags |= VM_METHOD_PRIVATE;
break;

case NOEX_PROTECTED:
flags |= VM_METHOD_PROTECTED;
break;

default:
break;
}

VALUE sklass = RCLASS_SUPER(klass); VALUE sklass = RCLASS_SUPER(klass);
if (sklass != 0) { if (sklass != 0) {
Method m = class_getInstanceMethod((Class)sklass, sel); Method m = class_getInstanceMethod((Class)sklass, sel);
if (m != NULL && method_getImplementation(m) == node->objc_imp) { if (m != NULL && method_getImplementation(m) == node->objc_imp) {
// The method actually exists on a superclass, we need to duplicate // The method actually exists on a superclass, we need to duplicate
// it to the current class then change its visibility. // it to the current class.
node = rb_vm_define_method2((Class)klass, sel, node, false); rb_vm_define_method2((Class)klass, sel, node, flags, false);
return;
} }
} }


switch (noex) { node->flags |= flags;
case NOEX_PUBLIC:
node->flags |= 0;
break;

case NOEX_PRIVATE:
node->flags |= VM_METHOD_PRIVATE;
break;

case NOEX_PROTECTED:
node->flags |= VM_METHOD_PROTECTED;
break;
}
} }


int int
Expand Down Expand Up @@ -749,7 +752,7 @@ rb_mod_modfunc(VALUE module, SEL sel, int argc, VALUE *argv)
rb_bug("undefined method `%s'; can't happen", rb_id2name(id)); rb_bug("undefined method `%s'; can't happen", rb_id2name(id));
} }


rb_vm_define_method2(*(Class *)module, sel, node, false); rb_vm_define_method2(*(Class *)module, sel, node, -1, false);
} }


return module; return module;
Expand Down

0 comments on commit 846054c

Please sign in to comment.