Skip to content
Advertisement

How to dynamically cast an object (of class Object) to the method return type using ASM?

What I want to do is to modify a method using ASM:

  1. I push an object (of class Object) to the stack
  2. I want to cast that object to the return type of that method
  3. Return that casted object.

My code in the methodVisitor adapter:

JavaScript

The method getOutputObj in MyClass (It tries to recover previously recorded Json String to an object using Gson):

JavaScript

My first version of method castPeekOnStack:

JavaScript

I tried this code on a benchmark whose methods only have int return type. Then I get java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer. I think when I push the object to the stack, it is of type Double by default if it represents value. So I have the second version:

JavaScript

However, I got java.lang.VerifyError: (class: com/D, method: p signature: ()I) Incompatible object argument for function call. I am stuck here, I have no idea why this error is thrown.

Advertisement

Answer

It seems the problem is: I use mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "intValue", "()I", false); on an object which is not of class java/lang/Double. I need to checkcast java/lang/Double first. I used the third version of method castPeekOnStack, the error has gone:

JavaScript

However I haven’t test the method on a wide range of cases, I am not sure if it can work for other return types.


The solution above can only handle cases that the object is a value. When I try to cast a reference type, It throws something like com.google.gson.internal.LinkedTreeMap cannot be cast to .... So the way I recover object from Json must have some problems.

So in method recoverObjFromJson, I directly cast the Json to the type I want. It should be noted that, although by fromJson the object is casted to the type I designate, the return type of method recoverObjFromJson is still Object, so I still need to cast it on the stack.

JavaScript

Finally, this recoverObjFromJson works well with the first version of castPeekOnStack.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement