From c4c8573c098981d53f1e4e31094a90806a0e892e Mon Sep 17 00:00:00 2001 From: headius Date: Sun, 10 Aug 2008 02:45:03 +0000 Subject: [PATCH] * Eliminate visibility checking for almost all fcall and vcall paths. * Outline some method_missing logic * Start adding some specific-arity paths for method_missing; still too much boxing, but the code isn't in normal call paths now. git-svn-id: http://svn.codehaus.org/jruby/trunk/jruby@7417 961051c9-f516-0410-bf72-c9f7e237a7b7 --- src/org/jruby/RubyClass.java | 139 +++++++++++++++++---- src/org/jruby/RubyKernel.java | 2 +- src/org/jruby/RubyObject.java | 8 +- src/org/jruby/RubySignal.java | 2 +- src/org/jruby/ast/AttrAssignNode.java | 28 ++++- src/org/jruby/ast/executable/RubiniusMachine.java | 2 +- src/org/jruby/java/proxies/JavaProxy.java | 2 +- src/org/jruby/javasupport/JavaClass.java | 2 +- src/org/jruby/javasupport/JavaProxyMethods.java | 2 +- .../javasupport/proxy/JavaProxyConstructor.java | 2 +- src/org/jruby/javasupport/util/RuntimeHelpers.java | 84 ++++++++----- 11 files changed, 199 insertions(+), 74 deletions(-) diff --git a/src/org/jruby/RubyClass.java b/src/org/jruby/RubyClass.java index c9c7abf93..83cfed106 100644 --- a/src/org/jruby/RubyClass.java +++ b/src/org/jruby/RubyClass.java @@ -296,11 +296,23 @@ public class RubyClass extends RubyModule { return invoke(context, self, name, args, callType, block); } + public boolean notVisibleAndNotMethodMissing(DynamicMethod method, String name, IRubyObject caller, CallType callType) { + return !method.isCallableFrom(caller, callType) && !name.equals("method_missing"); + } + public IRubyObject invoke(ThreadContext context, IRubyObject self, String name, CallType callType, Block block) { DynamicMethod method = searchMethod(name); - if (method.isUndefined() || (!name.equals("method_missing") && !method.isCallableFrom(context.getFrameSelf(), callType))) { - return RuntimeHelpers.callMethodMissing(context, self, method, name, IRubyObject.NULL_ARRAY, context.getFrameSelf(), callType, block); + if (method.isUndefined() || notVisibleAndNotMethodMissing(method, name, context.getFrameSelf(), callType)) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, context.getFrameSelf(), callType, block); + } + return method.call(context, self, this, name, block); + } + + public IRubyObject finvoke(ThreadContext context, IRubyObject self, String name, Block block) { + DynamicMethod method = searchMethod(name); + if (method.isUndefined()) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, context.getFrameSelf(), CallType.FUNCTIONAL, block); } return method.call(context, self, this, name, block); } @@ -309,18 +321,36 @@ public class RubyClass extends RubyModule { IRubyObject[] args, CallType callType, Block block) { assert args != null; DynamicMethod method = searchMethod(name); - if (method.isUndefined() || (!name.equals("method_missing") && !method.isCallableFrom(context.getFrameSelf(), callType))) { + if (method.isUndefined() || notVisibleAndNotMethodMissing(method, name, context.getFrameSelf(), callType)) { return RuntimeHelpers.callMethodMissing(context, self, method, name, args, context.getFrameSelf(), callType, block); } return method.call(context, self, this, name, args, block); } + public IRubyObject finvoke(ThreadContext context, IRubyObject self, String name, + IRubyObject[] args, Block block) { + assert args != null; + DynamicMethod method = searchMethod(name); + if (method.isUndefined()) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, args, context.getFrameSelf(), CallType.FUNCTIONAL, block); + } + return method.call(context, self, this, name, args, block); + } + public IRubyObject invoke(ThreadContext context, IRubyObject self, String name, IRubyObject arg, CallType callType, Block block) { DynamicMethod method = searchMethod(name); - if (method.isUndefined() || (!name.equals("method_missing") && !method.isCallableFrom(context.getFrameSelf(), callType))) { - return RuntimeHelpers.callMethodMissing(context, self, method, name, - new IRubyObject[] {arg}, context.getFrameSelf(), callType, block); + if (method.isUndefined() || notVisibleAndNotMethodMissing(method, name, context.getFrameSelf(), callType)) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, arg, context.getFrameSelf(), callType, block); + } + return method.call(context, self, this, name, arg, block); + } + + public IRubyObject finvoke(ThreadContext context, IRubyObject self, String name, + IRubyObject arg, Block block) { + DynamicMethod method = searchMethod(name); + if (method.isUndefined()) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, arg, context.getFrameSelf(), CallType.FUNCTIONAL, block); } return method.call(context, self, this, name, arg, block); } @@ -328,9 +358,17 @@ public class RubyClass extends RubyModule { public IRubyObject invoke(ThreadContext context, IRubyObject self, String name, IRubyObject arg0, IRubyObject arg1, CallType callType, Block block) { DynamicMethod method = searchMethod(name); - if (method.isUndefined() || (!name.equals("method_missing") && !method.isCallableFrom(context.getFrameSelf(), callType))) { - return RuntimeHelpers.callMethodMissing(context, self, method, name, - new IRubyObject[] {arg0, arg1}, context.getFrameSelf(), callType, block); + if (method.isUndefined() || notVisibleAndNotMethodMissing(method, name, context.getFrameSelf(), callType)) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, arg0, arg1, context.getFrameSelf(), callType, block); + } + return method.call(context, self, this, name, arg0, arg1, block); + } + + public IRubyObject finvoke(ThreadContext context, IRubyObject self, String name, + IRubyObject arg0, IRubyObject arg1, Block block) { + DynamicMethod method = searchMethod(name); + if (method.isUndefined()) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, arg0, arg1, context.getFrameSelf(), CallType.FUNCTIONAL, block); } return method.call(context, self, this, name, arg0, arg1, block); } @@ -338,9 +376,17 @@ public class RubyClass extends RubyModule { public IRubyObject invoke(ThreadContext context, IRubyObject self, String name, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2, CallType callType, Block block) { DynamicMethod method = searchMethod(name); - if (method.isUndefined() || (!name.equals("method_missing") && !method.isCallableFrom(context.getFrameSelf(), callType))) { - return RuntimeHelpers.callMethodMissing(context, self, method, name, - new IRubyObject[] {arg0, arg1, arg2}, context.getFrameSelf(), callType, block); + if (method.isUndefined() || notVisibleAndNotMethodMissing(method, name, context.getFrameSelf(), callType)) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, arg0, arg1, arg2, context.getFrameSelf(), callType, block); + } + return method.call(context, self, this, name, arg0, arg1, arg2, block); + } + + public IRubyObject finvoke(ThreadContext context, IRubyObject self, String name, + IRubyObject arg0, IRubyObject arg1, IRubyObject arg2, Block block) { + DynamicMethod method = searchMethod(name); + if (method.isUndefined()) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, arg0, arg1, arg2, context.getFrameSelf(), CallType.FUNCTIONAL, block); } return method.call(context, self, this, name, arg0, arg1, arg2, block); } @@ -348,8 +394,16 @@ public class RubyClass extends RubyModule { public IRubyObject invoke(ThreadContext context, IRubyObject self, String name, CallType callType) { DynamicMethod method = searchMethod(name); - if (method.isUndefined() || (!name.equals("method_missing") && !method.isCallableFrom(context.getFrameSelf(), callType))) { - return RuntimeHelpers.callMethodMissing(context, self, method, name, IRubyObject.NULL_ARRAY, context.getFrameSelf(), callType, Block.NULL_BLOCK); + if (method.isUndefined() || notVisibleAndNotMethodMissing(method, name, context.getFrameSelf(), callType)) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, context.getFrameSelf(), callType, Block.NULL_BLOCK); + } + return method.call(context, self, this, name); + } + + public IRubyObject finvoke(ThreadContext context, IRubyObject self, String name) { + DynamicMethod method = searchMethod(name); + if (method.isUndefined()) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, context.getFrameSelf(), CallType.FUNCTIONAL, Block.NULL_BLOCK); } return method.call(context, self, this, name); } @@ -358,18 +412,36 @@ public class RubyClass extends RubyModule { IRubyObject[] args, CallType callType) { assert args != null; DynamicMethod method = searchMethod(name); - if (method.isUndefined() || (!name.equals("method_missing") && !method.isCallableFrom(context.getFrameSelf(), callType))) { + if (method.isUndefined() || notVisibleAndNotMethodMissing(method, name, context.getFrameSelf(), callType)) { return RuntimeHelpers.callMethodMissing(context, self, method, name, args, context.getFrameSelf(), callType, Block.NULL_BLOCK); } return method.call(context, self, this, name, args); } + public IRubyObject finvoke(ThreadContext context, IRubyObject self, String name, + IRubyObject[] args) { + assert args != null; + DynamicMethod method = searchMethod(name); + if (method.isUndefined()) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, args, context.getFrameSelf(), CallType.FUNCTIONAL, Block.NULL_BLOCK); + } + return method.call(context, self, this, name, args); + } + public IRubyObject invoke(ThreadContext context, IRubyObject self, String name, IRubyObject arg, CallType callType) { DynamicMethod method = searchMethod(name); - if (method.isUndefined() || (!name.equals("method_missing") && !method.isCallableFrom(context.getFrameSelf(), callType))) { - return RuntimeHelpers.callMethodMissing(context, self, method, name, - new IRubyObject[] {arg}, context.getFrameSelf(), callType, Block.NULL_BLOCK); + if (method.isUndefined() || notVisibleAndNotMethodMissing(method, name, context.getFrameSelf(), callType)) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, arg, context.getFrameSelf(), callType, Block.NULL_BLOCK); + } + return method.call(context, self, this, name, arg); + } + + public IRubyObject finvoke(ThreadContext context, IRubyObject self, String name, + IRubyObject arg) { + DynamicMethod method = searchMethod(name); + if (method.isUndefined()) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, arg, context.getFrameSelf(), CallType.FUNCTIONAL, Block.NULL_BLOCK); } return method.call(context, self, this, name, arg); } @@ -377,9 +449,17 @@ public class RubyClass extends RubyModule { public IRubyObject invoke(ThreadContext context, IRubyObject self, String name, IRubyObject arg0, IRubyObject arg1, CallType callType) { DynamicMethod method = searchMethod(name); - if (method.isUndefined() || (!name.equals("method_missing") && !method.isCallableFrom(context.getFrameSelf(), callType))) { - return RuntimeHelpers.callMethodMissing(context, self, method, name, - new IRubyObject[] {arg0, arg1}, context.getFrameSelf(), callType, Block.NULL_BLOCK); + if (method.isUndefined() || notVisibleAndNotMethodMissing(method, name, context.getFrameSelf(), callType)) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, arg0, arg1, context.getFrameSelf(), callType, Block.NULL_BLOCK); + } + return method.call(context, self, this, name, arg0, arg1); + } + + public IRubyObject finvoke(ThreadContext context, IRubyObject self, String name, + IRubyObject arg0, IRubyObject arg1) { + DynamicMethod method = searchMethod(name); + if (method.isUndefined()) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, arg0, arg1, context.getFrameSelf(), CallType.FUNCTIONAL, Block.NULL_BLOCK); } return method.call(context, self, this, name, arg0, arg1); } @@ -387,9 +467,17 @@ public class RubyClass extends RubyModule { public IRubyObject invoke(ThreadContext context, IRubyObject self, String name, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2, CallType callType) { DynamicMethod method = searchMethod(name); - if (method.isUndefined() || (!name.equals("method_missing") && !method.isCallableFrom(context.getFrameSelf(), callType))) { - return RuntimeHelpers.callMethodMissing(context, self, method, name, - new IRubyObject[] {arg0, arg1, arg2}, context.getFrameSelf(), callType, Block.NULL_BLOCK); + if (method.isUndefined() || notVisibleAndNotMethodMissing(method, name, context.getFrameSelf(), callType)) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, arg0, arg1, arg2, context.getFrameSelf(), callType, Block.NULL_BLOCK); + } + return method.call(context, self, this, name, arg0, arg1, arg2); + } + + public IRubyObject finvoke(ThreadContext context, IRubyObject self, String name, + IRubyObject arg0, IRubyObject arg1, IRubyObject arg2) { + DynamicMethod method = searchMethod(name); + if (method.isUndefined()) { + return RuntimeHelpers.callMethodMissing(context, self, method, name, arg0, arg1, arg2, context.getFrameSelf(), CallType.FUNCTIONAL, Block.NULL_BLOCK); } return method.call(context, self, this, name, arg0, arg1, arg2); } @@ -398,8 +486,7 @@ public class RubyClass extends RubyModule { DynamicMethod method = getMetaClass().searchMethod("inherited"); if (method.isUndefined()) { - return RuntimeHelpers.callMethodMissing(context, self, method, "inherited", - new IRubyObject[] {subclass}, context.getFrameSelf(), CallType.FUNCTIONAL, Block.NULL_BLOCK); + return RuntimeHelpers.callMethodMissing(context, self, method, "inherited", subclass, context.getFrameSelf(), CallType.FUNCTIONAL, Block.NULL_BLOCK); } return method.call(context, self, getMetaClass(), "inherited", subclass, Block.NULL_BLOCK); diff --git a/src/org/jruby/RubyKernel.java b/src/org/jruby/RubyKernel.java index c435a8102..8be785509 100644 --- a/src/org/jruby/RubyKernel.java +++ b/src/org/jruby/RubyKernel.java @@ -916,7 +916,7 @@ public class RubyKernel { @JRubyMethod(name = "trap", required = 1, frame = true, optional = 1, module = true, visibility = PRIVATE) public static IRubyObject trap(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block block) { context.getRuntime().getLoadService().require("jsignal"); - return RuntimeHelpers.invoke(context, recv, "__jtrap", args, CallType.FUNCTIONAL, block); + return RuntimeHelpers.invoke(context, recv, "__jtrap", args, block); } @JRubyMethod(name = "warn", required = 1, module = true, visibility = PRIVATE) diff --git a/src/org/jruby/RubyObject.java b/src/org/jruby/RubyObject.java index bcd1697b9..828ad5842 100644 --- a/src/org/jruby/RubyObject.java +++ b/src/org/jruby/RubyObject.java @@ -689,7 +689,7 @@ public class RubyObject implements Cloneable, IRubyObject, Serializable, CoreObj * Will invoke a named method with no arguments and no block. */ public final IRubyObject callMethod(ThreadContext context, String name) { - return RuntimeHelpers.invoke(context, this, name, IRubyObject.NULL_ARRAY, null, Block.NULL_BLOCK); + return RuntimeHelpers.invoke(context, this, name, IRubyObject.NULL_ARRAY, Block.NULL_BLOCK); } /** @@ -697,7 +697,7 @@ public class RubyObject implements Cloneable, IRubyObject, Serializable, CoreObj * functional invocation. */ public final IRubyObject callMethod(ThreadContext context, String name, IRubyObject arg) { - return RuntimeHelpers.invoke(context, this, name, arg, CallType.FUNCTIONAL, Block.NULL_BLOCK); + return RuntimeHelpers.invoke(context, this, name, arg, Block.NULL_BLOCK); } /** @@ -705,7 +705,7 @@ public class RubyObject implements Cloneable, IRubyObject, Serializable, CoreObj * block with functional invocation. */ public final IRubyObject callMethod(ThreadContext context, String name, IRubyObject[] args) { - return RuntimeHelpers.invoke(context, this, name, args, CallType.FUNCTIONAL, Block.NULL_BLOCK); + return RuntimeHelpers.invoke(context, this, name, args, Block.NULL_BLOCK); } /** @@ -713,7 +713,7 @@ public class RubyObject implements Cloneable, IRubyObject, Serializable, CoreObj * supplied block with functional invocation. */ public final IRubyObject callMethod(ThreadContext context, String name, IRubyObject[] args, Block block) { - return RuntimeHelpers.invoke(context, this, name, args, CallType.FUNCTIONAL, block); + return RuntimeHelpers.invoke(context, this, name, args, block); } /** diff --git a/src/org/jruby/RubySignal.java b/src/org/jruby/RubySignal.java index cdbfc6ec4..3bd21488b 100644 --- a/src/org/jruby/RubySignal.java +++ b/src/org/jruby/RubySignal.java @@ -68,7 +68,7 @@ public class RubySignal { public static IRubyObject trap(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block block) { Ruby runtime = recv.getRuntime(); runtime.getLoadService().require("jsignal"); - return RuntimeHelpers.invoke(context, runtime.getKernel(), "__jtrap", args, CallType.FUNCTIONAL, block); + return RuntimeHelpers.invoke(context, runtime.getKernel(), "__jtrap", args, block); } @JRubyMethod(name = "list", meta = true) diff --git a/src/org/jruby/ast/AttrAssignNode.java b/src/org/jruby/ast/AttrAssignNode.java index 0c1fa9017..5c0574ddc 100644 --- a/src/org/jruby/ast/AttrAssignNode.java +++ b/src/org/jruby/ast/AttrAssignNode.java @@ -206,14 +206,36 @@ public class AttrAssignNode extends Node implements INameNode, IArgumentNode { IRubyObject receiver = receiverNode.interpret(runtime, context, self, block); // If reciever is self then we do the call the same way as vcall - CallType callType = (receiver == self ? CallType.VARIABLE : CallType.NORMAL); + if (receiver == self) { + return selfAssign(runtime, context, self, value, block, checkArity); + } else { + return otherAssign(runtime, context, self, value, block, checkArity); + } + } + + private IRubyObject selfAssign(Ruby runtime, ThreadContext context, IRubyObject self, IRubyObject value, Block block, boolean checkArity) { + IRubyObject receiver = receiverNode.interpret(runtime, context, self, block); + + if (argsNode == null) { // attribute set. + RuntimeHelpers.invoke(context, receiver, name, value, Block.NULL_BLOCK); + } else { // element set + RubyArray args = (RubyArray) argsNode.interpret(runtime, context, self, block); + args.append(value); + RuntimeHelpers.invoke(context, receiver, name, args.toJavaArray(), Block.NULL_BLOCK); + } + + return runtime.getNil(); + } + + private IRubyObject otherAssign(Ruby runtime, ThreadContext context, IRubyObject self, IRubyObject value, Block block, boolean checkArity) { + IRubyObject receiver = receiverNode.interpret(runtime, context, self, block); if (argsNode == null) { // attribute set. - RuntimeHelpers.invoke(context, receiver, name, value, callType, Block.NULL_BLOCK); + RuntimeHelpers.invoke(context, receiver, name, value, CallType.NORMAL, Block.NULL_BLOCK); } else { // element set RubyArray args = (RubyArray) argsNode.interpret(runtime, context, self, block); args.append(value); - RuntimeHelpers.invoke(context, receiver, name, args.toJavaArray(), callType, Block.NULL_BLOCK); + RuntimeHelpers.invoke(context, receiver, name, args.toJavaArray(), CallType.NORMAL, Block.NULL_BLOCK); } return runtime.getNil(); diff --git a/src/org/jruby/ast/executable/RubiniusMachine.java b/src/org/jruby/ast/executable/RubiniusMachine.java index c41d1b63a..8084628c2 100644 --- a/src/org/jruby/ast/executable/RubiniusMachine.java +++ b/src/org/jruby/ast/executable/RubiniusMachine.java @@ -272,7 +272,7 @@ public class RubiniusMachine { argu[i] = stack[stackTop--]; } if((call_flags & 0x01) == 0x01) { //Functional - stack[++stackTop] = RuntimeHelpers.invoke(context, recv, name, argu, CallType.FUNCTIONAL, Block.NULL_BLOCK); + stack[++stackTop] = RuntimeHelpers.invoke(context, recv, name, argu, Block.NULL_BLOCK); } else { stack[++stackTop] = RuntimeHelpers.invoke(context, recv, name, argu, CallType.NORMAL, Block.NULL_BLOCK); } diff --git a/src/org/jruby/java/proxies/JavaProxy.java b/src/org/jruby/java/proxies/JavaProxy.java index be3fbdcd3..00dd69b26 100644 --- a/src/org/jruby/java/proxies/JavaProxy.java +++ b/src/org/jruby/java/proxies/JavaProxy.java @@ -63,7 +63,7 @@ public class JavaProxy extends RubyObject { @JRubyMethod(name = "[]", meta = true, rest = true) public static IRubyObject op_aref(ThreadContext context, IRubyObject recv, IRubyObject[] args) { - IRubyObject javaClass = RuntimeHelpers.invoke(context, recv, "java_class", CallType.VARIABLE); + IRubyObject javaClass = RuntimeHelpers.invoke(context, recv, "java_class"); if (args.length > 0) { // construct new array proxy (ArrayJavaProxy) IRubyObject[] newArgs = new IRubyObject[args.length + 1]; diff --git a/src/org/jruby/javasupport/JavaClass.java b/src/org/jruby/javasupport/JavaClass.java index 6416de91f..2ce2a6dda 100644 --- a/src/org/jruby/javasupport/JavaClass.java +++ b/src/org/jruby/javasupport/JavaClass.java @@ -894,7 +894,7 @@ public class JavaClass extends JavaObject { System.arraycopy(args, 1, newArgs, 0, newArgs.length); if(v < 0 || v == (newArgs.length)) { - return RuntimeHelpers.invoke(self.getRuntime().getCurrentContext(), self, name, newArgs, CallType.FUNCTIONAL, block); + return RuntimeHelpers.invoke(self.getRuntime().getCurrentContext(), self, name, newArgs, block); } else { RubyClass superClass = self.getMetaClass().getSuperClass(); return RuntimeHelpers.invokeAs(self.getRuntime().getCurrentContext(), superClass, self, name, newArgs, CallType.SUPER, block); diff --git a/src/org/jruby/javasupport/JavaProxyMethods.java b/src/org/jruby/javasupport/JavaProxyMethods.java index 482a03ca0..2ca3b27de 100644 --- a/src/org/jruby/javasupport/JavaProxyMethods.java +++ b/src/org/jruby/javasupport/JavaProxyMethods.java @@ -26,7 +26,7 @@ public class JavaProxyMethods { public static IRubyObject java_class(ThreadContext context, IRubyObject recv) { RubyClass metaClass = recv.getMetaClass(); // TODO: can't we dig this out without a method call? - return RuntimeHelpers.invoke(context, metaClass, "java_class", CallType.FUNCTIONAL); + return RuntimeHelpers.invoke(context, metaClass, "java_class"); } @JRubyMethod(name = "==") diff --git a/src/org/jruby/javasupport/proxy/JavaProxyConstructor.java b/src/org/jruby/javasupport/proxy/JavaProxyConstructor.java index 28eaef6b4..8080e46f1 100644 --- a/src/org/jruby/javasupport/proxy/JavaProxyConstructor.java +++ b/src/org/jruby/javasupport/proxy/JavaProxyConstructor.java @@ -184,7 +184,7 @@ public class JavaProxyConstructor extends JavaProxyReflectionObject implements P } if (v < 0 || v == (newArgs.length)) { - return JavaUtil.convertRubyToJava(RuntimeHelpers.invoke(runtime.getCurrentContext(), self, name, newArgs, CallType.FUNCTIONAL, Block.NULL_BLOCK), m.getReturnType()); + return JavaUtil.convertRubyToJava(RuntimeHelpers.invoke(runtime.getCurrentContext(), self, name, newArgs, Block.NULL_BLOCK), m.getReturnType()); } else { RubyClass superClass = self.getMetaClass().getSuperClass(); return JavaUtil.convertRubyToJava(RuntimeHelpers.invokeAs(runtime.getCurrentContext(), superClass, self, name, newArgs, CallType.SUPER, Block.NULL_BLOCK), m.getReturnType()); diff --git a/src/org/jruby/javasupport/util/RuntimeHelpers.java b/src/org/jruby/javasupport/util/RuntimeHelpers.java index 19e6bf82e..4c4b8e760 100644 --- a/src/org/jruby/javasupport/util/RuntimeHelpers.java +++ b/src/org/jruby/javasupport/util/RuntimeHelpers.java @@ -228,19 +228,21 @@ public class RuntimeHelpers { } + @Deprecated public static IRubyObject callMethodMissing(ThreadContext context, IRubyObject receiver, DynamicMethod method, String name, int methodIndex, IRubyObject[] args, IRubyObject self, CallType callType, Block block) { - // store call information so method_missing impl can use it - context.setLastCallStatus(callType); - context.setLastVisibility(method.getVisibility()); - - if (methodIndex == MethodIndex.METHOD_MISSING) { + return callMethodMissing(context, receiver, method, name, args, self, callType, block); + } + + private static IRubyObject callMethodMissingInternal(ThreadContext context, IRubyObject receiver, String name, + IRubyObject[] args, IRubyObject self, Block block) { + if (name.equals("method_missing")) { return RubyKernel.method_missing(context, self, args, block); } - + IRubyObject[] newArgs = prepareMethodMissingArgs(args, context, name); - return receiver.callMethod(context, "method_missing", newArgs, block); + return invoke(context, receiver, "method_missing", newArgs, block); } public static IRubyObject callMethodMissing(ThreadContext context, IRubyObject receiver, DynamicMethod method, String name, @@ -248,14 +250,35 @@ public class RuntimeHelpers { // store call information so method_missing impl can use it context.setLastCallStatus(callType); context.setLastVisibility(method.getVisibility()); - - if (name.equals("method_missing")) { - return RubyKernel.method_missing(context, self, args, block); - } - - IRubyObject[] newArgs = prepareMethodMissingArgs(args, context, name); - - return receiver.callMethod(context, "method_missing", newArgs, block); + return callMethodMissingInternal(context, receiver, name, args, self, block); + } + public static IRubyObject callMethodMissing(ThreadContext context, IRubyObject receiver, DynamicMethod method, String name, + IRubyObject arg, IRubyObject self, CallType callType, Block block) { + // store call information so method_missing impl can use it + context.setLastCallStatus(callType); + context.setLastVisibility(method.getVisibility()); + return callMethodMissingInternal(context, receiver, name, new IRubyObject[] {arg}, self, block); + } + public static IRubyObject callMethodMissing(ThreadContext context, IRubyObject receiver, DynamicMethod method, String name, + IRubyObject arg0, IRubyObject arg1, IRubyObject self, CallType callType, Block block) { + // store call information so method_missing impl can use it + context.setLastCallStatus(callType); + context.setLastVisibility(method.getVisibility()); + return callMethodMissingInternal(context, receiver, name, new IRubyObject[] {arg0,arg1}, self, block); + } + public static IRubyObject callMethodMissing(ThreadContext context, IRubyObject receiver, DynamicMethod method, String name, + IRubyObject arg0, IRubyObject arg1, IRubyObject arg2, IRubyObject self, CallType callType, Block block) { + // store call information so method_missing impl can use it + context.setLastCallStatus(callType); + context.setLastVisibility(method.getVisibility()); + return callMethodMissingInternal(context, receiver, name, new IRubyObject[] {arg0,arg1,arg2}, self, block); + } + public static IRubyObject callMethodMissing(ThreadContext context, IRubyObject receiver, DynamicMethod method, String name, + IRubyObject self, CallType callType, Block block) { + // store call information so method_missing impl can use it + context.setLastCallStatus(callType); + context.setLastVisibility(method.getVisibility()); + return callMethodMissingInternal(context, receiver, name, IRubyObject.NULL_ARRAY, self, block); } public static IRubyObject callMethodMissing(ThreadContext context, IRubyObject receiver, DynamicMethod method, String name, @@ -263,14 +286,7 @@ public class RuntimeHelpers { // store call information so method_missing impl can use it context.setLastCallStatus(CallType.FUNCTIONAL); context.setLastVisibility(Visibility.PUBLIC); - - if (name.equals("method_missing")) { - return RubyKernel.method_missing(context, self, args, Block.NULL_BLOCK); - } - - IRubyObject[] newArgs = prepareMethodMissingArgs(args, context, name); - - return receiver.callMethod(context, "method_missing", newArgs, Block.NULL_BLOCK); + return callMethodMissingInternal(context, receiver, name, args, self, Block.NULL_BLOCK); } public static IRubyObject invokeMethodMissing(IRubyObject receiver, String name, IRubyObject[] args) { @@ -286,39 +302,39 @@ public class RuntimeHelpers { IRubyObject[] newArgs = prepareMethodMissingArgs(args, context, name); - return receiver.callMethod(context, "method_missing", newArgs, Block.NULL_BLOCK); + return invoke(context, receiver, "method_missing", newArgs, Block.NULL_BLOCK); } public static IRubyObject invoke(ThreadContext context, IRubyObject self, String name, Block block) { - return self.getMetaClass().invoke(context, self, name, CallType.FUNCTIONAL, block); + return self.getMetaClass().finvoke(context, self, name, block); } public static IRubyObject invoke(ThreadContext context, IRubyObject self, String name, IRubyObject arg0, Block block) { - return self.getMetaClass().invoke(context, self, name, arg0, CallType.FUNCTIONAL, block); + return self.getMetaClass().finvoke(context, self, name, arg0, block); } public static IRubyObject invoke(ThreadContext context, IRubyObject self, String name, IRubyObject arg0, IRubyObject arg1, Block block) { - return self.getMetaClass().invoke(context, self, name, arg0, arg1, CallType.FUNCTIONAL, block); + return self.getMetaClass().finvoke(context, self, name, arg0, arg1, block); } public static IRubyObject invoke(ThreadContext context, IRubyObject self, String name, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2, Block block) { - return self.getMetaClass().invoke(context, self, name, arg0, arg1, arg2, CallType.FUNCTIONAL, block); + return self.getMetaClass().finvoke(context, self, name, arg0, arg1, arg2, block); } public static IRubyObject invoke(ThreadContext context, IRubyObject self, String name, IRubyObject[] args, Block block) { - return self.getMetaClass().invoke(context, self, name, args, CallType.FUNCTIONAL, block); + return self.getMetaClass().finvoke(context, self, name, args, block); } public static IRubyObject invoke(ThreadContext context, IRubyObject self, String name) { - return self.getMetaClass().invoke(context, self, name, CallType.FUNCTIONAL); + return self.getMetaClass().finvoke(context, self, name); } public static IRubyObject invoke(ThreadContext context, IRubyObject self, String name, IRubyObject arg0) { - return self.getMetaClass().invoke(context, self, name, arg0, CallType.FUNCTIONAL); + return self.getMetaClass().finvoke(context, self, name, arg0); } public static IRubyObject invoke(ThreadContext context, IRubyObject self, String name, IRubyObject arg0, IRubyObject arg1) { - return self.getMetaClass().invoke(context, self, name, arg0, arg1, CallType.FUNCTIONAL); + return self.getMetaClass().finvoke(context, self, name, arg0, arg1); } public static IRubyObject invoke(ThreadContext context, IRubyObject self, String name, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2) { - return self.getMetaClass().invoke(context, self, name, arg0, arg1, arg2, CallType.FUNCTIONAL); + return self.getMetaClass().finvoke(context, self, name, arg0, arg1, arg2); } public static IRubyObject invoke(ThreadContext context, IRubyObject self, String name, IRubyObject[] args) { - return self.getMetaClass().invoke(context, self, name, args, CallType.FUNCTIONAL); + return self.getMetaClass().finvoke(context, self, name, args); } public static IRubyObject invoke(ThreadContext context, IRubyObject self, String name, CallType callType) { -- 2.11.4.GIT