mirror of
https://github.com/FranzHaidnor/haidnorJVM.git
synced 2026-03-29 10:13:42 +08:00
update
This commit is contained in:
@@ -117,4 +117,13 @@ public final class ConstantClass extends Constant implements ConstantObject {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString() + "(nameIndex = " + nameIndex + ")";
|
return super.toString() + "(nameIndex = " + nameIndex + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取长类名, 例如 java/lang/String
|
||||||
|
*/
|
||||||
|
public String getClassName() {
|
||||||
|
ConstantUtf8 constantUtf8 = constantPool.getConstant(getNameIndex());
|
||||||
|
return constantUtf8.getBytes();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,4 +63,29 @@ public final class ConstantFieldref extends ConstantCP {
|
|||||||
public void accept(final Visitor v) {
|
public void accept(final Visitor v) {
|
||||||
v.visitConstantFieldref(this);
|
v.visitConstantFieldref(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取字段所处于Java类的类名, 例如 java/lang/String
|
||||||
|
*/
|
||||||
|
public String getBelongClassName() {
|
||||||
|
ConstantClass constClass = constantPool.getConstant(getClassIndex());
|
||||||
|
return (String) constClass.getConstantValue(constantPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取字段名称
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
ConstantNameAndType constNameAndType = constantPool.getConstant(getNameAndTypeIndex());
|
||||||
|
return constNameAndType.getName(constantPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取字段类型签名
|
||||||
|
*/
|
||||||
|
public String getSignature() {
|
||||||
|
ConstantNameAndType constNameAndType = constantPool.getConstant(getNameAndTypeIndex());
|
||||||
|
return constNameAndType.getSignature(constantPool);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package haidnor.jvm.bcel.classfile;
|
package haidnor.jvm.bcel.classfile;
|
||||||
|
|
||||||
import haidnor.jvm.bcel.Const;
|
import haidnor.jvm.bcel.Const;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
import java.io.DataInput;
|
import java.io.DataInput;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -63,4 +64,49 @@ public final class ConstantInterfaceMethodref extends ConstantCP {
|
|||||||
public void accept(final Visitor v) {
|
public void accept(final Visitor v) {
|
||||||
v.visitConstantInterfaceMethodref(this);
|
v.visitConstantInterfaceMethodref(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getClassName() {
|
||||||
|
ConstantClass constClass = constantPool.getConstant(getClassIndex());
|
||||||
|
return (String) constClass.getConstantValue(constantPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMethodName() {
|
||||||
|
ConstantNameAndType constNameAndType = constantPool.getConstant(getNameAndTypeIndex());
|
||||||
|
return constNameAndType.getName(constantPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMethodSignature() {
|
||||||
|
ConstantNameAndType constNameAndType = constantPool.getConstant(getNameAndTypeIndex());
|
||||||
|
return constNameAndType.getSignature(constantPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReturnType() {
|
||||||
|
return Utility.methodSignatureReturnType(getMethodSignature(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析方法签名返回方法参数类型数组
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
public Class<?>[] getParameterTypeArr() {
|
||||||
|
String[] argumentTypeArr = Utility.methodSignatureArgumentTypes(getMethodSignature(), false);
|
||||||
|
Class<?>[] argumentClassArr = new Class[argumentTypeArr.length];
|
||||||
|
for (int i = 0; i < argumentTypeArr.length; i++) {
|
||||||
|
Class<?> argumentClass;
|
||||||
|
String argumentType = argumentTypeArr[i];
|
||||||
|
argumentClass = switch (argumentType) {
|
||||||
|
case "byte" -> byte.class;
|
||||||
|
case "short" -> short.class;
|
||||||
|
case "boolean" -> boolean.class;
|
||||||
|
case "char" -> char.class;
|
||||||
|
case "int" -> int.class;
|
||||||
|
case "long" -> long.class;
|
||||||
|
case "float" -> float.class;
|
||||||
|
case "double" -> double.class;
|
||||||
|
default -> Class.forName(argumentType);
|
||||||
|
};
|
||||||
|
argumentClassArr[i] = argumentClass;
|
||||||
|
}
|
||||||
|
return argumentClassArr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -434,163 +434,4 @@ public class ConstantPool implements Cloneable, Node, Iterable<Constant> {
|
|||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------- haidnorJVM
|
|
||||||
|
|
||||||
public ConstantFieldref getConstantFieldref(int constantFieldrefIndex) {
|
|
||||||
return getConstant(constantFieldrefIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConstantMethodref getConstantMethodref(int constantMethodrefIndex) {
|
|
||||||
return getConstant(constantMethodrefIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConstantClass getConstantClass(int constantClassIndex) {
|
|
||||||
return getConstant(constantClassIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConstantNameAndType getConstantNameAndType(int constantNameAndTypeIndex) {
|
|
||||||
return getConstant(constantNameAndTypeIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ConstantClass ---------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取长类名, 例如 java/lang/String
|
|
||||||
*/
|
|
||||||
public String constantClass_ClassName(final ConstantClass constantClass) {
|
|
||||||
ConstantUtf8 constantUtf8 = getConstant(constantClass.getNameIndex());
|
|
||||||
return constantUtf8.getBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取长类名, 例如 java/lang/String
|
|
||||||
*/
|
|
||||||
public String constantClass_ClassName(int constantClassIndex) {
|
|
||||||
ConstantClass constantClass = getConstant(constantClassIndex);
|
|
||||||
return constantClass_ClassName(constantClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ConstantFieldref ------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取字段所处于Java类的类名, 例如 java/lang/String
|
|
||||||
*/
|
|
||||||
public String constantFieldref_ClassName(final ConstantFieldref constantFieldref) {
|
|
||||||
ConstantClass constClass = getConstant(constantFieldref.getClassIndex());
|
|
||||||
return (String) constClass.getConstantValue(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取字段所处于Java类的类名, 例如 java/lang/String
|
|
||||||
*/
|
|
||||||
public String constantFieldref_ClassName(int constantFieldrefIndex) {
|
|
||||||
ConstantFieldref constantFieldref = getConstantFieldref(constantFieldrefIndex);
|
|
||||||
return constantFieldref_ClassName(constantFieldref);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取字段名称
|
|
||||||
*/
|
|
||||||
public String getFieldName(final ConstantFieldref constantFieldref) {
|
|
||||||
ConstantNameAndType constNameAndType = getConstant(constantFieldref.getNameAndTypeIndex());
|
|
||||||
return constNameAndType.getName(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取字段名称
|
|
||||||
*/
|
|
||||||
public String getFieldName(int constantFieldrefIndex) {
|
|
||||||
ConstantFieldref constantFieldref = getConstantFieldref(constantFieldrefIndex);
|
|
||||||
return getFieldName(constantFieldref);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取字段类型签名
|
|
||||||
*/
|
|
||||||
public String getFieldSignature(final ConstantFieldref constantFieldref) {
|
|
||||||
ConstantNameAndType constNameAndType = getConstant(constantFieldref.getNameAndTypeIndex());
|
|
||||||
return constNameAndType.getSignature(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取字段类型签名
|
|
||||||
*/
|
|
||||||
public String getFieldSignature(int constantFieldrefIndex) {
|
|
||||||
ConstantFieldref constantFieldref = getConstantFieldref(constantFieldrefIndex);
|
|
||||||
return getFieldSignature(constantFieldref);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConstantMethodref -----------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取方法所处于Java类的类名
|
|
||||||
* 名称使用/分割,例如 haidnor/jvm/test/instruction/references/NEW
|
|
||||||
*/
|
|
||||||
public String constantMethodref_ClassName(final ConstantMethodref methodref) {
|
|
||||||
ConstantClass constClass = getConstant(methodref.getClassIndex());
|
|
||||||
return (String) constClass.getConstantValue(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取方法名
|
|
||||||
*/
|
|
||||||
public String constantMethodref_MethodName(final ConstantMethodref methodref) {
|
|
||||||
ConstantNameAndType constNameAndType = getConstant(methodref.getNameAndTypeIndex());
|
|
||||||
return constNameAndType.getName(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取方法签名
|
|
||||||
*/
|
|
||||||
public String constantMethodref_MethodSignature(final ConstantMethodref methodref) {
|
|
||||||
ConstantNameAndType constNameAndType = getConstant(methodref.getNameAndTypeIndex());
|
|
||||||
return constNameAndType.getSignature(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConstantInterfaceMethodref -----------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public String constantInterfaceMethodref_ClassName(final ConstantInterfaceMethodref methodref) {
|
|
||||||
ConstantClass constClass = getConstant(methodref.getClassIndex());
|
|
||||||
return (String) constClass.getConstantValue(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取方法名
|
|
||||||
*/
|
|
||||||
public String constantInterfaceMethodref_MethodName(final ConstantInterfaceMethodref methodref) {
|
|
||||||
ConstantNameAndType constNameAndType = getConstant(methodref.getNameAndTypeIndex());
|
|
||||||
return constNameAndType.getName(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取方法签名
|
|
||||||
*/
|
|
||||||
public String constantInterfaceMethodref_MethodSignature(final ConstantInterfaceMethodref methodref) {
|
|
||||||
ConstantNameAndType constNameAndType = getConstant(methodref.getNameAndTypeIndex());
|
|
||||||
return constNameAndType.getSignature(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ConstantNameAndType -----------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ConstantNameAndType
|
|
||||||
*/
|
|
||||||
public ConstantNameAndType constantNameAndType(int constantNameAndTypeIndex) {
|
|
||||||
return getConstant(constantNameAndTypeIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String constantNameAndType_name(int constantNameAndTypeIndex) {
|
|
||||||
ConstantNameAndType constantNameAndType = constantNameAndType(constantNameAndTypeIndex);
|
|
||||||
return constantNameAndType.getName(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String constantNameAndType_signature(int constantNameAndTypeIndex) {
|
|
||||||
ConstantNameAndType constantNameAndType = constantNameAndType(constantNameAndTypeIndex);
|
|
||||||
return constantNameAndType.getSignature(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,7 +121,8 @@ public class JavaExecutionEngine {
|
|||||||
handlerPC = codeException.getHandlerPC();
|
handlerPC = codeException.getHandlerPC();
|
||||||
} else {
|
} else {
|
||||||
// 从常量池中查询异常表定义的异常类型
|
// 从常量池中查询异常表定义的异常类型
|
||||||
String exceptionClassName = frame.getJavaClass().getConstantPool().constantClass_ClassName(catchType);
|
ConstantClass constantClass = frame.getJavaMethod().getConstantPool().getConstant(catchType);
|
||||||
|
String exceptionClassName = constantClass.getClassName();
|
||||||
exceptionClassName = Utility.compactClassName(exceptionClassName, false);
|
exceptionClassName = Utility.compactClassName(exceptionClassName, false);
|
||||||
|
|
||||||
// 判断异常的泛型类型. 假如执行指令抛出的是 NullPointerException 类型, 异常表定义的是 Exception 类型, 则此异常可以被捕获
|
// 判断异常的泛型类型. 假如执行指令抛出的是 NullPointerException 类型, 异常表定义的是 Exception 类型, 则此异常可以被捕获
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package haidnor.jvm.instruction.references;
|
package haidnor.jvm.instruction.references;
|
||||||
|
|
||||||
import haidnor.jvm.bcel.Const;
|
import haidnor.jvm.bcel.Const;
|
||||||
|
import haidnor.jvm.bcel.classfile.ConstantClass;
|
||||||
import haidnor.jvm.bcel.classfile.JavaClass;
|
import haidnor.jvm.bcel.classfile.JavaClass;
|
||||||
import haidnor.jvm.bcel.classfile.Utility;
|
import haidnor.jvm.bcel.classfile.Utility;
|
||||||
import haidnor.jvm.instruction.Instruction;
|
import haidnor.jvm.instruction.Instruction;
|
||||||
@@ -10,7 +11,6 @@ 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 lombok.SneakyThrows;
|
|
||||||
|
|
||||||
public class ANEWARRAY extends Instruction {
|
public class ANEWARRAY extends Instruction {
|
||||||
|
|
||||||
@@ -22,18 +22,18 @@ public class ANEWARRAY extends Instruction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
|
||||||
public void execute(Frame frame) {
|
public void execute(Frame frame) {
|
||||||
String className = frame.getJavaMethod().getConstantPool().constantClass_ClassName(constantClassIndex);
|
ConstantClass constantClass = frame.getJavaMethod().getConstantPool().getConstant(constantClassIndex);
|
||||||
|
String className = constantClass.getClassName();
|
||||||
|
|
||||||
JavaClass klass = Metaspace.getJavaClass(Utility.compactClassName(className));
|
JavaClass javaClass = Metaspace.getJavaClass(Utility.compactClassName(className));
|
||||||
if (klass == null) {
|
if (javaClass == null) {
|
||||||
// 如果在元空间中找不到已加载的类,则开始进行类加载流程
|
// 如果在元空间中找不到已加载的类,则开始进行类加载流程
|
||||||
klass = frame.getJavaClass().getJVMClassLoader().loadWithClassPath(className);
|
javaClass = frame.getJavaClass().getJVMClassLoader().loadWithClassPath(className);
|
||||||
}
|
}
|
||||||
int size = frame.popInt();
|
int size = frame.popInt();
|
||||||
Instance[] items = new Instance[size];
|
Instance[] items = new Instance[size];
|
||||||
InstanceArray instanceArray = new InstanceArray(klass, items);
|
InstanceArray instanceArray = new InstanceArray(javaClass, items);
|
||||||
|
|
||||||
frame.push(new StackValue(Const.T_OBJECT, instanceArray));
|
frame.push(new StackValue(Const.T_OBJECT, instanceArray));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package haidnor.jvm.instruction.references;
|
package haidnor.jvm.instruction.references;
|
||||||
|
|
||||||
import haidnor.jvm.bcel.classfile.ConstantPool;
|
import haidnor.jvm.bcel.classfile.ConstantFieldref;
|
||||||
import haidnor.jvm.bcel.classfile.JavaField;
|
import haidnor.jvm.bcel.classfile.JavaField;
|
||||||
import haidnor.jvm.instruction.Instruction;
|
import haidnor.jvm.instruction.Instruction;
|
||||||
import haidnor.jvm.rtda.Instance;
|
import haidnor.jvm.rtda.Instance;
|
||||||
@@ -20,9 +20,9 @@ public class GETFIELD extends Instruction {
|
|||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public void execute(Frame frame) {
|
public void execute(Frame frame) {
|
||||||
ConstantPool constantPool = frame.getJavaMethod().getConstantPool();
|
ConstantFieldref fieldref = frame.getJavaMethod().getConstantPool().getConstant(constantFieldrefIndex);
|
||||||
String filedName = constantPool.getFieldName(constantFieldrefIndex);
|
String filedName = fieldref.getName();
|
||||||
String fieldSignature = constantPool.getFieldSignature(constantFieldrefIndex);
|
String fieldSignature = fieldref.getSignature();
|
||||||
|
|
||||||
Instance instanceRef = frame.popRef();
|
Instance instanceRef = frame.popRef();
|
||||||
JavaField field = instanceRef.getField(filedName, fieldSignature);
|
JavaField field = instanceRef.getField(filedName, fieldSignature);
|
||||||
|
|||||||
@@ -28,14 +28,13 @@ public class GETSTATIC extends Instruction {
|
|||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public void execute(Frame frame) {
|
public void execute(Frame frame) {
|
||||||
ConstantPool constantPool = frame.getJavaMethod().getConstantPool();
|
ConstantFieldref fieldref = frame.getJavaMethod().getConstantPool().getConstant(constantFieldrefIndex);
|
||||||
ConstantFieldref constFieldref = constantPool.getConstant(constantFieldrefIndex);
|
|
||||||
// 动态链接. 找到字段所属的 Java 类
|
// 动态链接. 找到字段所属的 Java 类
|
||||||
String className = constantPool.constantFieldref_ClassName(constFieldref);
|
String className = fieldref.getBelongClassName();
|
||||||
// 动态链接. 找到字段的名字
|
// 动态链接. 找到字段的名字
|
||||||
String fieldName = constantPool.getFieldName(constFieldref);
|
String fieldName = fieldref.getName();
|
||||||
// 以上代码体现了动态链接.Class文件的常量池中存有大量的符号引用,字节码中的方法调用指令就以常量池里指向方法的符号引用作为参数.
|
|
||||||
|
|
||||||
|
// 以上代码体现了动态链接.Class文件的常量池中存有大量的符号引用,字节码中的方法调用指令就以常量池里指向方法的符号引用作为参数.
|
||||||
if (className.startsWith("java/")) {
|
if (className.startsWith("java/")) {
|
||||||
Class<?> clazz = Class.forName(className.replace('/', '.'));
|
Class<?> clazz = Class.forName(className.replace('/', '.'));
|
||||||
Field field = clazz.getField(fieldName);
|
Field field = clazz.getField(fieldName);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package haidnor.jvm.instruction.references;
|
package haidnor.jvm.instruction.references;
|
||||||
|
|
||||||
import haidnor.jvm.bcel.Const;
|
import haidnor.jvm.bcel.Const;
|
||||||
import haidnor.jvm.bcel.classfile.ConstantPool;
|
import haidnor.jvm.bcel.classfile.ConstantClass;
|
||||||
import haidnor.jvm.bcel.classfile.JavaClass;
|
import haidnor.jvm.bcel.classfile.JavaClass;
|
||||||
import haidnor.jvm.bcel.classfile.Utility;
|
import haidnor.jvm.bcel.classfile.Utility;
|
||||||
import haidnor.jvm.instruction.Instruction;
|
import haidnor.jvm.instruction.Instruction;
|
||||||
@@ -26,9 +26,8 @@ public class INSTANCEOF extends Instruction {
|
|||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public void execute(Frame frame) {
|
public void execute(Frame frame) {
|
||||||
ConstantPool constantPool = frame.getJavaMethod().getConstantPool();
|
ConstantClass constantClass = frame.getJavaMethod().getConstantPool().getConstant(constantClassIndex);
|
||||||
|
String className = constantClass.getClassName();
|
||||||
String className = constantPool.constantClass_ClassName(constantClassIndex);
|
|
||||||
className = Utility.compactClassName(className);
|
className = Utility.compactClassName(className);
|
||||||
|
|
||||||
StackValue stackValue = frame.pop();
|
StackValue stackValue = frame.pop();
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ 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.SignatureUtil;
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@@ -35,23 +34,18 @@ public class INVOKEINTERFACE extends Instruction {
|
|||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public void execute(Frame frame) {
|
public void execute(Frame frame) {
|
||||||
ConstantPool constantPool = frame.getJavaMethod().getConstantPool();
|
ConstantInterfaceMethodref methodref = frame.getJavaMethod().getConstantPool().getConstant(constantMethodrefIndex);
|
||||||
|
|
||||||
ConstantInterfaceMethodref interfaceMethodref = constantPool.getConstant(constantMethodrefIndex);
|
String className = methodref.getClassName();
|
||||||
|
String methodName = methodref.getMethodName();
|
||||||
int classIndex = interfaceMethodref.getClassIndex();
|
String methodSignature = methodref.getMethodSignature();
|
||||||
String interfaceName = constantPool.constantClass_ClassName(classIndex);
|
|
||||||
|
|
||||||
int nameAndTypeIndex = interfaceMethodref.getNameAndTypeIndex();
|
|
||||||
String methodName = constantPool.constantNameAndType_name(nameAndTypeIndex);
|
|
||||||
String methodSignature = constantPool.constantNameAndType_signature(nameAndTypeIndex);
|
|
||||||
|
|
||||||
// 系统类反射 自定义类另外处理
|
// 系统类反射 自定义类另外处理
|
||||||
if (interfaceName.startsWith("java/")) {
|
if (className.startsWith("java/")) {
|
||||||
// 解析方法签名得到方法的返回类型
|
// 解析方法签名得到方法的返回类型
|
||||||
String returnType = Utility.methodSignatureReturnType(methodSignature, false);
|
String returnType = methodref.getReturnType();
|
||||||
// 执行方法的参数列表
|
// 执行方法的参数列表
|
||||||
Class<?>[] parameterTypeArr = SignatureUtil.getParameterTypeArr(methodSignature);
|
Class<?>[] parameterTypeArr = methodref.getParameterTypeArr();
|
||||||
// 执行方法的参数值
|
// 执行方法的参数值
|
||||||
Object[] args = frame.popStacksValue(parameterTypeArr.length);
|
Object[] args = frame.popStacksValue(parameterTypeArr.length);
|
||||||
// 将特定的参数转换为基本类型
|
// 将特定的参数转换为基本类型
|
||||||
@@ -78,10 +72,10 @@ public class INVOKEINTERFACE extends Instruction {
|
|||||||
}
|
}
|
||||||
// 调用自定义类的方法
|
// 调用自定义类的方法
|
||||||
else {
|
else {
|
||||||
JavaClass interfaceKlass = Metaspace.getJavaClass(Utility.compactClassName(interfaceName));
|
JavaClass javaClass = Metaspace.getJavaClass(Utility.compactClassName(className));
|
||||||
if (interfaceKlass == null) {
|
if (javaClass == null) {
|
||||||
JVMClassLoader classLoader = frame.getJavaClass().getJVMClassLoader();
|
JVMClassLoader classLoader = frame.getJavaClass().getJVMClassLoader();
|
||||||
classLoader.loadWithClassPath(interfaceName);
|
classLoader.loadWithClassPath(className);
|
||||||
}
|
}
|
||||||
|
|
||||||
StackValue stackValue = frame.peek();
|
StackValue stackValue = frame.peek();
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ 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.SignatureUtil;
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,9 +29,9 @@ public class INVOKESPECIAL extends Instruction {
|
|||||||
ConstantPool constantPool = frame.getJavaMethod().getConstantPool();
|
ConstantPool constantPool = frame.getJavaMethod().getConstantPool();
|
||||||
ConstantMethodref methodref = constantPool.getConstant(constantMethodrefIndex);
|
ConstantMethodref methodref = constantPool.getConstant(constantMethodrefIndex);
|
||||||
|
|
||||||
String className = constantPool.constantMethodref_ClassName(methodref);
|
String className = methodref.getClassName();
|
||||||
String methodName = constantPool.constantMethodref_MethodName(methodref);
|
String methodName = methodref.getMethodName();
|
||||||
String methodSignature = constantPool.constantMethodref_MethodSignature(methodref);
|
String methodSignature = methodref.getMethodSignature();
|
||||||
|
|
||||||
JavaClass javaClass = Metaspace.getJavaClass(Utility.compactClassName(className));
|
JavaClass javaClass = Metaspace.getJavaClass(Utility.compactClassName(className));
|
||||||
if (javaClass == null) {
|
if (javaClass == null) {
|
||||||
@@ -44,7 +43,7 @@ public class INVOKESPECIAL extends Instruction {
|
|||||||
// 执行 RT.jar 中 Java 对象构造方法的时候创建java对象
|
// 执行 RT.jar 中 Java 对象构造方法的时候创建java对象
|
||||||
if (methodName.equals("<init>")) {
|
if (methodName.equals("<init>")) {
|
||||||
// 执行方法的参数列表
|
// 执行方法的参数列表
|
||||||
Class<?>[] parameterTypeArr = SignatureUtil.getParameterTypeArr(methodSignature);
|
Class<?>[] parameterTypeArr = methodref.getParameterTypeArr();
|
||||||
// 执行方法的参数值
|
// 执行方法的参数值
|
||||||
Object[] args = frame.popStacksValue(parameterTypeArr.length);
|
Object[] args = frame.popStacksValue(parameterTypeArr.length);
|
||||||
// 将特定的参数转换为基本类型
|
// 将特定的参数转换为基本类型
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ 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.SignatureUtil;
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -33,26 +32,28 @@ public class INVOKESTATIC extends Instruction {
|
|||||||
String className;
|
String className;
|
||||||
String methodName;
|
String methodName;
|
||||||
String methodSignature;
|
String methodSignature;
|
||||||
|
String returnType;
|
||||||
|
Class<?>[] parameterTypeArr;
|
||||||
|
|
||||||
Constant constant = constantPool.getConstant(constantIndex);
|
Constant constant = constantPool.getConstant(constantIndex);
|
||||||
if (constant instanceof ConstantMethodref constantMethodref) {
|
if (constant instanceof ConstantMethodref methodref) {
|
||||||
className = constantPool.constantMethodref_ClassName(constantMethodref);
|
className = methodref.getClassName();
|
||||||
methodName = constantPool.constantMethodref_MethodName(constantMethodref);
|
methodName = methodref.getMethodName();
|
||||||
methodSignature = constantPool.constantMethodref_MethodSignature(constantMethodref);
|
methodSignature = methodref.getMethodSignature();
|
||||||
|
returnType = methodref.getReturnType();
|
||||||
} else if (constant instanceof ConstantInterfaceMethodref interfaceMethodref) {
|
parameterTypeArr = methodref.getParameterTypeArr();
|
||||||
className = constantPool.constantInterfaceMethodref_ClassName(interfaceMethodref);
|
} else if (constant instanceof ConstantInterfaceMethodref methodref) {
|
||||||
methodName = constantPool.constantInterfaceMethodref_MethodName(interfaceMethodref);
|
className = methodref.getClassName();
|
||||||
methodSignature = constantPool.constantInterfaceMethodref_MethodSignature(interfaceMethodref);
|
methodName = methodref.getMethodName();
|
||||||
|
methodSignature = methodref.getMethodSignature();
|
||||||
|
returnType = methodref.getReturnType();
|
||||||
|
parameterTypeArr = methodref.getParameterTypeArr();
|
||||||
} else {
|
} else {
|
||||||
throw new ClassCastException();
|
throw new ClassCastException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 系统类反射 自定义类另外处理
|
// 系统类反射 自定义类另外处理
|
||||||
if (className.startsWith("java/")) {
|
if (className.startsWith("java/")) {
|
||||||
// 解析方法签名得到方法的返回类型
|
|
||||||
String returnType = Utility.methodSignatureReturnType(methodSignature, false);
|
|
||||||
Class<?>[] parameterTypeArr = SignatureUtil.getParameterTypeArr(methodSignature);
|
|
||||||
Object[] stacksValueArr = frame.popStacksValue(parameterTypeArr.length);
|
Object[] stacksValueArr = frame.popStacksValue(parameterTypeArr.length);
|
||||||
for (int i = 0; i < parameterTypeArr.length; i++) {
|
for (int i = 0; i < parameterTypeArr.length; i++) {
|
||||||
Class<?> aClass = parameterTypeArr[i];
|
Class<?> aClass = parameterTypeArr[i];
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package haidnor.jvm.instruction.references;
|
package haidnor.jvm.instruction.references;
|
||||||
|
|
||||||
import haidnor.jvm.bcel.Const;
|
import haidnor.jvm.bcel.Const;
|
||||||
import haidnor.jvm.bcel.classfile.ConstantPool;
|
import haidnor.jvm.bcel.classfile.ConstantClass;
|
||||||
import haidnor.jvm.bcel.classfile.JavaClass;
|
import haidnor.jvm.bcel.classfile.JavaClass;
|
||||||
import haidnor.jvm.bcel.classfile.Utility;
|
import haidnor.jvm.bcel.classfile.Utility;
|
||||||
import haidnor.jvm.instruction.Instruction;
|
import haidnor.jvm.instruction.Instruction;
|
||||||
@@ -24,8 +24,8 @@ public class NEW extends Instruction {
|
|||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public void execute(Frame frame) {
|
public void execute(Frame frame) {
|
||||||
ConstantPool constantPool = frame.getJavaMethod().getConstantPool();
|
ConstantClass constantClass = frame.getJavaMethod().getConstantPool().getConstant(constantClassIndex);
|
||||||
String className = constantPool.constantClass_ClassName(constantClassIndex);
|
String className = constantClass.getClassName();
|
||||||
|
|
||||||
if (className.startsWith("java/")) {
|
if (className.startsWith("java/")) {
|
||||||
frame.push(new StackValue(Const.T_OBJECT, null));
|
frame.push(new StackValue(Const.T_OBJECT, null));
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package haidnor.jvm.instruction.references;
|
package haidnor.jvm.instruction.references;
|
||||||
|
|
||||||
import haidnor.jvm.bcel.classfile.ConstantPool;
|
import haidnor.jvm.bcel.classfile.ConstantFieldref;
|
||||||
import haidnor.jvm.bcel.classfile.JavaField;
|
import haidnor.jvm.bcel.classfile.JavaField;
|
||||||
import haidnor.jvm.instruction.Instruction;
|
import haidnor.jvm.instruction.Instruction;
|
||||||
import haidnor.jvm.rtda.Instance;
|
import haidnor.jvm.rtda.Instance;
|
||||||
@@ -21,10 +21,9 @@ public class PUTFIELD extends Instruction {
|
|||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public void execute(Frame frame) {
|
public void execute(Frame frame) {
|
||||||
ConstantPool constantPool = frame.getJavaMethod().getConstantPool();
|
ConstantFieldref fieldref = frame.getJavaMethod().getConstantPool().getConstant(constantFieldrefIndex);
|
||||||
|
String filedName = fieldref.getName();
|
||||||
String filedName = constantPool.getFieldName(constantFieldrefIndex);
|
String fieldSignature = fieldref.getSignature();
|
||||||
String fieldSignature = constantPool.getFieldSignature(constantFieldrefIndex);
|
|
||||||
|
|
||||||
StackValue stackValue = frame.pop();
|
StackValue stackValue = frame.pop();
|
||||||
|
|
||||||
|
|||||||
@@ -22,12 +22,11 @@ public class PUTSTATIC extends Instruction {
|
|||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public void execute(Frame frame) {
|
public void execute(Frame frame) {
|
||||||
ConstantPool constantPool = frame.getJavaMethod().getConstantPool();
|
ConstantFieldref constFieldref = frame.getJavaMethod().getConstantPool().getConstant(constantFieldrefIndex);
|
||||||
ConstantFieldref constFieldref = constantPool.getConstant(constantFieldrefIndex);
|
|
||||||
// 动态链接. 找到字段所属的 Java 类
|
// 动态链接. 找到字段所属的 Java 类
|
||||||
String className = constantPool.constantFieldref_ClassName(constFieldref);
|
String className = constFieldref.getBelongClassName();
|
||||||
// 动态链接. 找到字段的名字
|
// 动态链接. 找到字段的名字
|
||||||
String fieldName = constantPool.getFieldName(constFieldref);
|
String fieldName = constFieldref.getName();
|
||||||
// 以上代码体现了动态链接.Class文件的常量池中存有大量的符号引用,字节码中的方法调用指令就以常量池里指向方法的符号引用作为参数.
|
// 以上代码体现了动态链接.Class文件的常量池中存有大量的符号引用,字节码中的方法调用指令就以常量池里指向方法的符号引用作为参数.
|
||||||
|
|
||||||
JavaClass javaClass = Metaspace.getJavaClass(Utility.compactClassName(className));
|
JavaClass javaClass = Metaspace.getJavaClass(Utility.compactClassName(className));
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
package haidnor.jvm.util;
|
|
||||||
|
|
||||||
import haidnor.jvm.bcel.classfile.Utility;
|
|
||||||
import lombok.SneakyThrows;
|
|
||||||
|
|
||||||
public abstract class SignatureUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 解析方法签名返回方法参数类型数组
|
|
||||||
*/
|
|
||||||
@SneakyThrows
|
|
||||||
public static Class<?>[] getParameterTypeArr(String methodeSignature) {
|
|
||||||
String[] argumentTypeArr = Utility.methodSignatureArgumentTypes(methodeSignature, false);
|
|
||||||
Class<?>[] argumentClassArr = new Class[argumentTypeArr.length];
|
|
||||||
for (int i = 0; i < argumentTypeArr.length; i++) {
|
|
||||||
Class<?> argumentClass;
|
|
||||||
String argumentType = argumentTypeArr[i];
|
|
||||||
argumentClass = switch (argumentType) {
|
|
||||||
case "byte" -> byte.class;
|
|
||||||
case "short" -> short.class;
|
|
||||||
case "boolean" -> boolean.class;
|
|
||||||
case "char" -> char.class;
|
|
||||||
case "int" -> int.class;
|
|
||||||
case "long" -> long.class;
|
|
||||||
case "float" -> float.class;
|
|
||||||
case "double" -> double.class;
|
|
||||||
default -> Class.forName(argumentType);
|
|
||||||
};
|
|
||||||
argumentClassArr[i] = argumentClass;
|
|
||||||
}
|
|
||||||
return argumentClassArr;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user