mirror of
https://github.com/FranzHaidnor/haidnorJVM.git
synced 2026-03-13 21:43:42 +08:00
update INVOKEVIRTUAL
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
package haidnor.jvm.instruction.references;
|
||||
|
||||
import haidnor.jvm.classloader.ClassLoader;
|
||||
import haidnor.jvm.core.JavaExecutionEngine;
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.rtda.heap.Instance;
|
||||
import haidnor.jvm.rtda.heap.Klass;
|
||||
import haidnor.jvm.rtda.heap.KlassMethod;
|
||||
import haidnor.jvm.rtda.metaspace.Metaspace;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.runtime.StackValue;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
@@ -76,20 +77,42 @@ public class INVOKEVIRTUAL extends Instruction {
|
||||
}
|
||||
// 调用自定义类的方法
|
||||
else {
|
||||
// 获得栈顶对象实例,根据对象的实际类型进行分派(虚方法分派),支持多态
|
||||
StackValue stackValue = frame.peek();
|
||||
Instance instance = (Instance) stackValue.getValue();
|
||||
Klass meteKlass = instance.klass;
|
||||
JavaClass javaClass = meteKlass.getJavaClass();
|
||||
for (org.apache.bcel.classfile.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));
|
||||
JavaClass javaClass;
|
||||
if (klass != null) {
|
||||
javaClass = klass.getJavaClass();
|
||||
} else {
|
||||
ClassLoader classLoader = frame.getMetaClass().getClassLoader();
|
||||
klass = classLoader.loadClass(className);
|
||||
javaClass = klass.getJavaClass();
|
||||
}
|
||||
|
||||
org.apache.bcel.classfile.Method method = getMethod(javaClass, methodSignature, methodName);
|
||||
if (method == null) {
|
||||
throw new NoSuchMethodException();
|
||||
}
|
||||
KlassMethod klassMethod = new KlassMethod(klass, method);
|
||||
JavaExecutionEngine.callMethod(frame, klassMethod);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归查找方法, 如果子类没有实现方法则向父类查找
|
||||
*/
|
||||
private static org.apache.bcel.classfile.Method getMethod(JavaClass javaClass, String methodSignature,String methodName) throws ClassNotFoundException {
|
||||
org.apache.bcel.classfile.Method m = null;
|
||||
for (org.apache.bcel.classfile.Method method : javaClass.getMethods()) {
|
||||
if (method.getSignature().equals(methodSignature) && method.getName().equals(methodName)) {
|
||||
m = method;
|
||||
}
|
||||
}
|
||||
if (m != null) {
|
||||
return m;
|
||||
}
|
||||
if (javaClass.getSuperClass() == null) {
|
||||
return null;
|
||||
}
|
||||
return getMethod(javaClass.getSuperClass(), methodSignature, methodName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import haidnor.jvm.runtime.JvmThread;
|
||||
import haidnor.jvm.test.demo.Demo1;
|
||||
import haidnor.jvm.test.demo.Demo2;
|
||||
import haidnor.jvm.test.demo.Demo3;
|
||||
import haidnor.jvm.test.demo.Demo4;
|
||||
import haidnor.jvm.test.instruction.Array;
|
||||
import haidnor.jvm.test.instruction.DO_WHILE;
|
||||
import haidnor.jvm.test.instruction.math.ISUB;
|
||||
@@ -51,6 +52,11 @@ public class TestJVM {
|
||||
runMainClass(Demo3.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_4() throws Exception {
|
||||
runMainClass(Demo4.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_NEW() throws Exception {
|
||||
runMainClass(NEW.class);
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
package haidnor.jvm.test.clazz;
|
||||
|
||||
public class Student implements Person {
|
||||
public class Student extends Baby{
|
||||
|
||||
@Override
|
||||
public void eat() {
|
||||
System.out.println("学生只能在学校食堂吃饭");
|
||||
private int age;
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,17 +30,5 @@ class Student {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean equals(Object o) {
|
||||
// Student student = (Student) o;
|
||||
// System.out.println("调用了 equals 方法, 将 age=" + age + " 与 age=" + student.age + " 的对象进行比较");
|
||||
// return age == student.age;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
System.out.println("调用了 hashCode 方法");
|
||||
return 123; // 这个 hashCode() 算法很糟糕, 100% hash冲突
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package haidnor.jvm.test.demo;
|
||||
|
||||
import haidnor.jvm.test.clazz.Student;
|
||||
|
||||
public class Demo4 {
|
||||
|
||||
public static String str = "ABC";
|
||||
|
||||
public static void main(String[] args) {
|
||||
// System.out.println(Demo3.str == Demo4.str); // true
|
||||
Student student = new Student();
|
||||
student.eat();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user