From f0de9e9fa24675b76d164c8ec464df169d05f3c4 Mon Sep 17 00:00:00 2001 From: Clisprail Date: Fri, 16 May 2014 20:31:06 +0200 Subject: [PATCH] Invoker cast args + object args --- .../core/asm/adapters/AddInvokerAdapter.java | 25 +++++++++++++++---- .../parabot/core/asm/wrappers/Invoker.java | 8 +++--- .../core/parsers/hooks/JSONHookParser.java | 2 +- .../core/parsers/hooks/XMLHookParser.java | 3 ++- 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/parabotv2/src/org/parabot/core/asm/adapters/AddInvokerAdapter.java b/parabotv2/src/org/parabot/core/asm/adapters/AddInvokerAdapter.java index 6a7e237..d465939 100644 --- a/parabotv2/src/org/parabot/core/asm/adapters/AddInvokerAdapter.java +++ b/parabotv2/src/org/parabot/core/asm/adapters/AddInvokerAdapter.java @@ -3,6 +3,7 @@ package org.parabot.core.asm.adapters; import java.lang.reflect.Modifier; import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.MethodNode; import org.parabot.core.asm.ASMUtils; @@ -26,13 +27,14 @@ public class AddInvokerAdapter implements Opcodes, Injectable { private String instanceCast; private String mName; private String mDesc; + private String argsCheckCast; private boolean isStatic; public AddInvokerAdapter(final ClassNode methodLocation, final ClassNode into, final MethodNode mn, final String mName, final String mDesc, final String argsDesc, final String returnDesc, final String methodName, - boolean isInterface, String instanceCast) { + boolean isInterface, String instanceCast, String argsCheckCastDesc) { this.into = into; this.methodLocation = methodLocation; this.mName = mName; @@ -43,12 +45,16 @@ public class AddInvokerAdapter implements Opcodes, Injectable { this.methodName = methodName; this.isInterface = isInterface; this.instanceCast = instanceCast; + this.argsCheckCast = argsCheckCastDesc; + } @Override public void inject() { + String mArgsDesc = argsCheckCast == null ? this.argsDesc : this.argsCheckCast; + MethodNode m = new MethodNode(ACC_PUBLIC, this.methodName, - this.argsDesc + this.returnDesc, null, null); + mArgsDesc + this.returnDesc, null, null); if(!isInterface) { isStatic = (this.mn.access & ACC_STATIC) != 0; @@ -73,9 +79,18 @@ public class AddInvokerAdapter implements Opcodes, Injectable { } if (!this.argsDesc.equals("()")) { - for (int i = 1; i < this.argsDesc.length() - 1; i++) { - m.visitVarInsn(ASMUtils.getLoadOpcode(this.argsDesc.substring( - i, i + 1)), i); + Type[] castArgs = argsCheckCast == null ? null : Type.getArgumentTypes(argsCheckCast + "V"); + Type[] methodArgs = Type.getArgumentTypes(argsDesc + "V"); + + for(int i = 0; i < methodArgs.length; i++) { + m.visitVarInsn(ASMUtils.getLoadOpcode(methodArgs[i].getDescriptor()), i + 1); + if(castArgs != null && !castArgs[i].getDescriptor().equals(methodArgs[i].getDescriptor())) { + String cast = methodArgs[i].getDescriptor(); + if(cast.startsWith("L")) { + cast = cast.substring(1).replace(";", ""); + } + m.visitTypeInsn(CHECKCAST, cast); + } } } diff --git a/parabotv2/src/org/parabot/core/asm/wrappers/Invoker.java b/parabotv2/src/org/parabot/core/asm/wrappers/Invoker.java index 6396df7..d68658d 100644 --- a/parabotv2/src/org/parabot/core/asm/wrappers/Invoker.java +++ b/parabotv2/src/org/parabot/core/asm/wrappers/Invoker.java @@ -22,6 +22,7 @@ public class Invoker implements Injectable { private String methodName; private boolean isInterface; private String instanceCast; + private String argsCheckCastDesc; private String mName; private String mDesc; @@ -29,11 +30,11 @@ public class Invoker implements Injectable { public Invoker(String methodLoc, String invMethName, String argsDesc, String returnDesc, String methodName) { this(methodLoc, methodLoc, invMethName, argsDesc, returnDesc, - methodName, false, null); + methodName, false, null, null); } public Invoker(String into, String methodLoc, String invMethName, - String argsDesc, String returnDesc, String methodName, boolean isInterface, String instanceCast) { + String argsDesc, String returnDesc, String methodName, boolean isInterface, String instanceCast, String argsCheckCastDesc) { this.into = ASMUtils.getClass(into); this.methodLocation = ASMUtils.getClass(methodLoc); this.mn = getMethod(this.methodLocation, invMethName, argsDesc); @@ -45,6 +46,7 @@ public class Invoker implements Injectable { this.mName = invMethName; this.mDesc = argsDesc + returnDesc; + this.argsCheckCastDesc = argsCheckCastDesc; } private static MethodNode getMethod(ClassNode into, String name, String desc) { @@ -74,7 +76,7 @@ public class Invoker implements Injectable { */ public AddInvokerAdapter getAdapter() { return new AddInvokerAdapter(this.methodLocation, this.into, this.mn, this.mName, this.mDesc, - this.argsDesc, this.returnDesc, this.methodName, this.isInterface, this.instanceCast); + this.argsDesc, this.returnDesc, this.methodName, this.isInterface, this.instanceCast, this.argsCheckCastDesc); } } diff --git a/parabotv2/src/org/parabot/core/parsers/hooks/JSONHookParser.java b/parabotv2/src/org/parabot/core/parsers/hooks/JSONHookParser.java index 93686bb..eea34eb 100644 --- a/parabotv2/src/org/parabot/core/parsers/hooks/JSONHookParser.java +++ b/parabotv2/src/org/parabot/core/parsers/hooks/JSONHookParser.java @@ -185,7 +185,7 @@ public class JSONHookParser extends HookParser { String clazz = o.containsKey("class") ? this.get(o, "class") : interfaces.get(this.get(o, "accessor")); String into = o.containsKey("into") ? this.get(o, "into") : clazz; - i[j] = new Invoker(into, clazz, this.get(o, "invokemethod"), this.get(o, "argdesc"), this.get(o, "desc"), this.get(o, "method"), false, null); + i[j] = new Invoker(into, clazz, this.get(o, "invokemethod"), this.get(o, "argdesc"), this.get(o, "desc"), this.get(o, "method"), false, null, null); } return i; } diff --git a/parabotv2/src/org/parabot/core/parsers/hooks/XMLHookParser.java b/parabotv2/src/org/parabot/core/parsers/hooks/XMLHookParser.java index 15b5ccd..35f2bae 100644 --- a/parabotv2/src/org/parabot/core/parsers/hooks/XMLHookParser.java +++ b/parabotv2/src/org/parabot/core/parsers/hooks/XMLHookParser.java @@ -348,9 +348,10 @@ public class XMLHookParser extends HookParser { final boolean isInterface = isSet("interface", addInvoker) ? Boolean.parseBoolean(getValue("interface", addInvoker)) : false; final String instanceCast = isSet("instancecast", addInvoker) ? getValue("instancecast", addInvoker) : null; + final String checkCastArgsDesc = isSet("castargs", addInvoker) ? getValue("castargs", addInvoker) : null; final Invoker invoker = new Invoker(into, className, invMethodName, - argsDesc, returnDesc, methodName, isInterface, instanceCast); + argsDesc, returnDesc, methodName, isInterface, instanceCast, checkCastArgsDesc); invokerList.add(invoker); } return invokerList.toArray(new Invoker[invokerList.size()]);