Fuck Stringer @param src @param owner @param min @param args @return
(String callerCaller, MethodNode src, ClassNode owner, MethodInsnNode min, Object[] args)
| 203 | * @return |
| 204 | */ |
| 205 | public static Object getProxyReturnStringer(String callerCaller, MethodNode src, ClassNode owner, MethodInsnNode min, |
| 206 | Object[] args) { |
| 207 | if (owner == null) { |
| 208 | return null; |
| 209 | } |
| 210 | // Creating the proxy class |
| 211 | ClassNode proxy = new ClassNode(); |
| 212 | proxy.name = min.owner; |
| 213 | proxy.superName = "java/lang/Object"; |
| 214 | proxy.version = 52; |
| 215 | proxy.access = Opcodes.ACC_PUBLIC; |
| 216 | MethodNode methodCallProxy = new MethodNode(); |
| 217 | methodCallProxy.name = src.name; |
| 218 | methodCallProxy.desc = "()Ljava/lang/String;"; |
| 219 | methodCallProxy.access = Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC; |
| 220 | methodCallProxy.exceptions = new ArrayList<String>(); |
| 221 | methodCallProxy.owner = proxy.name; |
| 222 | for (Object o : args) { |
| 223 | boolean n = o instanceof Number; |
| 224 | if (o instanceof String || (n && !(o instanceof Integer))) { |
| 225 | methodCallProxy.instructions.add(new LdcInsnNode(o)); |
| 226 | } else if (n) { |
| 227 | methodCallProxy.instructions.add(OpUtils.toInt(((Number) o).intValue())); |
| 228 | } |
| 229 | } |
| 230 | methodCallProxy.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, min.owner, min.name, min.desc, false)); |
| 231 | methodCallProxy.instructions.add(new InsnNode(Opcodes.ARETURN)); |
| 232 | methodCallProxy.visitMaxs(args.length, 0); |
| 233 | proxy.methods.add(methodCallProxy); |
| 234 | // Second proxy class because #Stringer |
| 235 | ClassNode proxy2 = new ClassNode(); |
| 236 | proxy2.name = callerCaller; |
| 237 | proxy2.superName = "java/lang/Object"; |
| 238 | proxy2.version = 52; |
| 239 | proxy2.access = Opcodes.ACC_PUBLIC; |
| 240 | MethodNode methodCallProxy2 = new MethodNode(); |
| 241 | methodCallProxy2.name = "sandbox"; |
| 242 | methodCallProxy2.desc = "()Ljava/lang/String;"; |
| 243 | methodCallProxy2.access = Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC; |
| 244 | methodCallProxy2.exceptions = new ArrayList<String>(); |
| 245 | methodCallProxy2.owner = proxy2.name; |
| 246 | methodCallProxy2.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, methodCallProxy.owner, |
| 247 | methodCallProxy.name, methodCallProxy.desc, false)); |
| 248 | methodCallProxy2.instructions.add(new InsnNode(Opcodes.ARETURN)); |
| 249 | methodCallProxy2.visitMaxs(1, 0); |
| 250 | proxy2.methods.add(methodCallProxy2); |
| 251 | |
| 252 | // |
| 253 | // Now that the proxy call is done |
| 254 | // Sometimes classes/methods will have improper access, so we're gonna |
| 255 | // have to fix that. |
| 256 | owner.version = 52; |
| 257 | owner.access = Opcodes.ACC_PUBLIC; |
| 258 | for (MethodNode mn : owner.methods) { |
| 259 | boolean isStatic = AccessHelper.isStatic(mn.access); |
| 260 | mn.access = Opcodes.ACC_PUBLIC; |
| 261 | if (isStatic) { |
| 262 | mn.access |= Opcodes.ACC_STATIC; |