update INSTANCEOF

This commit is contained in:
wangxiang
2023-07-26 10:46:08 +08:00
parent f5e2af2909
commit 5bbc904cd1
10 changed files with 46 additions and 33 deletions

View File

@@ -112,7 +112,7 @@ public class JavaExecutionEngine {
frame.push(new StackValue(Const.T_OBJECT, exception)); frame.push(new StackValue(Const.T_OBJECT, exception));
handlerPC = codeException.getHandlerPC(); handlerPC = codeException.getHandlerPC();
} else { } else {
String exceptionClassName = frame.getConstantPoolUtil().getConstantClassClassName(catchType); String exceptionClassName = frame.getConstantPoolUtil().constantClass_ClassName(catchType);
exceptionClassName = Utility.compactClassName(exceptionClassName, false); exceptionClassName = Utility.compactClassName(exceptionClassName, false);
Class<?> exceptionClass = Class.forName(exceptionClassName); Class<?> exceptionClass = Class.forName(exceptionClassName);
if (exceptionClass.isAssignableFrom(exception.getClass())) { if (exceptionClass.isAssignableFrom(exception.getClass())) {

View File

@@ -8,11 +8,8 @@ import haidnor.jvm.rtda.Metaspace;
import haidnor.jvm.runtime.Frame; import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue; import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream; import haidnor.jvm.util.CodeStream;
import haidnor.jvm.util.ConstantPoolUtil;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.apache.bcel.Const; import org.apache.bcel.Const;
import org.apache.bcel.classfile.ConstantClass;
import org.apache.bcel.classfile.ConstantPool;
import org.apache.bcel.classfile.Utility; import org.apache.bcel.classfile.Utility;
public class ANEWARRAY extends Instruction { public class ANEWARRAY extends Instruction {
@@ -27,10 +24,7 @@ public class ANEWARRAY extends Instruction {
@Override @Override
@SneakyThrows @SneakyThrows
public void execute(Frame frame) { public void execute(Frame frame) {
ConstantPool constantPool = frame.getConstantPool(); String className = frame.getConstantPoolUtil().constantClass_ClassName(constantClassIndex);
ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil();
ConstantClass constantClass = constantPool.getConstant(constantClassIndex);
String className = constantPoolUtil.getConstantClassClassName(constantClass);
Klass klass = Metaspace.getJavaClass(Utility.compactClassName(className)); Klass klass = Metaspace.getJavaClass(Utility.compactClassName(className));
if (klass == null) { if (klass == null) {

View File

@@ -37,7 +37,7 @@ public class GETSTATIC extends Instruction {
ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil(); ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil();
ConstantFieldref constFieldref = constantPool.getConstant(constantFieldrefIndex); ConstantFieldref constFieldref = constantPool.getConstant(constantFieldrefIndex);
// 动态链接. 找到字段所属的 Java 类 // 动态链接. 找到字段所属的 Java 类
String className = constantPoolUtil.getFiledBelongClassName(constFieldref); String className = constantPoolUtil.constantFieldref_ClassName(constFieldref);
// 动态链接. 找到字段的名字 // 动态链接. 找到字段的名字
String fieldName = constantPoolUtil.getFieldName(constFieldref); String fieldName = constantPoolUtil.getFieldName(constFieldref);
// 以上代码体现了动态链接.Class文件的常量池中存有大量的符号引用,字节码中的方法调用指令就以常量池里指向方法的符号引用作为参数. // 以上代码体现了动态链接.Class文件的常量池中存有大量的符号引用,字节码中的方法调用指令就以常量池里指向方法的符号引用作为参数.

View File

@@ -8,8 +8,7 @@ import haidnor.jvm.util.CodeStream;
import haidnor.jvm.util.ConstantPoolUtil; import haidnor.jvm.util.ConstantPoolUtil;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.apache.bcel.Const; import org.apache.bcel.Const;
import org.apache.bcel.classfile.ConstantClass; import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.ConstantPool;
import org.apache.bcel.classfile.Utility; import org.apache.bcel.classfile.Utility;
/** /**
@@ -27,10 +26,9 @@ public class INSTANCEOF extends Instruction {
@Override @Override
@SneakyThrows @SneakyThrows
public void execute(Frame frame) { public void execute(Frame frame) {
ConstantPool constantPool = frame.getConstantPool();
ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil(); ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil();
ConstantClass constantClass = constantPool.getConstant(constantClassIndex);
String className = constantPoolUtil.getConstantClassClassName(constantClass); String className = constantPoolUtil.constantClass_ClassName(constantClassIndex);
className = Utility.compactClassName(className); className = Utility.compactClassName(className);
StackValue stackValue = frame.pop(); StackValue stackValue = frame.pop();
@@ -38,14 +36,17 @@ public class INSTANCEOF extends Instruction {
Class<?> objClass = obj.getClass(); Class<?> objClass = obj.getClass();
if (obj instanceof Instance instance) { if (obj instanceof Instance instance) {
String instanceClassName = instance.klass.getClassName(); boolean result = findClassFromSuper(instance.klass.getJavaClass(), className);
if (instanceClassName.equals(className)) { if (!result) {
result = findClassFromInterface(instance.klass.getJavaClass(), className);
}
if (result) {
frame.push(new StackValue(Const.T_INT, 1)); frame.push(new StackValue(Const.T_INT, 1));
} else { } else {
frame.push(new StackValue(Const.T_INT, 0)); frame.push(new StackValue(Const.T_INT, 0));
} }
} else { } else {
if (objClass.getName().equals(className)) { if (Class.forName(className).isAssignableFrom(objClass)) {
frame.push(new StackValue(Const.T_INT, 1)); frame.push(new StackValue(Const.T_INT, 1));
} else { } else {
frame.push(new StackValue(Const.T_INT, 0)); frame.push(new StackValue(Const.T_INT, 0));
@@ -53,4 +54,25 @@ public class INSTANCEOF extends Instruction {
} }
} }
public boolean findClassFromSuper(JavaClass javaClass, String className) throws ClassNotFoundException {
if (javaClass.getClassName().equals(className)) {
return true;
}
for (JavaClass superClass : javaClass.getSuperClasses()) {
if (superClass.getClassName().equals(className)) {
return true;
}
}
return false;
}
public boolean findClassFromInterface(JavaClass javaClass, String className) throws ClassNotFoundException {
for (JavaClass anInterface : javaClass.getInterfaces()) {
if (anInterface.getClassName().equals(className)) {
return true;
}
}
return false;
}
} }

View File

@@ -47,7 +47,7 @@ public class INVOKEINTERFACE extends Instruction {
ConstantInterfaceMethodref interfaceMethodref = constantPool.getConstant(constantMethodrefIndex); ConstantInterfaceMethodref interfaceMethodref = constantPool.getConstant(constantMethodrefIndex);
int classIndex = interfaceMethodref.getClassIndex(); int classIndex = interfaceMethodref.getClassIndex();
String interfaceName = constantPoolUtil.getConstantClassClassName(classIndex); String interfaceName = constantPoolUtil.constantClass_ClassName(classIndex);
int nameAndTypeIndex = interfaceMethodref.getNameAndTypeIndex(); int nameAndTypeIndex = interfaceMethodref.getNameAndTypeIndex();
String methodName = constantPoolUtil.constantNameAndType_name(nameAndTypeIndex); String methodName = constantPoolUtil.constantNameAndType_name(nameAndTypeIndex);

View File

@@ -10,8 +10,6 @@ import haidnor.jvm.util.CodeStream;
import haidnor.jvm.util.ConstantPoolUtil; import haidnor.jvm.util.ConstantPoolUtil;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.apache.bcel.Const; import org.apache.bcel.Const;
import org.apache.bcel.classfile.ConstantClass;
import org.apache.bcel.classfile.ConstantPool;
import org.apache.bcel.classfile.Utility; import org.apache.bcel.classfile.Utility;
public class NEW extends Instruction { public class NEW extends Instruction {
@@ -26,10 +24,8 @@ public class NEW extends Instruction {
@Override @Override
@SneakyThrows @SneakyThrows
public void execute(Frame frame) { public void execute(Frame frame) {
ConstantPool constantPool = frame.getConstantPool();
ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil(); ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil();
ConstantClass constantClass = constantPool.getConstant(constantClassIndex); String className = constantPoolUtil.constantClass_ClassName(constantClassIndex);
String className = constantPoolUtil.getConstantClassClassName(constantClass);
if (className.startsWith("java/")) { if (className.startsWith("java/")) {
frame.push(new StackValue(Const.T_OBJECT, null)); frame.push(new StackValue(Const.T_OBJECT, null));

View File

@@ -31,7 +31,7 @@ public class PUTSTATIC extends Instruction {
ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil(); ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil();
ConstantFieldref constFieldref = constantPool.getConstant(constantFieldrefIndex); ConstantFieldref constFieldref = constantPool.getConstant(constantFieldrefIndex);
// 动态链接. 找到字段所属的 Java 类 // 动态链接. 找到字段所属的 Java 类
String className = constantPoolUtil.getFiledBelongClassName(constFieldref); String className = constantPoolUtil.constantFieldref_ClassName(constFieldref);
// 动态链接. 找到字段的名字 // 动态链接. 找到字段的名字
String fieldName = constantPoolUtil.getFieldName(constFieldref); String fieldName = constantPoolUtil.getFieldName(constFieldref);
// 以上代码体现了动态链接.Class文件的常量池中存有大量的符号引用,字节码中的方法调用指令就以常量池里指向方法的符号引用作为参数. // 以上代码体现了动态链接.Class文件的常量池中存有大量的符号引用,字节码中的方法调用指令就以常量池里指向方法的符号引用作为参数.

View File

@@ -42,7 +42,7 @@ public class ConstantPoolUtil {
/** /**
* 获取长类名, 例如 java/lang/String * 获取长类名, 例如 java/lang/String
*/ */
public String getConstantClassClassName(final ConstantClass constantClass) { public String constantClass_ClassName(final ConstantClass constantClass) {
ConstantUtf8 constantUtf8 = cp.getConstant(constantClass.getNameIndex()); ConstantUtf8 constantUtf8 = cp.getConstant(constantClass.getNameIndex());
return constantUtf8.getBytes(); return constantUtf8.getBytes();
} }
@@ -50,9 +50,9 @@ public class ConstantPoolUtil {
/** /**
* 获取长类名, 例如 java/lang/String * 获取长类名, 例如 java/lang/String
*/ */
public String getConstantClassClassName(int constantClassIndex) { public String constantClass_ClassName(int constantClassIndex) {
ConstantClass constantClass = cp.getConstant(constantClassIndex); ConstantClass constantClass = cp.getConstant(constantClassIndex);
return getConstantClassClassName(constantClass); return constantClass_ClassName(constantClass);
} }
@@ -61,7 +61,7 @@ public class ConstantPoolUtil {
/** /**
* 获取字段所处于Java类的类名, 例如 java/lang/String * 获取字段所处于Java类的类名, 例如 java/lang/String
*/ */
public String getFiledBelongClassName(final ConstantFieldref constantFieldref) { public String constantFieldref_ClassName(final ConstantFieldref constantFieldref) {
ConstantClass constClass = cp.getConstant(constantFieldref.getClassIndex()); ConstantClass constClass = cp.getConstant(constantFieldref.getClassIndex());
return (String) constClass.getConstantValue(cp); return (String) constClass.getConstantValue(cp);
} }
@@ -69,9 +69,9 @@ public class ConstantPoolUtil {
/** /**
* 获取字段所处于Java类的类名, 例如 java/lang/String * 获取字段所处于Java类的类名, 例如 java/lang/String
*/ */
public String getFiledBelongClassName(int constantFieldrefIndex) { public String constantFieldref_ClassName(int constantFieldrefIndex) {
ConstantFieldref constantFieldref = getConstantFieldref(constantFieldrefIndex); ConstantFieldref constantFieldref = getConstantFieldref(constantFieldrefIndex);
return getFiledBelongClassName(constantFieldref); return constantFieldref_ClassName(constantFieldref);
} }
/** /**

View File

@@ -1,6 +1,6 @@
package haidnor.jvm.test.clazz; package haidnor.jvm.test.clazz;
public class Student implements Organism { public class Student extends Human implements Organism {
public void method1() { public void method1() {
System.out.println("method1"); System.out.println("method1");

View File

@@ -1,14 +1,15 @@
package haidnor.jvm.test.demo; package haidnor.jvm.test.demo;
import haidnor.jvm.test.clazz.Human;
import haidnor.jvm.test.clazz.Student; import haidnor.jvm.test.clazz.Student;
public class Demo6 { public class Demo6 {
public static void main(String[] args) { public static void main(String[] args) {
Student student = new Student(); Student student = new Student();
if (student instanceof Student) { if (student instanceof Human) {
System.out.println("instanceof"); System.out.println("true");
} }
} }