diff --git a/src/main/java/haidnor/jvm/instruction/references/INVOKESPECIAL.java b/src/main/java/haidnor/jvm/instruction/references/INVOKESPECIAL.java index 5ecf266..80996fa 100644 --- a/src/main/java/haidnor/jvm/instruction/references/INVOKESPECIAL.java +++ b/src/main/java/haidnor/jvm/instruction/references/INVOKESPECIAL.java @@ -34,9 +34,9 @@ public class INVOKESPECIAL extends Instruction { ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil(); ConstantMethodref methodref = constantPool.getConstant(constantMethodrefIndex); - String className = constantPoolUtil.getBelongClassName(methodref); - String methodName = constantPoolUtil.getMethodName(methodref); - String methodSignature = constantPoolUtil.getMethodSignature(methodref); + String className = constantPoolUtil.constantMethodref_ClassName(methodref); + String methodName = constantPoolUtil.constantMethodref_MethodName(methodref); + String methodSignature = constantPoolUtil.constantMethodref_MethodSignature(methodref); Klass klass = Metaspace.getJavaClass(Utility.compactClassName(className)); JavaClass javaClass; diff --git a/src/main/java/haidnor/jvm/instruction/references/INVOKESTATIC.java b/src/main/java/haidnor/jvm/instruction/references/INVOKESTATIC.java index 285ee12..f766e19 100644 --- a/src/main/java/haidnor/jvm/instruction/references/INVOKESTATIC.java +++ b/src/main/java/haidnor/jvm/instruction/references/INVOKESTATIC.java @@ -21,11 +21,11 @@ import java.util.Objects; */ public class INVOKESTATIC extends Instruction { - private final int constantMethodrefIndex; + private final int constantIndex; public INVOKESTATIC(CodeStream codeStream) { super(codeStream); - this.constantMethodrefIndex = codeStream.readUnsignedShort(this); + this.constantIndex = codeStream.readUnsignedShort(this); } @Override @@ -34,10 +34,23 @@ public class INVOKESTATIC extends Instruction { ConstantPool constantPool = frame.getConstantPool(); ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil(); - ConstantMethodref methodref = constantPool.getConstant(constantMethodrefIndex); - String className = constantPoolUtil.getBelongClassName(methodref); - String methodName = constantPoolUtil.getMethodName(methodref); - String methodSignature = constantPoolUtil.getMethodSignature(methodref); + String className; + String methodName; + String methodSignature; + + Constant constant = constantPool.getConstant(constantIndex); + if (constant instanceof ConstantMethodref constantMethodref) { + className = constantPoolUtil.constantMethodref_ClassName(constantMethodref); + methodName = constantPoolUtil.constantMethodref_MethodName(constantMethodref); + methodSignature = constantPoolUtil.constantMethodref_MethodSignature(constantMethodref); + + } else if (constant instanceof ConstantInterfaceMethodref interfaceMethodref) { + className = constantPoolUtil.constantInterfaceMethodref_ClassName(interfaceMethodref); + methodName = constantPoolUtil.constantInterfaceMethodref_MethodName(interfaceMethodref); + methodSignature = constantPoolUtil.constantInterfaceMethodref_MethodSignature(interfaceMethodref); + } else { + throw new ClassCastException(); + } // 系统类反射 自定义类另外处理 if (className.startsWith("java/")) { diff --git a/src/main/java/haidnor/jvm/instruction/references/INVOKEVIRTUAL.java b/src/main/java/haidnor/jvm/instruction/references/INVOKEVIRTUAL.java index d1a5e18..23d58ee 100644 --- a/src/main/java/haidnor/jvm/instruction/references/INVOKEVIRTUAL.java +++ b/src/main/java/haidnor/jvm/instruction/references/INVOKEVIRTUAL.java @@ -41,9 +41,9 @@ public class INVOKEVIRTUAL extends Instruction { ConstantMethodref methodref = constantPool.getConstant(constantMethodrefIndex); - String className = constantPoolUtil.getBelongClassName(methodref); - String methodName = constantPoolUtil.getMethodName(methodref); - String methodSignature = constantPoolUtil.getMethodSignature(methodref); + String className = constantPoolUtil.constantMethodref_ClassName(methodref); + String methodName = constantPoolUtil.constantMethodref_MethodName(methodref); + String methodSignature = constantPoolUtil.constantMethodref_MethodSignature(methodref); // 系统类反射 自定义类另外处理 if (className.startsWith("java/")) { diff --git a/src/main/java/haidnor/jvm/util/ConstantPoolUtil.java b/src/main/java/haidnor/jvm/util/ConstantPoolUtil.java index f6e6789..d4c5b2e 100644 --- a/src/main/java/haidnor/jvm/util/ConstantPoolUtil.java +++ b/src/main/java/haidnor/jvm/util/ConstantPoolUtil.java @@ -112,7 +112,7 @@ public class ConstantPoolUtil { * 获取方法所处于Java类的类名 * 名称使用/分割,例如 haidnor/jvm/test/instruction/references/NEW */ - public String getBelongClassName(final ConstantMethodref methodref) { + public String constantMethodref_ClassName(final ConstantMethodref methodref) { ConstantClass constClass = cp.getConstant(methodref.getClassIndex()); return (String) constClass.getConstantValue(cp); } @@ -120,7 +120,7 @@ public class ConstantPoolUtil { /** * 获取方法名 */ - public String getMethodName(final ConstantMethodref methodref) { + public String constantMethodref_MethodName(final ConstantMethodref methodref) { ConstantNameAndType constNameAndType = cp.getConstant(methodref.getNameAndTypeIndex()); return constNameAndType.getName(cp); } @@ -128,11 +128,35 @@ public class ConstantPoolUtil { /** * 获取方法签名 */ - public String getMethodSignature(final ConstantMethodref methodref) { + public String constantMethodref_MethodSignature(final ConstantMethodref methodref) { ConstantNameAndType constNameAndType = cp.getConstant(methodref.getNameAndTypeIndex()); return constNameAndType.getSignature(cp); } + // ConstantInterfaceMethodref ----------------------------------------------------------------------------------------------- + + public String constantInterfaceMethodref_ClassName(final ConstantInterfaceMethodref methodref) { + ConstantClass constClass = cp.getConstant(methodref.getClassIndex()); + return (String) constClass.getConstantValue(cp); + } + + /** + * 获取方法名 + */ + public String constantInterfaceMethodref_MethodName(final ConstantInterfaceMethodref methodref) { + ConstantNameAndType constNameAndType = cp.getConstant(methodref.getNameAndTypeIndex()); + return constNameAndType.getName(cp); + } + + /** + * 获取方法签名 + */ + public String constantInterfaceMethodref_MethodSignature(final ConstantInterfaceMethodref methodref) { + ConstantNameAndType constNameAndType = cp.getConstant(methodref.getNameAndTypeIndex()); + return constNameAndType.getSignature(cp); + } + + // ConstantNameAndType ----------------------------------------------------------------------------------------------- /** diff --git a/src/test/java/haidnor/jvm/test/TestJVM.java b/src/test/java/haidnor/jvm/test/TestJVM.java index 6f0c209..b5ff6ed 100644 --- a/src/test/java/haidnor/jvm/test/TestJVM.java +++ b/src/test/java/haidnor/jvm/test/TestJVM.java @@ -92,11 +92,22 @@ public class TestJVM { runMainClass(demo_foreach.class); } + /** + * --add-opens java.base/java.util=ALL-UNNAMED + */ @Test public void demo_foreach_2() throws Exception { runMainClass(demo_foreach_2.class); } + /** + * --add-opens java.base/java.util=ALL-UNNAMED + */ + @Test + public void demo_foreach_3() throws Exception { + runMainClass(demo_foreach_3.class); + } + @Test public void test_8() throws Exception { runMainClass(Demo8.class); diff --git a/src/test/java/haidnor/jvm/test/demo/demo_foreach_3.java b/src/test/java/haidnor/jvm/test/demo/demo_foreach_3.java new file mode 100644 index 0000000..08742cf --- /dev/null +++ b/src/test/java/haidnor/jvm/test/demo/demo_foreach_3.java @@ -0,0 +1,18 @@ +package haidnor.jvm.test.demo; + +import java.util.List; + +/** + * 需要添加启动参数 + * --add-opens java.base/java.util=ALL-UNNAMED + */ +public class demo_foreach_3 { + + public static void main(String[] args) { + List list = List.of(1, 2, 3, 4, 5); + for (Integer integer : list) { + System.out.println(integer); + } + } + +}