Remapper variables during bytecode method inlining by ASM

一世执手 提交于 2019-12-03 06:48:01

As @Holger already suggested, start by uncommenting the lines in InliningAdapter.

  1. To tackle the main problems you listed: The LocalVariablesSorter (extended by InliningAdapter) thinks that the arguments are already stored in the local variables at fixed locations - this is indeed the normal situation when entering a method. So it does not map those at all (see first line in LocalVariablesSorter.remap() - firstLocal is calculated in constructor). However in this case we get the arguments on the stack instead and need to allocate the local variables manually. The solution is to tell LocalVariablesSorter that there are no parameters already stored in local variables (make firstLocal = 0). Then it will treat any reference to them as new variables and allocate new local variables for them. This we can achieve by fooling LocalVariablesSorter to think that there are no arguments and that the method is static (even if it really isn't). So we change the first line in InliningAdapter from

        super(acc, desc, mv, remapper);
    

    to

        super(acc | Opcodes.ACC_STATIC, "()V", mv, remapper);
    

    Now the variables 0,1,2,... get remapped to 5,6,7,... or similar (doesn't really matter what they are, the LocalVariablesSorter of Caller (i.e. the MethodCallInliner instance) takes care of allocating them).

  2. There is another problem also that you map the Callee class to Caller by having InliningAdapter extend RemappingMethodAdaptor - however I guess you want to keep the _a and _b variables stored in the Callee instance.

    • If my guess is correct then you should actually not remap the references from Callee to Caller. You can just make InliningAdapter extend LocalVariableSorter instead and get rid of the remapper.
    • If my guess is incorrect then I guess you will probably need to embed the variables of Callee into Caller as well, in which case you should keep the RemappingMethodAdaptor you have.
  3. When debugging the inlined code the linenumbers from the Callee will not make sense since the code was inlined into the Caller class. So all linenumbers from Callee should probably be replaced with the line number of the line in Caller where the inlined call occured. Unfortunately in Java you cannot specify different source code files on a line-by-line basis (like you can in C for example). So you would override visitLineNumber() in InliningAdapter using something like this (inlinedLine would be passed to constructor of InliningAdapter):

    @Override
    public void visitLineNumber(int line, Label start) {
        super.visitLineNumber(inlinedLine, start);
    }
    

    .. or perhaps skip the super call altogether, I'm not 100% sure about this.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!