public CheckedSites(String x) { respond_to_X = new RespondToCallSite(x); site = new FunctionalCachingCallSite(x); methodName = x; } }
@Override protected IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, ThreadContext context, IRubyObject self, IRubyObject arg) { CacheEntry entry = selfType.searchWithCache(methodName); DynamicMethod method = entry.method; if (methodMissing(method, caller)) { return callMethodMissing(context, self, method, arg); } // alternate logic to cache the result of respond_to if it's the standard one // FIXME: 1.9's respond_to_missing breaks this, so we have to bail out if (!context.runtime.is1_9() && entry.method.equals(context.runtime.getRespondToMethod())) { String name = arg.asJavaString(); RespondToTuple tuple = recacheRespondsTo(entry, name, selfType, true, context); respondToTuple = tuple; return tuple.respondsTo; } // normal logic if it's not the builtin respond_to? method cache = entry; return method.call(context, self, selfType, methodName, arg); }
@JRubyMethod(name = "respond_to?", frame = true) public IRubyObject respond_to(ThreadContext context, IRubyObject name, IRubyObject includePrivate) { if (name.asJavaString().equals("path")) { return sites(context).reader_respond_to.call(context, this, this.realIo, name, includePrivate); } return Helpers.invokeSuper(context, this, name, Block.NULL_BLOCK); }
/** * Check if the method has a custom respond_to? and call it if so with the method ID we're hoping to call. * * MRI: check_funcall_respond_to */ private static boolean checkFuncallRespondTo(ThreadContext context, RubyClass klass, IRubyObject recv, RespondToCallSite respondToSite) { final Ruby runtime = context.runtime; DynamicMethod me = respondToSite.retrieveCache(klass).method; // NOTE: isBuiltin here would be NOEX_BASIC in MRI, a flag only added to respond_to?, method_missing, and // respond_to_missing? Same effect, I believe. if (me != null && !me.isUndefined() && !me.isBuiltin()) { int arityValue = me.getArity().getValue(); if (arityValue > 2) throw runtime.newArgumentError("respond_to? must accept 1 or 2 arguments (requires " + arityValue + ")"); boolean result; if (arityValue == 1) { result = respondToSite.respondsTo(context, recv, recv); } else { result = respondToSite.respondsTo(context, recv, recv, true); } return result; } return true; }
/** * Return true if the given object responds to "begin" and "end" methods. * * @param context current context * @param obj possibly range-like object * @param respond_to_begin respond_to? site for begin * @param respond_to_end respond_to? site for end * @return */ public static boolean isRangeLike(ThreadContext context, IRubyObject obj, RespondToCallSite respond_to_begin, RespondToCallSite respond_to_end) { return respond_to_begin.respondsTo(context, obj, obj) && respond_to_end.respondsTo(context, obj, obj); }
public boolean respondsTo(ThreadContext context, IRubyObject caller, IRubyObject self) { RubyClass klass = getMetaClass(self); RespondToTuple tuple = respondToTuple; if (tuple.cacheOk(klass)) { String strName = respondToName; if (strName.equals(tuple.name) && tuple.checkVisibility) return tuple.respondsToBoolean; } // go through normal call logic, which will hit overridden cacheAndCall return super.call(context, caller, self, getRespondToNameSym(context)).isTrue(); }
private static RespondToTuple recacheRespondsTo(CacheEntry respondToMethod, String newString, RubyClass klass, boolean checkVisibility, ThreadContext context) { Ruby runtime = context.runtime; CacheEntry respondToLookupResult = klass.searchWithCache(newString); IRubyObject respondsTo; if (!respondToLookupResult.method.isUndefined() && !respondToLookupResult.method.isNotImplemented()) { respondsTo = checkVisibilityAndCache(respondToLookupResult, checkVisibility, runtime); } else { respondsTo = runtime.getFalse(); } return new RespondToTuple(newString, checkVisibility, respondToMethod, respondToLookupResult, respondsTo); }
/** * Return true if the given object responds to "begin" and "end" methods. * * @param context current context * @param obj possibly range-like object * @param respond_to_begin respond_to? site for begin * @param respond_to_end respond_to? site for end * @return */ public static boolean isRangeLike(ThreadContext context, IRubyObject obj, RespondToCallSite respond_to_begin, RespondToCallSite respond_to_end) { return respond_to_begin.respondsTo(context, obj, obj) && respond_to_end.respondsTo(context, obj, obj); }
/** * Check if the method has a custom respond_to? and call it if so with the method ID we're hoping to call. * * MRI: check_funcall_respond_to */ private static boolean checkFuncallRespondTo(ThreadContext context, RubyClass klass, IRubyObject recv, RespondToCallSite respondToSite) { final Ruby runtime = context.runtime; DynamicMethod me = respondToSite.retrieveCache(klass).method; // NOTE: isBuiltin here would be NOEX_BASIC in MRI, a flag only added to respond_to?, method_missing, and // respond_to_missing? Same effect, I believe. if (me != null && !me.isUndefined() && !me.isBuiltin()) { int arityValue = me.getArity().getValue(); if (arityValue > 2) throw runtime.newArgumentError("respond_to? must accept 1 or 2 arguments (requires " + arityValue + ")"); boolean result; if (arityValue == 1) { result = respondToSite.respondsTo(context, recv, recv); } else { result = respondToSite.respondsTo(context, recv, recv, true); } return result; } return true; }
public boolean respondsTo(ThreadContext context, IRubyObject caller, IRubyObject self) { RubyClass klass = getMetaClass(self); RespondToTuple tuple = respondToTuple; if (tuple.cacheOk(klass)) { String strName = respondToName; if (strName.equals(tuple.name) && tuple.checkVisibility) return tuple.respondsToBoolean; } // go through normal call logic, which will hit overridden cacheAndCall return super.call(context, caller, self, getRespondToNameSym(context)).isTrue(); }
private static RespondToTuple recacheRespondsTo(CacheEntry respondToMethod, String newString, RubyClass klass, boolean checkVisibility, ThreadContext context) { Ruby runtime = context.runtime; CacheEntry respondToLookupResult = klass.searchWithCache(newString); IRubyObject respondsTo; if (!respondToLookupResult.method.isUndefined() && !respondToLookupResult.method.isNotImplemented()) { respondsTo = checkVisibilityAndCache(respondToLookupResult, checkVisibility, runtime); } else { respondsTo = runtime.getFalse(); } return new RespondToTuple(newString, checkVisibility, respondToMethod, respondToLookupResult, respondsTo); }
@Override protected IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, ThreadContext context, IRubyObject self, IRubyObject arg0, IRubyObject arg1) { CacheEntry entry = selfType.searchWithCache(methodName); DynamicMethod method = entry.method; if (methodMissing(method, caller)) { return callMethodMissing(context, self, method, arg0, arg1); } // alternate logic to cache the result of respond_to if it's the standard one // FIXME: 1.9's respond_to_missing breaks this, so we have to bail out // FIXME: 1.9's respond_to_missing breaks this, so we have to bail out if (!context.runtime.is1_9() && entry.method.equals(context.runtime.getRespondToMethod())) { String name = arg0.asJavaString(); RespondToTuple tuple = recacheRespondsTo(entry, name, selfType, !arg1.isTrue(), context); respondToTuple = tuple; return tuple.respondsTo; } // normal logic if it's not the builtin respond_to? method cache = entry; return method.call(context, self, selfType, methodName, arg0, arg1); }
private static boolean discreteObject(ThreadContext context, IRubyObject obj) { if (obj instanceof RubyTime) return false; return sites(context).respond_to_succ.respondsTo(context, obj, obj, false); }
public CheckedSites(String x) { respond_to_X = new RespondToCallSite(x); site = new FunctionalCachingCallSite(x); methodName = x; } }
@JRubyMethod(name = "respond_to?", frame = true) public IRubyObject respond_to(ThreadContext context, IRubyObject name) { if (name.asJavaString().equals("path")) { return sites(context).reader_respond_to.call(context, this, this.realIo, name); } return Helpers.invokeSuper(context, this, name, Block.NULL_BLOCK); }
public boolean respondsTo(ThreadContext context, IRubyObject caller, IRubyObject self, boolean includePrivate) { RubyClass klass = getMetaClass(self); RespondToTuple tuple = respondToTuple; if (tuple.cacheOk(klass)) { String strName = respondToName; if (strName.equals(tuple.name) && !includePrivate == tuple.checkVisibility) return tuple.respondsToBoolean; } // go through normal call logic, which will hit overridden cacheAndCall return super.call(context, caller, self, getRespondToNameSym(context), context.runtime.newBoolean(includePrivate)).isTrue(); }
@Override protected IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, ThreadContext context, IRubyObject self, IRubyObject arg) { CacheEntry entry = selfType.searchWithCache(methodName); DynamicMethod method = entry.method; if (methodMissing(method, caller)) { return callMethodMissing(context, self, selfType, method, arg); } // alternate logic to cache the result of respond_to if it's the standard one if (entry.method.isBuiltin()) { String name = arg.asJavaString(); RespondToTuple tuple = recacheRespondsTo(entry, name, selfType, true, context); // only cache if it does respond_to? OR there's no custom respond_to_missing? logic if (tuple.respondsTo.isTrue() || selfType.searchWithCache("respond_to_missing?").method == context.runtime.getRespondToMissingMethod()) { respondToTuple = tuple; return tuple.respondsTo; } } // normal logic if it's not the builtin respond_to? method cache = entry; return method.call(context, self, selfType, methodName, arg); }
private static boolean discreteObject(ThreadContext context, IRubyObject obj) { if (obj instanceof RubyTime) return false; return sites(context).respond_to_succ.respondsTo(context, obj, obj, false); }
public static CallSite getCallSite(String name) { // fast and safe respond_to? call site logic if (name.equals("respond_to?")) return new RespondToCallSite(); // only use fast ops if we're not tracing if (RubyInstanceConfig.FASTOPS_COMPILE_ENABLED && !(RubyInstanceConfig.FULL_TRACE_ENABLED)) return getFastFixnumOpsCallSite(name); return new NormalCachingCallSite(name); }
@JRubyMethod(name = "respond_to?", frame = true) public IRubyObject respond_to(ThreadContext context, IRubyObject name) { if (name.asJavaString().equals("path")) { return sites(context).reader_respond_to.call(context, this, this.realIo, name); } return Helpers.invokeSuper(context, this, name, Block.NULL_BLOCK); }