【问题标题】:Access variable/constant values in method call在方法调用中访问变量/常量值
【发布时间】:2013-07-25 04:05:07
【问题描述】:

我想查看方法调用的参数。所以如果我打电话给 foo:

x = 4;

y = 5;

...

foo(x, y, 20, 25);

我想打印参数(4,5,20,25) 我知道这些参数在调用方法之前被推入堆栈。如何从方法的局部变量数组中获取值(如果已初始化或为常量)?

visitVarInsn() 和 VarInsnNode 无法从数组中查找实际值。

我需要使用分析器和解释器来执行此操作,还是有更简单的方法?

编辑:想出了如何做到这一点。 我修改了 BasicValue 和 BasicInterpreter 以考虑字节码指令参数。 所以表示像 BIPUSH 这样的指令的值包含有关被推送的值的信息,而不仅仅是类型信息。 使用分析器以相同的方式检查帧

【问题讨论】:

  • 你想解决什么问题?
  • 您想在编译时(不运行程序)还是在运行时静态地找出参数? (第二个蜜蜂要容易得多)
  • 我需要静态地找到它们。我只需要知道它们是否被初始化,以及初始值

标签: java bytecode java-bytecode-asm


【解决方案1】:

直接传递给方法调用的常量数值(20 和 25)很容易静态检索 - 它们会生成推送指令,您可以在 visitIntInsn 中读取这些指令。较小的值将导致您可以使用 visitInsn 捕获的 const 指令,较大的值可以使用 visitLdcInsn 捕获。

我认为通常不可能在方法调用时静态确定绑定到变量的值。您将需要进行数据流分析(按照您的建议使用分析器和解释器),该分析应该能够为每个变量提供可能值的范围。这不会在一般情况下为您提供确定的值,但会在特定情况下为变量分配一次或多次分配,但无条件。

【讨论】:

    【解决方案2】:

    它与 asm 和字节码操作无关,但以防万一 -

    如果方法 foo 属于具有接口方法 foo 的类,则可以使用 Proxy 包装接口实现并截取方法名称。

    此外,您可能会发现 this 答案对 ASM 字节码修改很有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-29
      • 2016-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多