Revision: 2785 http://trac.macosforge.org/projects/ruby/changeset/2785 Author: lsansonetti@apple.com Date: 2009-10-12 20:48:44 -0700 (Mon, 12 Oct 2009) Log Message: ----------- implemented protected visibility check Modified Paths: -------------- MacRuby/trunk/compiler.cpp MacRuby/trunk/dispatcher.cpp MacRuby/trunk/vm.cpp MacRuby/trunk/vm.h Modified: MacRuby/trunk/compiler.cpp =================================================================== --- MacRuby/trunk/compiler.cpp 2009-10-12 20:10:32 UTC (rev 2784) +++ MacRuby/trunk/compiler.cpp 2009-10-13 03:48:44 UTC (rev 2785) @@ -249,6 +249,7 @@ if (comparedToVal != NULL) { std::vector<Value *> params; params.push_back(compile_mcache(selEqq, false)); + params.push_back(current_self); params.push_back(subnodeVal); params.push_back(compile_sel(selEqq)); params.push_back(compile_const_pointer(NULL)); @@ -718,11 +719,12 @@ RoxorCompiler::compile_dispatch_call(std::vector<Value *> ¶ms) { if (dispatcherFunc == NULL) { - // VALUE rb_vm_dispatch(struct mcache *cache, VALUE self, SEL sel, - // void *block, unsigned char opt, int argc, ...); + // VALUE rb_vm_dispatch(struct mcache *cache, VALUE top, VALUE self, + // SEL sel, void *block, unsigned char opt, int argc, ...); std::vector<const Type *> types; types.push_back(PtrTy); types.push_back(RubyObjTy); + types.push_back(RubyObjTy); types.push_back(PtrTy); types.push_back(PtrTy); types.push_back(Int8Ty); @@ -767,6 +769,7 @@ std::vector<Value *> params; const SEL sel = mid_to_sel(mid, argc); params.push_back(compile_mcache(sel, false)); + params.push_back(current_self); params.push_back(recv); params.push_back(compile_sel(sel)); params.push_back(compile_const_pointer(NULL)); @@ -2123,7 +2126,7 @@ return NULL; } - Value *val = params[1]; // self + Value *val = params[2]; // self Function *f = bb->getParent(); @@ -2156,7 +2159,7 @@ GlobalVariable *is_redefined = GET_CORE()->redefined_op_gvar(sel, true); - Value *leftVal = params[1]; // self + Value *leftVal = params[2]; // self Value *rightVal = params.back(); VALUE leftRVal = Qundef, rightRVal = Qundef; @@ -2546,12 +2549,13 @@ std::vector<Value *> new_params; new_params.push_back(compile_mcache(new_sel, false)); new_params.push_back(params[1]); + new_params.push_back(params[2]); new_params.push_back(compile_sel(new_sel)); - new_params.push_back(params[3]); + new_params.push_back(params[4]); new_params.push_back(ConstantInt::get(Int8Ty, DISPATCH_FCALL)); new_params.push_back(ConstantInt::get(Int32Ty, argc - 1)); for (int i = 0; i < argc - 1; i++) { - new_params.push_back(params[7 + i]); + new_params.push_back(params[8 + i]); } Value *thenVal = compile_dispatch_call(new_params); thenBB = bb; @@ -3474,6 +3478,7 @@ sel = mid_to_sel(node->nd_next->nd_vid, 0); } params.push_back(compile_mcache(sel, false)); + params.push_back(current_self); params.push_back(recv); params.push_back(compile_sel(sel)); params.push_back(compile_const_pointer(NULL)); @@ -3533,6 +3538,7 @@ sel = mid_to_sel(mid, 1); params.clear(); params.push_back(compile_mcache(sel, false)); + params.push_back(current_self); params.push_back(tmp); params.push_back(compile_sel(sel)); params.push_back(compile_const_pointer(NULL)); @@ -3557,6 +3563,7 @@ } params.clear(); params.push_back(compile_mcache(sel, false)); + params.push_back(current_self); params.push_back(recv); params.push_back(compile_sel(sel)); params.push_back(compile_const_pointer(NULL)); @@ -3609,6 +3616,7 @@ std::vector<Value *> params; params.push_back(compile_mcache(selBackquote, false)); params.push_back(current_self); + params.push_back(current_self); params.push_back(compile_sel(selBackquote)); params.push_back(compile_const_pointer(NULL)); params.push_back(ConstantInt::get(Int8Ty, DISPATCH_FCALL)); @@ -4055,6 +4063,9 @@ params.push_back(compile_get_mcache(sel_val, true)); } + // Top. + params.push_back(current_self); + // Self. params.push_back(recv == NULL ? current_self : compile_node(recv)); @@ -4137,7 +4148,7 @@ ? compile_block_create(NULL) : compile_const_pointer(NULL); } - params[3] = blockVal; + params[4] = blockVal; // If we are calling a method that needs a top-level binding // object, let's create it. @@ -4397,6 +4408,7 @@ std::vector<Value *> params; params.push_back(compile_mcache(selEqTilde, false)); + params.push_back(current_self); params.push_back(reTarget); params.push_back(compile_sel(selEqTilde)); params.push_back(compile_const_pointer(NULL)); @@ -4959,6 +4971,7 @@ std::vector<Value *> params; params.push_back(compile_mcache(selEach, false)); + params.push_back(current_self); // the block must not be passed to the code // that generates the values we loop on @@ -5130,6 +5143,7 @@ std::vector<Value *> params; SEL sel = sel_registerName("at_exit"); params.push_back(compile_mcache(sel, false)); + params.push_back(current_self); params.push_back(compile_nsobject()); params.push_back(compile_sel(sel)); params.push_back(compile_block_create(NULL)); Modified: MacRuby/trunk/dispatcher.cpp =================================================================== --- MacRuby/trunk/dispatcher.cpp 2009-10-12 20:10:32 UTC (rev 2784) +++ MacRuby/trunk/dispatcher.cpp 2009-10-13 03:48:44 UTC (rev 2785) @@ -351,8 +351,9 @@ } static force_inline VALUE -__rb_vm_ruby_dispatch(VALUE self, SEL sel, rb_vm_method_node_t *node, - unsigned char opt, int argc, const VALUE *argv) +__rb_vm_ruby_dispatch(VALUE top, VALUE self, SEL sel, + rb_vm_method_node_t *node, unsigned char opt, + int argc, const VALUE *argv) { const rb_vm_arity_t &arity = node->arity; if ((argc < arity.min) || ((arity.max != -1) && (argc > arity.max))) { @@ -364,9 +365,21 @@ // Calling a private method with no explicit receiver OR an attribute // assignment to non-self, triggering #method_missing. rb_vm_block_t *b = GET_VM()->current_block(); - return method_missing(self, sel, b, argc, argv, METHOD_MISSING_PRIVATE); + return method_missing(self, sel, b, argc, argv, + METHOD_MISSING_PRIVATE); } + if ((node->flags & VM_METHOD_PROTECTED) + && top != 0 && node->klass != NULL + && !rb_obj_is_kind_of(top, (VALUE)node->klass)) { + // Calling a protected method inside a method where 'self' is not + // an instance of the class where the method was originally defined, + // triggering #method_missing. + rb_vm_block_t *b = GET_VM()->current_block(); + return method_missing(self, sel, b, argc, argv, + METHOD_MISSING_PROTECTED); + } + if ((node->flags & VM_METHOD_EMPTY) && arity.max == arity.min) { // Calling an empty method, let's just return nil! return Qnil; @@ -501,9 +514,9 @@ } static force_inline VALUE -__rb_vm_dispatch(RoxorVM *vm, struct mcache *cache, VALUE self, Class klass, - SEL sel, rb_vm_block_t *block, unsigned char opt, int argc, - const VALUE *argv) +__rb_vm_dispatch(RoxorVM *vm, struct mcache *cache, VALUE top, VALUE self, + Class klass, SEL sel, rb_vm_block_t *block, unsigned char opt, + int argc, const VALUE *argv) { assert(cache != NULL); @@ -653,7 +666,7 @@ } #if ROXOR_VM_DEBUG - printf("ruby dispatch %c[<%s %p> %s] (imp=%p, block=%p, argc=%d, cached=%s)\n", + printf("ruby dispatch %c[<%s %p> %s] (imp %p block %p argc %d opt %d cached %s)\n", class_isMetaClass(klass) ? '+' : '-', class_getName(klass), (void *)self, @@ -661,6 +674,7 @@ rcache.node->ruby_imp, block, argc, + opt, cached ? "true" : "false"); #endif @@ -701,7 +715,7 @@ MACRUBY_METHOD_ENTRY(class_name, method_name, file, line); } - VALUE v = __rb_vm_ruby_dispatch(self, sel, rcache.node, opt, + VALUE v = __rb_vm_ruby_dispatch(top, self, sel, rcache.node, opt, argc, argv); // DTrace probe: method__return @@ -959,8 +973,8 @@ extern "C" VALUE -rb_vm_dispatch(struct mcache *cache, VALUE self, SEL sel, rb_vm_block_t *block, - unsigned char opt, int argc, ...) +rb_vm_dispatch(struct mcache *cache, VALUE top, VALUE self, SEL sel, + rb_vm_block_t *block, unsigned char opt, int argc, ...) { VALUE base_argv[MAX_DISPATCH_ARGS]; VALUE *argv = base_argv; @@ -987,8 +1001,8 @@ RoxorVM *vm = GET_VM(); - VALUE retval = __rb_vm_dispatch(vm, cache, self, NULL, sel, block, opt, - argc, argv); + VALUE retval = __rb_vm_dispatch(vm, cache, top, self, NULL, sel, block, + opt, argc, argv); vm->pop_current_binding(); @@ -1010,8 +1024,8 @@ cache = GET_CORE()->method_cache_get(sel, false); } - return __rb_vm_dispatch(GET_VM(), cache, self, NULL, sel, NULL, opt, argc, - argv); + return __rb_vm_dispatch(GET_VM(), cache, 0, self, NULL, sel, NULL, opt, + argc, argv); } extern "C" @@ -1019,8 +1033,8 @@ rb_vm_call_with_cache(void *cache, VALUE self, SEL sel, int argc, const VALUE *argv) { - return __rb_vm_dispatch(GET_VM(), (struct mcache *)cache, self, NULL, sel, - NULL, DISPATCH_FCALL, argc, argv); + return __rb_vm_dispatch(GET_VM(), (struct mcache *)cache, 0, self, NULL, + sel, NULL, DISPATCH_FCALL, argc, argv); } extern "C" @@ -1028,7 +1042,7 @@ rb_vm_call_with_cache2(void *cache, rb_vm_block_t *block, VALUE self, VALUE klass, SEL sel, int argc, const VALUE *argv) { - return __rb_vm_dispatch(GET_VM(), (struct mcache *)cache, self, + return __rb_vm_dispatch(GET_VM(), (struct mcache *)cache, 0, self, (Class)klass, sel, block, DISPATCH_FCALL, argc, argv); } @@ -1066,7 +1080,7 @@ case T_COMPLEX: return rb_nu_plus(self, other); } - return rb_vm_dispatch(cache, self, selPLUS, NULL, 0, 1, other); + return rb_vm_dispatch(cache, 0, self, selPLUS, NULL, 0, 1, other); } extern "C" @@ -1084,7 +1098,7 @@ case T_COMPLEX: return rb_nu_minus(self, other); } - return rb_vm_dispatch(cache, self, selMINUS, NULL, 0, 1, other); + return rb_vm_dispatch(cache, 0, self, selMINUS, NULL, 0, 1, other); } extern "C" @@ -1101,7 +1115,7 @@ case T_COMPLEX: return rb_nu_div(self, other); } - return rb_vm_dispatch(cache, self, selDIV, NULL, 0, 1, other); + return rb_vm_dispatch(cache, 0, self, selDIV, NULL, 0, 1, other); } extern "C" @@ -1119,7 +1133,7 @@ case T_COMPLEX: return rb_nu_mul(self, other); } - return rb_vm_dispatch(cache, self, selMULT, NULL, 0, 1, other); + return rb_vm_dispatch(cache, 0, self, selMULT, NULL, 0, 1, other); } extern "C" @@ -1130,7 +1144,7 @@ case T_BIGNUM: return FIX2INT(rb_big_cmp(self, other)) < 0 ? Qtrue : Qfalse; } - return rb_vm_dispatch(cache, self, selLT, NULL, 0, 1, other); + return rb_vm_dispatch(cache, 0, self, selLT, NULL, 0, 1, other); } extern "C" @@ -1141,7 +1155,7 @@ case T_BIGNUM: return FIX2INT(rb_big_cmp(self, other)) <= 0 ? Qtrue : Qfalse; } - return rb_vm_dispatch(cache, self, selLE, NULL, 0, 1, other); + return rb_vm_dispatch(cache, 0, self, selLE, NULL, 0, 1, other); } extern "C" @@ -1152,7 +1166,7 @@ case T_BIGNUM: return FIX2INT(rb_big_cmp(self, other)) > 0 ? Qtrue : Qfalse; } - return rb_vm_dispatch(cache, self, selGT, NULL, 0, 1, other); + return rb_vm_dispatch(cache, 0, self, selGT, NULL, 0, 1, other); } extern "C" @@ -1163,7 +1177,7 @@ case T_BIGNUM: return FIX2INT(rb_big_cmp(self, other)) >= 0 ? Qtrue : Qfalse; } - return rb_vm_dispatch(cache, self, selGE, NULL, 0, 1, other); + return rb_vm_dispatch(cache, 0, self, selGE, NULL, 0, 1, other); } extern "C" @@ -1193,7 +1207,7 @@ case T_BIGNUM: return rb_big_eq(self, other); } - return rb_vm_dispatch(cache, self, selEq, NULL, 0, 1, other); + return rb_vm_dispatch(cache, 0, self, selEq, NULL, 0, 1, other); } extern "C" @@ -1201,7 +1215,7 @@ rb_vm_fast_neq(struct mcache *cache, VALUE self, VALUE other) { // TODO - return rb_vm_dispatch(cache, self, selNeq, NULL, 0, 1, other); + return rb_vm_dispatch(cache, 0, self, selNeq, NULL, 0, 1, other); } extern "C" @@ -1227,7 +1241,7 @@ return rb_obj_is_kind_of(other, self); default: - return rb_vm_dispatch(cache, self, selEqq, NULL, 0, 1, other); + return rb_vm_dispatch(cache, 0, self, selEqq, NULL, 0, 1, other); } } @@ -1252,7 +1266,8 @@ else { for (int i = 0; i < count; ++i) { VALUE o = RARRAY_AT(ary, i); - if (RTEST(rb_vm_dispatch(cache, o, selEqq, NULL, 0, 1, comparedTo))) { + if (RTEST(rb_vm_dispatch(cache, 0, o, selEqq, NULL, 0, 1, + comparedTo))) { return Qtrue; } } @@ -1276,7 +1291,7 @@ return obj; } } - return __rb_vm_dispatch(GET_VM(), cache, obj, NULL, selLTLT, NULL, 0, 1, + return __rb_vm_dispatch(GET_VM(), cache, 0, obj, NULL, selLTLT, NULL, 0, 1, &other); } @@ -1292,7 +1307,7 @@ } return rb_ary_aref(obj, 0, 1, &other); } - return __rb_vm_dispatch(GET_VM(), cache, obj, NULL, selAREF, NULL, 0, 1, + return __rb_vm_dispatch(GET_VM(), cache, 0, obj, NULL, selAREF, NULL, 0, 1, &other); } @@ -1309,7 +1324,7 @@ } } VALUE args[2] = { other1, other2 }; - return __rb_vm_dispatch(GET_VM(), cache, obj, NULL, selASET, NULL, 0, 2, + return __rb_vm_dispatch(GET_VM(), cache, 0, obj, NULL, selASET, NULL, 0, 2, args); } Modified: MacRuby/trunk/vm.cpp =================================================================== --- MacRuby/trunk/vm.cpp 2009-10-12 20:10:32 UTC (rev 2784) +++ MacRuby/trunk/vm.cpp 2009-10-13 03:48:44 UTC (rev 2785) @@ -720,6 +720,7 @@ assert(m != NULL); assert(method_getImplementation(m) == imp); rb_vm_method_node_t *real_node = method_node_get(m, true); + real_node->klass = klass; real_node->objc_imp = imp; real_node->ruby_imp = ruby_imp; real_node->arity = arity; @@ -738,6 +739,7 @@ node = iter2->second; assert(node->objc_imp == imp); } + node->klass = klass; node->arity = arity; node->flags = flags; node->sel = sel; @@ -810,6 +812,7 @@ assert(m != NULL); assert(method_getImplementation(m) == imp); node = method_node_get(m, true); + node->klass = (Class)mod; node->objc_imp = imp; node->ruby_imp = ruby_imp; node->arity = arity; @@ -3236,6 +3239,7 @@ // For symbolication. rb_vm_method_node_t *mnode = GET_CORE()->method_node_get(imp, true); + mnode->klass = 0; mnode->arity = rb_vm_arity(2); mnode->sel = sel_registerName("<main>"); mnode->objc_imp = mnode->ruby_imp = imp; Modified: MacRuby/trunk/vm.h =================================================================== --- MacRuby/trunk/vm.h 2009-10-12 20:10:32 UTC (rev 2784) +++ MacRuby/trunk/vm.h 2009-10-13 03:48:44 UTC (rev 2785) @@ -93,6 +93,7 @@ typedef struct rb_vm_method_node { rb_vm_arity_t arity; + Class klass; SEL sel; IMP objc_imp; IMP ruby_imp;
participants (1)
-
source_changes@macosforge.org