Invoke the Java method on the specified object, performing needed type mappings on arguments and return values. @param args may be null
(Method method, Object object, Object[] args)
| 116 | * @param args may be null |
| 117 | */ |
| 118 | static Object invokeMethod(Method method, Object object, Object[] args) throws ReflectError, InvocationTargetException { |
| 119 | if (args == null) { |
| 120 | args = new Object[0]; |
| 121 | } |
| 122 | |
| 123 | logInvokeMethod("Invoking method (entry): ", method, args); |
| 124 | |
| 125 | boolean isVarArgs = method.isVarArgs(); |
| 126 | |
| 127 | // Map types to assignable forms, need to keep this fast... |
| 128 | Class[] types = method.getParameterTypes(); |
| 129 | Object[] tmpArgs = new Object[types.length]; |
| 130 | int fixedArgLen = types.length; |
| 131 | if (isVarArgs) { |
| 132 | if (fixedArgLen == args.length && types[fixedArgLen - 1].isAssignableFrom(args[fixedArgLen - 1].getClass())) { |
| 133 | isVarArgs = false; |
| 134 | } else { |
| 135 | fixedArgLen--; |
| 136 | } |
| 137 | } |
| 138 | try { |
| 139 | for (int i = 0; i < fixedArgLen; i++) { |
| 140 | tmpArgs[i] = Types.castObject(args[i]/*rhs*/, types[i]/*lhsType*/, Types.ASSIGNMENT); |
| 141 | } |
| 142 | if (isVarArgs) { |
| 143 | Class varType = types[fixedArgLen].getComponentType(); |
| 144 | Object varArgs = Array.newInstance(varType, args.length - fixedArgLen); |
| 145 | for (int i = fixedArgLen, j = 0; i < args.length; i++, j++) { |
| 146 | Array.set(varArgs, j, Primitive.unwrap(Types.castObject(args[i]/*rhs*/, varType/*lhsType*/, Types.ASSIGNMENT))); |
| 147 | } |
| 148 | tmpArgs[fixedArgLen] = varArgs; |
| 149 | } |
| 150 | } catch (UtilEvalError e) { |
| 151 | throw new InterpreterError("illegal argument type in method invocation: " + e); |
| 152 | } |
| 153 | |
| 154 | // unwrap any primitives |
| 155 | tmpArgs = Primitive.unwrap(tmpArgs); |
| 156 | |
| 157 | logInvokeMethod("Invoking method (after massaging values): ", method, tmpArgs); |
| 158 | |
| 159 | try { |
| 160 | Object returnValue = method.invoke(object, tmpArgs); |
| 161 | if (returnValue == null) { |
| 162 | returnValue = Primitive.NULL; |
| 163 | } |
| 164 | Class returnType = method.getReturnType(); |
| 165 | |
| 166 | return Primitive.wrap(returnValue, returnType); |
| 167 | } catch (IllegalAccessException e) { |
| 168 | throw new ReflectError("Cannot access method " + StringUtil.methodString(method.getName(), method.getParameterTypes()) + " in '" + method.getDeclaringClass() + "' :" + e, e); |
| 169 | } |
| 170 | } |
| 171 | |
| 172 | |
| 173 | public static Object getIndex(Object array, int index) throws ReflectError, UtilTargetError { |
no test coverage detected