美文网首页
60 - ASM之opcode: return

60 - ASM之opcode: return

作者: 舍是境界 | 来源:发表于2022-03-17 07:18 被阅读0次

    从Instruction的角度来说,与return相关的opcode有6个,内容如下:

    opcode mnemonic symbol
    172 ireturn
    174 freturn
    176 areturn
    173 lreturn
    175 dreturn
    177 return

    从ASM的角度来说,这些opcode是通过MethodVisitor.visitInsn(int opcode)方法来调用的。

    return void type

    从Java语言的视角,有一个HelloWorld类,代码如下:

    public class HelloWorld {
        public void test() {
            // do nothing
        }
    }
    

    从Instruction的视角来看,方法体对应的内容如下:

    $ javap -c sample.HelloWorld
    Compiled from "HelloWorld.java"
    public class sample.HelloWorld {
    ...
      public void test();
        Code:
           0: return
    }
    

    从ASM的视角来看,方法体对应的内容如下:

    methodVisitor.visitCode();
    methodVisitor.visitInsn(RETURN);
    methodVisitor.visitMaxs(0, 1);
    methodVisitor.visitEnd();
    

    从Frame的视角来看,local variable和operand stack的变化:

                                   // {this} | {}
    0000: return                   // {} | {}
    

    从JVM规范的角度来看,Operand Stack的变化如下:

    ... →
    
    [empty]
    

    The current method must have return type void.

    • If no exception is thrown, any values on the operand stack of the current frame are discarded.
    • The interpreter then returns control to the invoker of the method, reinstating the frame of the invoker.

    return primitive type

    从Java语言的视角,有一个HelloWorld类,代码如下:

    public class HelloWorld {
        public int test() {
            return 0;
        }
    }
    

    从Instruction的视角来看,方法体对应的内容如下:

    $ javap -c sample.HelloWorld
    Compiled from "HelloWorld.java"
    public class sample.HelloWorld {
    ...
      public int test();
        Code:
           0: iconst_0
           1: ireturn
    }
    

    从ASM的视角来看,方法体对应的内容如下:

    methodVisitor.visitCode();
    methodVisitor.visitInsn(ICONST_0);
    methodVisitor.visitInsn(IRETURN);
    methodVisitor.visitMaxs(1, 1);
    methodVisitor.visitEnd();
    

    从Frame的视角来看,local variable和operand stack的变化:

                                   // {this} | {}
    0000: iconst_0                 // {this} | {int}
    0001: ireturn                  // {} | {}
    

    从JVM规范的角度来看,Operand Stack的变化如下:

    ..., value →
    
    [empty]
    
    • The current method must have return type boolean, byte, short, char, or int. The value must be of type int.
    • If no exception is thrown, value is popped from the operand stack of the current frame and pushed onto the operand stack of the frame of the invoker.
    • Any other values on the operand stack of the current method are discarded.
      The interpreter then returns control to the invoker of the method, reinstating the frame of the invoker.

    freturn

    从Java语言的视角,有一个HelloWorld类,代码如下:

    public class HelloWorld {
        public float test() {
            return 0;
        }
    }
    

    从Instruction的视角来看,方法体对应的内容如下:

    $ javap -c sample.HelloWorld
    Compiled from "HelloWorld.java"
    public class sample.HelloWorld {
    ...
      public float test();
        Code:
           0: fconst_0
           1: freturn
    }
    

    从ASM的视角来看,方法体对应的内容如下:

    methodVisitor.visitCode();
    methodVisitor.visitInsn(FCONST_0);
    methodVisitor.visitInsn(FRETURN);
    methodVisitor.visitMaxs(1, 1);
    methodVisitor.visitEnd();
    

    从Frame的视角来看,local variable和operand stack的变化:

                                   // {this} | {}
    0000: fconst_0                 // {this} | {float}
    0001: freturn                  // {} | {}
    

    从JVM规范的角度来看,Operand Stack的变化如下:

    ..., value →
    
    [empty]
    
    • The current method must have return type float. The value must be of type float.
    • If no exception is thrown, value is popped from the operand stack of the current frame. The value is pushed onto the operand stack of the frame of the invoker.
    • Any other values on the operand stack of the current method are discarded.
      The interpreter then returns control to the invoker of the method, reinstating the frame of the invoker.

    lreturn

    这里需要注意的就是long类型在local variable和operand stack当中占用2个slot的位置。

    从Java语言的视角,有一个HelloWorld类,代码如下:

    public class HelloWorld {
        public long test() {
            return 0;
        }
    }
    

    从Instruction的视角来看,方法体对应的内容如下:

    $ javap -c sample.HelloWorld
    Compiled from "HelloWorld.java"
    public class sample.HelloWorld {
    ...
      public long test();
        Code:
           0: lconst_0
           1: lreturn
    }
    

    从ASM的视角来看,方法体对应的内容如下:

    methodVisitor.visitCode();
    methodVisitor.visitInsn(LCONST_0);
    methodVisitor.visitInsn(LRETURN);
    methodVisitor.visitMaxs(2, 1);
    methodVisitor.visitEnd();
    

    从Frame的视角来看,local variable和operand stack的变化:

    ..., value →
    
    [empty]
    
    • The current method must have return type long. The value must be of type long.
    • If no exception is thrown, value is popped from the operand stack of the current frame and pushed onto the operand stack of the frame of the invoker.
    • Any other values on the operand stack of the current method are discarded.
    • The interpreter then returns control to the invoker of the method, reinstating the frame of the invoker.

    dreturn

    从Java语言的视角,有一个HelloWorld类,代码如下:

    public class HelloWorld {
        public double test() {
            return 0;
        }
    }
    

    从Instruction的视角来看,方法体对应的内容如下:

    $ javap -c sample.HelloWorld
    Compiled from "HelloWorld.java"
    public class sample.HelloWorld {
    ...
      public double test();
        Code:
           0: dconst_0
           1: dreturn
    }
    

    从ASM的视角来看,方法体对应的内容如下:

    methodVisitor.visitCode();
    methodVisitor.visitInsn(DCONST_0);
    methodVisitor.visitInsn(DRETURN);
    methodVisitor.visitMaxs(2, 1);
    methodVisitor.visitEnd();
    

    从Frame的视角来看,local variable和operand stack的变化:

                                   // {this} | {}
    0000: dconst_0                 // {this} | {double, top}
    0001: dreturn                  // {} | {}
    

    从JVM规范的角度来看,Operand Stack的变化如下:

    ..., value →
    
    [empty]
    
    • The current method must have return type double. The value must be of type double.
    • If no exception is thrown, value is popped from the operand stack of the current frame. The value is pushed onto the operand stack of the frame of the invoker.
    • Any other values on the operand stack of the current method are discarded.
    • The interpreter then returns control to the invoker of the method, reinstating the frame of the invoker.

    return reference type

    从Java语言的视角,有一个HelloWorld类,代码如下:

    public class HelloWorld {
        public Object test() {
            return null;
        }
    }
    

    从Instruction的视角来看,方法体对应的内容如下:

    $ javap -c sample.HelloWorld
    Compiled from "HelloWorld.java"
    public class sample.HelloWorld {
    ...
      public java.lang.Object test();
        Code:
           0: aconst_null
           1: areturn
    }
    

    从ASM的视角来看,方法体对应的内容如下:

    methodVisitor.visitCode();
    methodVisitor.visitInsn(ACONST_NULL);
    methodVisitor.visitInsn(ARETURN);
    methodVisitor.visitMaxs(1, 1);
    methodVisitor.visitEnd();
    

    从Frame的视角来看,local variable和operand stack的变化:

                                  // {this} | {}
    0000: aconst_null              // {this} | {null}
    0001: areturn                  // {} | {}
    

    从JVM规范的角度来看,Operand Stack的变化如下:

    ..., objectref →
    
    [empty]
    
    • The objectref must be of type reference and must refer to an object of a type that is assignment compatible with the type represented by the return descriptor of the current method.
    • If no exception is thrown, objectref is popped from the operand stack of the current frame and pushed onto the operand stack of the frame of the invoker.
    • Any other values on the operand stack of the current method are discarded.
    • The interpreter then reinstates the frame of the invoker and returns control to the invoker.

    相关文章

      网友评论

          本文标题:60 - ASM之opcode: return

          本文链接:https://www.haomeiwen.com/subject/qfvqdrtx.html