# HG changeset patch # User Doug Simon # Date 1385487833 -3600 # Node ID 74cfcd0fbedfa1e30321e8b4ed6502a075ab4a76 # Parent bc868f83bcec413de3eef8898381e805e4288a81 made method substitution take return types into account (GRAAL-612) diff -r bc868f83bcec -r 74cfcd0fbedf graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Tue Nov 26 13:35:52 2013 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Tue Nov 26 18:43:53 2013 +0100 @@ -165,8 +165,8 @@ throw new GraalInternalError("Substitution method must not be abstract or native: " + substituteMethod); } String originalName = originalName(substituteMethod, methodSubstitution.value()); - Class[] originalParameters = originalParameters(substituteMethod, methodSubstitution.signature(), methodSubstitution.isStatic()); - Member originalMethod = originalMethod(classSubstitution, methodSubstitution.optional(), originalName, originalParameters); + JavaSignature originalSignature = originalSignature(substituteMethod, methodSubstitution.signature(), methodSubstitution.isStatic()); + Member originalMethod = originalMethod(classSubstitution, methodSubstitution.optional(), originalName, originalSignature); if (originalMethod != null) { ResolvedJavaMethod original = registerMethodSubstitution(originalMethod, substituteMethod); if (original != null && methodSubstitution.forced() && shouldIntrinsify(original)) { @@ -176,8 +176,8 @@ } if (macroSubstitution != null) { String originalName = originalName(substituteMethod, macroSubstitution.value()); - Class[] originalParameters = originalParameters(substituteMethod, macroSubstitution.signature(), macroSubstitution.isStatic()); - Member originalMethod = originalMethod(classSubstitution, macroSubstitution.optional(), originalName, originalParameters); + JavaSignature originalSignature = originalSignature(substituteMethod, macroSubstitution.signature(), macroSubstitution.isStatic()); + Member originalMethod = originalMethod(classSubstitution, macroSubstitution.optional(), originalName, originalSignature); if (originalMethod != null) { ResolvedJavaMethod original = registerMacroSubstitution(originalMethod, macroSubstitution.macro()); if (original != null && macroSubstitution.forced() && shouldIntrinsify(original)) { @@ -204,7 +204,7 @@ } else { original = metaAccess.lookupJavaConstructor((Constructor) originalMember); } - Debug.log("substitution: " + MetaUtil.format("%H.%n(%p)", original) + " --> " + MetaUtil.format("%H.%n(%p)", substitute)); + Debug.log("substitution: " + MetaUtil.format("%H.%n(%p) %r", original) + " --> " + MetaUtil.format("%H.%n(%p) %r", substitute)); registeredMethodSubstitutions.put(original, substitute); return original; @@ -507,25 +507,50 @@ return dimensions == 0 ? baseClass : Array.newInstance(baseClass, new int[dimensions]).getClass(); } - private Class[] originalParameters(Method substituteMethod, String methodSubstitution, boolean isStatic) { + static class JavaSignature { + final Class returnType; + final Class[] parameters; + + public JavaSignature(Class returnType, Class[] parameters) { + this.parameters = parameters; + this.returnType = returnType; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("("); + for (int i = 0; i < parameters.length; i++) { + if (i != 0) { + sb.append(", "); + } + sb.append(parameters[i].getName()); + } + return sb.append(") ").append(returnType.getName()).toString(); + } + } + + private JavaSignature originalSignature(Method substituteMethod, String methodSubstitution, boolean isStatic) { Class[] parameters; + Class returnType; if (methodSubstitution.isEmpty()) { parameters = substituteMethod.getParameterTypes(); if (!isStatic) { assert parameters.length > 0 : "must be a static method with the 'this' object as its first parameter"; parameters = Arrays.copyOfRange(parameters, 1, parameters.length); } + returnType = substituteMethod.getReturnType(); } else { Signature signature = providers.getMetaAccess().parseMethodDescriptor(methodSubstitution); parameters = new Class[signature.getParameterCount(false)]; for (int i = 0; i < parameters.length; i++) { parameters[i] = resolveType(signature.getParameterType(i, null)); } + returnType = resolveType(signature.getReturnType(null)); } - return parameters; + return new JavaSignature(returnType, parameters); } - private static Member originalMethod(ClassSubstitution classSubstitution, boolean optional, String name, Class[] parameters) { + private static Member originalMethod(ClassSubstitution classSubstitution, boolean optional, String name, JavaSignature signature) { Class originalClass = classSubstitution.value(); if (originalClass == ClassSubstitution.class) { originalClass = resolveType(classSubstitution.className(), classSubstitution.optional()); @@ -536,9 +561,15 @@ } try { if (name.equals("")) { - return originalClass.getDeclaredConstructor(parameters); + assert signature.returnType.equals(void.class) : signature; + Constructor original = originalClass.getDeclaredConstructor(signature.parameters); + return original; } else { - return originalClass.getDeclaredMethod(name, parameters); + Method original = originalClass.getDeclaredMethod(name, signature.parameters); + if (!original.getReturnType().equals(signature.returnType)) { + throw new NoSuchMethodException(originalClass.getName() + "." + name + signature); + } + return original; } } catch (NoSuchMethodException | SecurityException e) { if (optional) {