From 05affb1a80b1917afaa2a44555402f7a84f6fce9 Mon Sep 17 00:00:00 2001 From: wangxiang <276644985@qq.com> Date: Fri, 21 Jul 2023 15:01:43 +0800 Subject: [PATCH] =?UTF-8?q?add=20ARETURN=20=E6=94=AF=E6=8C=81=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E5=AF=B9=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jvm/instruction/InstructionFactory.java | 2 +- .../jvm/instruction/control/ARETURN.java | 26 +++++++++++++++++++ .../instruction/references/INVOKESTATIC.java | 23 +++++++++------- .../java/haidnor/jvm/test/clazz/Human.java | 2 ++ .../java/haidnor/jvm/test/clazz/Student.java | 12 ++++++++- .../java/haidnor/jvm/test/demo/Demo3.java | 20 +++----------- .../java/haidnor/jvm/test/demo/Demo4.java | 4 ++- 7 files changed, 60 insertions(+), 29 deletions(-) create mode 100644 src/main/java/haidnor/jvm/instruction/control/ARETURN.java diff --git a/src/main/java/haidnor/jvm/instruction/InstructionFactory.java b/src/main/java/haidnor/jvm/instruction/InstructionFactory.java index 370a4f9..742ebd8 100644 --- a/src/main/java/haidnor/jvm/instruction/InstructionFactory.java +++ b/src/main/java/haidnor/jvm/instruction/InstructionFactory.java @@ -547,7 +547,7 @@ public abstract class InstructionFactory { return new DRETURN(codeStream); } case Const.ARETURN -> { - throw new Error("Not support JavaVM opcode ARETURN"); + return new ARETURN(codeStream); } case Const.RETURN -> { return new RETURN(codeStream); diff --git a/src/main/java/haidnor/jvm/instruction/control/ARETURN.java b/src/main/java/haidnor/jvm/instruction/control/ARETURN.java new file mode 100644 index 0000000..15533cb --- /dev/null +++ b/src/main/java/haidnor/jvm/instruction/control/ARETURN.java @@ -0,0 +1,26 @@ +package haidnor.jvm.instruction.control; + +import haidnor.jvm.instruction.Instruction; +import haidnor.jvm.runtime.Frame; +import haidnor.jvm.runtime.StackValue; +import haidnor.jvm.util.CodeStream; +import haidnor.jvm.util.JvmThreadHolder; + +public class ARETURN extends Instruction { + + public ARETURN(CodeStream codeStream) { + super(codeStream); + } + + @Override + public void execute(Frame frame) { + // 弹出操作数栈中的值 + StackValue stackValue = frame.pop(); + // 将当前栈帧从 jvm 线程栈中弹出 + JvmThreadHolder.get().pop(); + // 将方法返回值压入前一个栈帧的操作数栈中 + Frame topFrame = JvmThreadHolder.get().peek(); + topFrame.push(stackValue); + } + +} diff --git a/src/main/java/haidnor/jvm/instruction/references/INVOKESTATIC.java b/src/main/java/haidnor/jvm/instruction/references/INVOKESTATIC.java index 1dc3857..b7a74c3 100644 --- a/src/main/java/haidnor/jvm/instruction/references/INVOKESTATIC.java +++ b/src/main/java/haidnor/jvm/instruction/references/INVOKESTATIC.java @@ -53,7 +53,7 @@ public class INVOKESTATIC extends Instruction { } } - Class javaClass = Class.forName(Utility.compactClassName(className,false)); + Class javaClass = Class.forName(Utility.compactClassName(className, false)); java.lang.reflect.Method method = javaClass.getMethod(methodName, parameterTypeArr); method.setAccessible(true); Object value = method.invoke(null, stacksValueArr); @@ -63,17 +63,20 @@ public class INVOKESTATIC extends Instruction { } // 自定义类的方法 else { - Klass meteKlass = Metaspace.getJavaClass(Utility.compactClassName(className)); - if (meteKlass != null) { - JavaClass javaClass = meteKlass.getJavaClass(); - for (Method method : javaClass.getMethods()) { - if (method.getSignature().equals(methodSignature) && method.getName().equals(methodName)) { - KlassMethod klassMethod = new KlassMethod(meteKlass, method); - JavaExecutionEngine.callMethod(frame, klassMethod); - break; - } + Klass klass = Metaspace.getJavaClass(Utility.compactClassName(className)); + // 调用静态方法时加载类 + if (klass == null) { + klass = frame.getMetaClass().getClassLoader().loadClass(className); + } + JavaClass javaClass = klass.getJavaClass(); + for (Method method : javaClass.getMethods()) { + if (method.getSignature().equals(methodSignature) && method.getName().equals(methodName)) { + KlassMethod klassMethod = new KlassMethod(klass, method); + JavaExecutionEngine.callMethod(frame, klassMethod); + break; } } + } } diff --git a/src/test/java/haidnor/jvm/test/clazz/Human.java b/src/test/java/haidnor/jvm/test/clazz/Human.java index 301fe8e..f2473d8 100644 --- a/src/test/java/haidnor/jvm/test/clazz/Human.java +++ b/src/test/java/haidnor/jvm/test/clazz/Human.java @@ -1,7 +1,9 @@ package haidnor.jvm.test.clazz; public class Human { + public void eat() { System.out.println("人类吃饭"); } + } diff --git a/src/test/java/haidnor/jvm/test/clazz/Student.java b/src/test/java/haidnor/jvm/test/clazz/Student.java index e14ad91..3a1ef4b 100644 --- a/src/test/java/haidnor/jvm/test/clazz/Student.java +++ b/src/test/java/haidnor/jvm/test/clazz/Student.java @@ -2,6 +2,16 @@ package haidnor.jvm.test.clazz; public class Student extends Human { - public static String name = "张三"; + public static String school = "家里蹲大学"; + + public String name; + + public void printSchool() { + System.out.println(school); + } + + public static Student newStudent() { + return new Student(); + } } diff --git a/src/test/java/haidnor/jvm/test/demo/Demo3.java b/src/test/java/haidnor/jvm/test/demo/Demo3.java index 70aa83f..69ef2a0 100644 --- a/src/test/java/haidnor/jvm/test/demo/Demo3.java +++ b/src/test/java/haidnor/jvm/test/demo/Demo3.java @@ -1,16 +1,14 @@ package haidnor.jvm.test.demo; +import haidnor.jvm.test.clazz.Student; + import java.util.HashMap; public class Demo3 { public static void main(String[] args) { - Student sut1 = new Student(1); - Student sut2 = new Student(2); - - if (sut1 == sut2) { - - } + Student sut1 = new Student(); + Student sut2 = new Student(); HashMap hashMap = new HashMap<>(); hashMap.put(sut1, "张三"); @@ -22,13 +20,3 @@ public class Demo3 { } -class Student { - - public int age; - - public Student(int age) { - this.age = age; - } - - -} diff --git a/src/test/java/haidnor/jvm/test/demo/Demo4.java b/src/test/java/haidnor/jvm/test/demo/Demo4.java index c5255ce..5e72150 100644 --- a/src/test/java/haidnor/jvm/test/demo/Demo4.java +++ b/src/test/java/haidnor/jvm/test/demo/Demo4.java @@ -5,8 +5,10 @@ import haidnor.jvm.test.clazz.Student; public class Demo4 { public static void main(String[] args) { - Student student = new Student(); + Student student = Student.newStudent(); student.eat(); + student.name = "张三"; + System.out.println(student.name); } }