首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java如何在方法中创建局部变量

Java如何在方法中创建局部变量
EN

Stack Overflow用户
提问于 2017-06-21 12:31:09
回答 1查看 2.6K关注 0票数 1

我正在尝试将AST编译成一个java类文件,使用ASM来创建类本身。当我试图向函数添加局部变量(函数是正确创建的)时,我遇到了一个问题。

一个像这样简单的函数:

代码语言:javascript
复制
public void test() {
    int a = 10;
    int b = 11;
    int c = 12;
    int d = 1;
}

一旦被插装(用JD解压缩),就会变成这样:

代码语言:javascript
复制
public void test() {
    int i = 10;
    int j = 11;
    int k = 12;
    int m = 4;
}

它的字节码如下所示:

代码语言:javascript
复制
 public test() { //()V
         bipush 10
         istore1
         bipush 11
         istore2
         bipush 12
         istore3
         iconst_4
         istore4
         return
 }

我正在创建这样的局部变量:

代码语言:javascript
复制
methodVisitor.visitVarInsn(Opcodes.BIPUSH, symbol.value);
methodVisitor.visitVarInsn(Opcodes.ISTORE, position);

symbol是当前局部变量,position是基于1的索引.F.e.a将位于1位置,d将位于4位置。

我的问题是对不同的值正确地使用Opcodes。我尝试了类似于OpcodesOpcodes.LDC,但是生成的类在其方法中没有任何局部变量,但是所有全局定义的变量和函数都在其中两次。

向方法中添加任意类型和任意值变量的正确方法是什么?

编辑:

根据评论,我试图将其他问题的答案合并如下:

代码语言:javascript
复制
MethodVisitor methodVisitor = cw.visitMethod(
        access,
        methodName,
        typeDescriptors,
        null,
        null
);

LocalVariablesSorter mv = new LocalVariablesSorter(access, typeDescriptors, methodVisitor);

然后使用LocalVariablesSorter添加一个局部变量,如下所示:

代码语言:javascript
复制
// type is net.bytebuddy.jar.asm.Type.INT_TYPE
net.bytebuddy.jar.asm.Type type = getType(symbol.type);
int id = mv.newLocal(type);
mv.visitVarInsn(Opcodes.ISTORE, id);

其中分解为:

代码语言:javascript
复制
/* Error */
public void test()
{
    // Byte code:
    //   0: istore_2
    //   1: istore 4
    //   3: istore 6
    //   5: istore 8
    //   7: return
}

导致这一字节码:

代码语言:javascript
复制
public test() { //()V
    istore2
    istore4
    istore6
    istore8
    return
}

我在这里错过了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-06-21 16:52:00

ISTORE指令将堆栈顶部的值存储到寄存器中。堆栈上没有值,这将导致验证错误。

例如,如果要存储值2,首先需要将值加载到堆栈中:

代码语言:javascript
复制
net.bytebuddy.jar.asm.Type type = getType(symbol.type);
int id = mv.newLocal(type);
mv.visitInsn(Opcodes.ICONST_2);
mv.visitVarInsn(Opcodes.ISTORE, id);

对于“更高”的值,还有其他指令,如BIPUSHSIPUSH。否则,可以使用LDC从常量池加载值。这通常是存储值的最有效的方式;ASM隐式地重复其中的值。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44676210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档