This commit is contained in:
wangxiang
2023-10-25 17:05:22 +08:00
parent 4ed66bc553
commit 74b0140f85
269 changed files with 7632 additions and 640 deletions

View File

@@ -48,7 +48,7 @@ public class HaidnorJVM {
JVMThreadHolder.set(new JVMThread());
JavaClass javaClass = classLoader.loadWithJar(jarFile, entry);
Metaspace.registerJavaClass(javaClass);
JavaExecutionEngine.callMainMethod(javaClass);
JavaExecutionEngine.callMain(javaClass);
return;
}
}
@@ -62,7 +62,7 @@ public class HaidnorJVM {
String path = cmd.getOptionValue("class");
JVMClassLoader bootClassLoader = new JVMClassLoader("ApplicationClassLoader");
JavaClass javaClass = bootClassLoader.loadWithAbsolutePath(path);
JavaExecutionEngine.callMainMethod(javaClass);
JavaExecutionEngine.callMain(javaClass);
}
}
@@ -80,4 +80,11 @@ public class HaidnorJVM {
return parser.parse(options, args);
}
public static void testRun(Class<?> mainClass) {
JVMThreadHolder.set(new JVMThread());
JVMClassLoader bootClassLoader = new JVMClassLoader("ApplicationClassLoader");
JavaClass mainMeteKlass = bootClassLoader.loadWithClassPath(mainClass.getName().replace('.', '/'));
JavaExecutionEngine.callMain(mainMeteKlass);
}
}

View File

@@ -29,6 +29,7 @@ import java.util.Objects;
* classes keep closely to the JVM specification.
*/
public abstract class Constant implements Cloneable, Node {
public ConstantPool constantPool;
private static BCELComparator bcelComparator = new BCELComparator() {
@@ -160,6 +161,10 @@ public abstract class Constant implements Cloneable, Node {
public abstract void dump(DataOutputStream file) throws IOException;
public void setConstantPool(ConstantPool constantPool) {
this.constantPool = constantPool;
}
/**
* Returns value as defined by given BCELComparator strategy. By default two Constant objects are said to be equal when
* the result of toString() is equal.

View File

@@ -17,6 +17,7 @@
package haidnor.jvm.bcel.classfile;
import haidnor.jvm.bcel.Const;
import lombok.SneakyThrows;
import java.io.DataInput;
import java.io.IOException;
@@ -63,4 +64,46 @@ public final class ConstantMethodref extends ConstantCP {
public void accept(final Visitor v) {
v.visitConstantMethodref(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;
}
}

View File

@@ -318,6 +318,9 @@ public class ConstantPool implements Cloneable, Node, Iterable<Constant> {
throw new ClassFormatException("Constant pool at index " + index + " is null.");
}
}
if (c != null) {
c.setConstantPool(this);
}
return c;
}

View File

@@ -24,8 +24,10 @@ import haidnor.jvm.bcel.util.ClassQueue;
import haidnor.jvm.bcel.util.Repository;
import haidnor.jvm.bcel.util.SyntheticRepository;
import haidnor.jvm.classloader.JVMClassLoader;
import haidnor.jvm.rtda.Instance;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import org.apache.commons.lang3.ArrayUtils;
import java.io.*;
@@ -896,5 +898,18 @@ public class JavaClass extends AccessFlags implements Cloneable, Node, Comparabl
return null;
}
@SneakyThrows
public Instance newInstance() {
// 创建对象存放字段的内存空间
List<JavaField> javaFieldList = Arrays.asList(getFields());
// 创建 JVM 中的对象实例
Instance obj = new Instance(javaFieldList, this);
// 加载父类
if (this.getSuperClass() != null) {
obj.setSuperInstance(this.getSuperClass().newInstance());
}
return obj;
}
}

View File

@@ -5,7 +5,7 @@ import haidnor.jvm.bcel.Const;
import haidnor.jvm.bcel.classfile.*;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.instruction.InstructionFactory;
import haidnor.jvm.instruction.ReturnableInstruction;
import haidnor.jvm.instruction.control.ReturnableInstruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.JVMThread;
import haidnor.jvm.runtime.StackValue;
@@ -26,8 +26,8 @@ public class JavaExecutionEngine {
/**
* 执行 public static void main(String[] args) 方法
*/
public static void callMainMethod(JavaClass javaClass) {
JavaMethod mainMethod = javaClass.getMainMethod();
public static void callMain(JavaClass clazz) {
JavaMethod mainMethod = clazz.getMainMethod();
callMethod(null, mainMethod);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;
/**
* @author wang xiang
*/
public class DCMPG extends Instruction {
public DCMPG(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
double v2 = frame.popDouble();
double v1 = frame.popDouble();
if (v1 == v2) {
frame.pushInt(0);
return;
}
if (v1 < v2) {
frame.pushInt(-1);
return;
}
frame.pushInt(1);
}
}

View File

@@ -0,0 +1,31 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;
/**
* @author wang xiang
*/
public class DCMPL extends Instruction {
public DCMPL(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
Double v2 = frame.popDouble();
Double v1 = frame.popDouble();
if (v1.equals(v2)) {
frame.pushInt(0);
return;
}
if (v1 < v2) {
frame.pushInt(-1);
return;
}
frame.pushInt(1);
}
}

View File

@@ -0,0 +1,30 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;
/**
* @author wang xiang
*/
public class FCMPG extends Instruction {
public FCMPG(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
float v2 = frame.popFloat();
float v1 = frame.popFloat();
if (v1 == v2) {
frame.pushInt(0);
return;
}
if (v1 < v2) {
frame.pushInt(-1);
return;
}
frame.pushInt(1);
}
}

View File

@@ -0,0 +1,30 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;
/**
* @author wang xiang
*/
public class FCMPL extends Instruction {
public FCMPL(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
float v2 = frame.popFloat();
float v1 = frame.popFloat();
if (v1 == v2) {
frame.pushInt(0);
return;
}
if (v1 < v2) {
frame.pushInt(-1);
return;
}
frame.pushInt(1);
}
}

View File

@@ -0,0 +1,40 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
public class IFEQ extends Instruction {
private final int offSet;
public IFEQ(CodeStream codeStream) {
super(codeStream);
this.offSet = codeStream.readShort(this);
}
@Override
public void execute(Frame frame) {
StackValue v1 = frame.pop();
if (v1.getValue() instanceof Boolean) {
if (!((boolean) v1.getValue())) {
super.setOffSet(offSet);
} else {
super.setOffSet(3);
}
} else {
if ((int) v1.getValue() == 0) {
super.setOffSet(offSet);
} else {
super.setOffSet(3);
}
}
}
@Override
public String toString() {
return super.getIndex() + " " + this.getClass().getSimpleName() + " " + offSet;
}
}

View File

@@ -0,0 +1,34 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
public class IFGE extends Instruction {
/**
* 下次再执行的偏移量
*/
private final int offSet;
public IFGE(CodeStream codeStream) {
super(codeStream);
this.offSet = codeStream.readShort(this);
}
@Override
public void execute(Frame frame) {
StackValue v1 = frame.pop();
if ((int) v1.getValue() >= 0) {
super.setOffSet(offSet);
} else {
super.setOffSet(3);
}
}
@Override
public String toString() {
return super.getIndex() + " " + this.getClass().getSimpleName() + " " + offSet;
}
}

View File

@@ -0,0 +1,34 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
public class IFGT extends Instruction {
/**
* 下次再执行的偏移量
*/
private final int offSet;
public IFGT(CodeStream codeStream) {
super(codeStream);
this.offSet = codeStream.readShort(this);
}
@Override
public void execute(Frame frame) {
StackValue v1 = frame.pop();
if ((int) v1.getValue() > 0) {
super.setOffSet(offSet);
} else {
super.setOffSet(3);
}
}
@Override
public String toString() {
return super.getIndex() + " " + this.getClass().getSimpleName() + " " + offSet;
}
}

View File

@@ -0,0 +1,34 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
public class IFLE extends Instruction {
/**
* 下次再执行的偏移量
*/
private final int offSet;
public IFLE(CodeStream codeStream) {
super(codeStream);
this.offSet = codeStream.readShort(this);
}
@Override
public void execute(Frame frame) {
StackValue v1 = frame.pop();
if ((int) v1.getValue() <= 0) {
super.setOffSet(offSet);
} else {
super.setOffSet(3);
}
}
@Override
public String toString() {
return super.getIndex() + " " + this.getClass().getSimpleName() + " " + offSet;
}
}

View File

@@ -0,0 +1,34 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
public class IFLT extends Instruction {
/**
* 下次再执行的偏移量
*/
private final int offSet;
public IFLT(CodeStream codeStream) {
super(codeStream);
this.offSet = codeStream.readShort(this);
}
@Override
public void execute(Frame frame) {
StackValue v1 = frame.pop();
if ((int) v1.getValue() < 0) {
super.setOffSet(offSet);
} else {
super.setOffSet(3);
}
}
@Override
public String toString() {
return super.getIndex() + " " + this.getClass().getSimpleName() + " " + offSet;
}
}

View File

@@ -0,0 +1,43 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
public class IFNE extends Instruction {
/**
* 下次再执行的偏移量
*/
private final int offSet;
public IFNE(CodeStream codeStream) {
super(codeStream);
this.offSet = codeStream.readShort(this);
}
@Override
public void execute(Frame frame) {
StackValue v1 = frame.pop();
if (v1.getValue() instanceof Boolean) {
if (((boolean) v1.getValue())) {
super.setOffSet(offSet);
} else {
super.setOffSet(3);
}
} else {
if ((int) v1.getValue() != 0) {
super.setOffSet(offSet);
} else {
super.setOffSet(3);
}
}
}
@Override
public String toString() {
return super.getIndex() + " " + this.getClass().getSimpleName() + " " + offSet;
}
}

View File

@@ -0,0 +1,36 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;
/**
* @author wang xiang
*/
public class IF_ACMPEQ extends Instruction {
/**
* 下次再执行的偏移量
*/
private final int offSet;
public IF_ACMPEQ(CodeStream codeStream) {
super(codeStream);
this.offSet = codeStream.readShort(this);
}
@Override
public void execute(Frame frame) {
Object val2 = frame.popRef();
Object val1 = frame.popRef();
if (val1 == val2) {
super.setOffSet(offSet);
} else {
super.setOffSet(3);
}
}
@Override
public String toString() {
return super.getIndex() + " " + this.getClass().getSimpleName() + " " + offSet;
}
}

View File

@@ -0,0 +1,36 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;
/**
* @author wang xiang
*/
public class IF_ACMPNE extends Instruction {
/**
* 下次再执行的偏移量
*/
private final int offSet;
public IF_ACMPNE(CodeStream codeStream) {
super(codeStream);
this.offSet = codeStream.readShort(this);
}
@Override
public void execute(Frame frame) {
Object val2 = frame.popRef();
Object val1 = frame.popRef();
if (val1 != val2) {
super.setOffSet(offSet);
} else {
super.setOffSet(3);
}
}
@Override
public String toString() {
return super.getIndex() + " " + this.getClass().getSimpleName() + " " + offSet;
}
}

View File

@@ -0,0 +1,42 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
/**
* Java VM opcode.
*
* @author wang xiang
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> Opcode
* definitions in The Java Virtual Machine Specification</a>
*/
public class IF_ICMPEQ extends Instruction {
/**
* 下次再执行的偏移量
*/
private final int offSet;
public IF_ICMPEQ(CodeStream codeStream) {
super(codeStream);
this.offSet = codeStream.readShort(this);
}
@Override
public void execute(Frame frame) {
StackValue v1 = frame.pop();
StackValue v2 = frame.pop();
if ((int) v1.getValue() == (int) v2.getValue()) {
super.setOffSet(offSet);
} else {
super.setOffSet(3);
}
}
@Override
public String toString() {
return super.getIndex() + " " + this.getClass().getSimpleName() + " " + offSet;
}
}

View File

@@ -0,0 +1,42 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
/**
* Java VM opcode.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> Opcode
* definitions in The Java Virtual Machine Specification</a>
*/
public class IF_ICMPGE extends Instruction {
/**
* 下次再执行的偏移量
*/
private final int offSet;
public IF_ICMPGE(CodeStream codeStream) {
super(codeStream);
this.offSet = codeStream.readShort(this);
}
@Override
public void execute(Frame frame) {
StackValue v2 = frame.pop();
StackValue v1 = frame.pop();
if ((int) v1.getValue() >= (int) v2.getValue()) {
super.setOffSet(offSet);
} else {
super.setOffSet(3);
}
}
@Override
public String toString() {
return super.getIndex() + " " + this.getClass().getSimpleName() + " " + offSet;
}
}

View File

@@ -0,0 +1,42 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
/**
* Java VM opcode.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> Opcode
* definitions in The Java Virtual Machine Specification</a>
*/
public class IF_ICMPGT extends Instruction {
/**
* 下次再执行的偏移量
*/
private final int offSet;
public IF_ICMPGT(CodeStream codeStream) {
super(codeStream);
this.offSet = codeStream.readShort(this);
}
@Override
public void execute(Frame frame) {
StackValue v2 = frame.pop();
StackValue v1 = frame.pop();
if ((int) v1.getValue() > (int) v2.getValue()) {
super.setOffSet(offSet);
} else {
super.setOffSet(3);
}
}
@Override
public String toString() {
return super.getIndex() + " " + this.getClass().getSimpleName() + " " + offSet;
}
}

View File

@@ -0,0 +1,37 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
/**
* Java VM opcode.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> Opcode
* definitions in The Java Virtual Machine Specification</a>
*/
public class IF_ICMPLE extends Instruction {
/**
* 下次再执行的偏移量
*/
private final int offSet;
public IF_ICMPLE(CodeStream codeStream) {
super(codeStream);
this.offSet = codeStream.readShort(this);
}
@Override
public void execute(Frame frame) {
StackValue v2 = frame.pop();
StackValue v1 = frame.pop();
if ((int) v1.getValue() <= (int) v2.getValue()) {
super.setOffSet(offSet);
} else {
super.setOffSet(3);
}
}
}

View File

@@ -0,0 +1,42 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
/**
* Java VM opcode.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> Opcode
* definitions in The Java Virtual Machine Specification</a>
*/
public class IF_ICMPLT extends Instruction {
/**
* 下次再执行的偏移量
*/
private final int offSet;
public IF_ICMPLT(CodeStream codeStream) {
super(codeStream);
this.offSet = codeStream.readShort(this);
}
@Override
public void execute(Frame frame) {
StackValue v2 = frame.pop();
StackValue v1 = frame.pop();
if ((int) v1.getValue() < (int) v2.getValue()) {
super.setOffSet(offSet);
} else {
super.setOffSet(3);
}
}
@Override
public String toString() {
return super.getIndex() + " " + this.getClass().getSimpleName() + " " + offSet;
}
}

View File

@@ -0,0 +1,42 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
/**
* Java VM opcode.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> Opcode
* definitions in The Java Virtual Machine Specification</a>
*/
public class IF_ICMPNE extends Instruction {
/**
* 下次再执行的偏移量
*/
private final int offSet;
public IF_ICMPNE(CodeStream codeStream) {
super(codeStream);
this.offSet = codeStream.readShort(this);
}
@Override
public void execute(Frame frame) {
StackValue v1 = frame.pop();
StackValue v2 = frame.pop();
if ((int) v1.getValue() != (int) v2.getValue()) {
super.setOffSet(offSet);
} else {
super.setOffSet(3);
}
}
@Override
public String toString() {
return super.getIndex() + " " + this.getClass().getSimpleName() + " " + offSet;
}
}

View File

@@ -0,0 +1,28 @@
package haidnor.jvm.instruction.comparisons;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;
public class LCMP extends Instruction {
public LCMP(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
Long v2 = frame.popLong();
Long v1 = frame.popLong();
if (v1.equals(v2)) {
frame.pushInt(0);
return;
}
if (v1 < v2) {
frame.pushInt(-1);
return;
}
frame.pushInt(1);
}
}

View File

@@ -0,0 +1,20 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.bcel.Const;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
public class ACONST_NULL extends Instruction {
public ACONST_NULL(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
frame.push(new StackValue(Const.T_OBJECT, null));
}
}

View File

@@ -0,0 +1,29 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.bcel.Const;
/**
* Java VM opcode.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.bipush"> Opcode definitions in
* The Java Virtual Machine Specification</a>
*/
public class BIPUSH extends Instruction {
private final int value;
public BIPUSH(CodeStream codeStream) {
super(codeStream);
this.value = codeStream.readByte(this);
}
@Override
public void execute(Frame frame) {
frame.push(new StackValue(Const.T_INT, value));
}
}

View File

@@ -0,0 +1,26 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.bcel.Const;
/**
* Java VM opcode.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dconst_d"> Opcode definitions
* in The Java Virtual Machine Specification</a>
*/
public class DCONST_0 extends Instruction {
public DCONST_0(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
frame.push(new StackValue(Const.T_DOUBLE, 0.0D));
}
}

View File

@@ -0,0 +1,26 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.bcel.Const;
/**
* Java VM opcode.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dconst_d"> Opcode definitions
* in The Java Virtual Machine Specification</a>
*/
public class DCONST_1 extends Instruction {
public DCONST_1(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
frame.push(new StackValue(Const.T_DOUBLE, 1.0D));
}
}

View File

@@ -0,0 +1,26 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.bcel.Const;
/**
* Java VM opcode.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fconst_f"> Opcode definitions
* in The Java Virtual Machine Specification</a>
*/
public class FCONST_1 extends Instruction {
public FCONST_1(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
frame.push(new StackValue(Const.T_FLOAT, 1.0f));
}
}

View File

@@ -0,0 +1,26 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.bcel.Const;
/**
* Java VM opcode.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fconst_f"> Opcode definitions
* in The Java Virtual Machine Specification</a>
*/
public class FCONST_2 extends Instruction {
public FCONST_2(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
frame.push(new StackValue(Const.T_FLOAT, 2.0f));
}
}

View File

@@ -0,0 +1,23 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.bcel.Const;
/**
* https://docs.oracle.com/javase/specs/jvms/se19/html/jvms-6.html#jvms-6.5.iconst_i
*/
public class ICONST_0 extends Instruction {
public ICONST_0(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
frame.push(new StackValue(Const.T_INT, 0));
}
}

View File

@@ -0,0 +1,23 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.bcel.Const;
/**
* https://docs.oracle.com/javase/specs/jvms/se19/html/jvms-6.html#jvms-6.5.iconst_i
*/
public class ICONST_1 extends Instruction {
public ICONST_1(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
frame.push(new StackValue(Const.T_INT, 1));
}
}

View File

@@ -0,0 +1,23 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.bcel.Const;
/**
* https://docs.oracle.com/javase/specs/jvms/se19/html/jvms-6.html#jvms-6.5.iconst_i
*/
public class ICONST_2 extends Instruction {
public ICONST_2(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
frame.push(new StackValue(Const.T_INT, 2));
}
}

View File

@@ -0,0 +1,23 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.bcel.Const;
/**
* https://docs.oracle.com/javase/specs/jvms/se19/html/jvms-6.html#jvms-6.5.iconst_i
*/
public class ICONST_3 extends Instruction {
public ICONST_3(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
frame.push(new StackValue(Const.T_INT, 3));
}
}

View File

@@ -0,0 +1,23 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.bcel.Const;
/**
* https://docs.oracle.com/javase/specs/jvms/se19/html/jvms-6.html#jvms-6.5.iconst_i
*/
public class ICONST_4 extends Instruction {
public ICONST_4(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
frame.push(new StackValue(Const.T_INT, 4));
}
}

View File

@@ -0,0 +1,23 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.bcel.Const;
/**
* https://docs.oracle.com/javase/specs/jvms/se19/html/jvms-6.html#jvms-6.5.iconst_i
*/
public class ICONST_5 extends Instruction {
public ICONST_5(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
frame.push(new StackValue(Const.T_INT, 5));
}
}

View File

@@ -0,0 +1,23 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.bcel.Const;
/**
* https://docs.oracle.com/javase/specs/jvms/se19/html/jvms-6.html#jvms-6.5.iconst_i
*/
public class ICONST_M1 extends Instruction {
public ICONST_M1(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
frame.push(new StackValue(Const.T_INT, -1));
}
}

View File

@@ -0,0 +1,26 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.bcel.Const;
/**
* Java VM opcode.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lconst_l"> Opcode definitions
* in The Java Virtual Machine Specification</a>
*/
public class LCONST_0 extends Instruction {
public LCONST_0(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
frame.push(new StackValue(Const.T_LONG, 0L));
}
}

View File

@@ -0,0 +1,26 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.bcel.Const;
/**
* Java VM opcode.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lconst_l"> Opcode definitions
* in The Java Virtual Machine Specification</a>
*/
public class LCONST_1 extends Instruction {
public LCONST_1(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
frame.push(new StackValue(Const.T_LONG, 1L));
}
}

View File

@@ -0,0 +1,58 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.bcel.Const;
import haidnor.jvm.bcel.classfile.*;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import lombok.SneakyThrows;
/**
* Java VM opcode.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldc"> Opcode definitions in The
* Java Virtual Machine Specification</a>
*/
public class LDC extends Instruction {
private final int constantIndex;
public LDC(CodeStream codeStream) {
super(codeStream);
this.constantIndex = codeStream.readUnsignedByte(this);
}
@Override
@SneakyThrows
public void execute(Frame frame) {
ConstantPool constantPool = frame.getJavaMethod().getConstantPool();
// 从常量池中获取值
Constant constant = constantPool.getConstant(constantIndex);
switch (constant.getTag()) {
case Const.CONSTANT_Integer: {
ConstantInteger constantInteger = (ConstantInteger) constant;
Object value = constantInteger.getConstantValue(constantPool);
frame.push(new StackValue(Const.T_INT, value));
break;
}
case Const.CONSTANT_Float: {
ConstantFloat constantFloat = (ConstantFloat) constant;
Object value = constantFloat.getConstantValue(constantPool);
frame.push(new StackValue(Const.T_FLOAT, value));
break;
}
case Const.CONSTANT_String: {
ConstantString constString = (ConstantString) constant;
Object value = constString.getConstantValue(constantPool);
frame.push(new StackValue(Const.T_OBJECT, value));
break;
}
default:
throw new Error("not supported LDC type" + constant.getTag());
}
}
}

View File

@@ -0,0 +1,48 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.bcel.Const;
import haidnor.jvm.bcel.classfile.Constant;
import haidnor.jvm.bcel.classfile.ConstantDouble;
import haidnor.jvm.bcel.classfile.ConstantLong;
import haidnor.jvm.bcel.classfile.ConstantPool;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
/**
* 将 long 或 double 型常量从常量池中推送至栈顶 (宽索引)
*/
public class LDC2W extends Instruction {
private final byte constantTag;
private long longValue;
private double doubleValue;
public LDC2W(CodeStream codeStream) {
super(codeStream);
int index = codeStream.readUnsignedShort(this);
ConstantPool constantPool = codeStream.getCode().getConstantPool();
Constant constant = constantPool.getConstant(index);
this.constantTag = constant.getTag();
if (constantTag == Const.CONSTANT_Long) {
ConstantLong constantLong = (ConstantLong) constant;
this.longValue = constantLong.getBytes();
} else if (constantTag == Const.CONSTANT_Double) {
ConstantDouble constantDouble = (ConstantDouble) constant;
this.doubleValue = constantDouble.getBytes();
}
}
@Override
public void execute(Frame frame) {
if (constantTag == Const.CONSTANT_Long) {
frame.push(new StackValue(Const.T_LONG, this.longValue));
} else if (constantTag == Const.CONSTANT_Double) {
frame.push(new StackValue(Const.T_DOUBLE, this.doubleValue));
}
}
}

View File

@@ -0,0 +1,58 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.bcel.Const;
import haidnor.jvm.bcel.classfile.*;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import lombok.SneakyThrows;
/**
* Java VM opcode.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldc_w"> Opcode definitions in
* The Java Virtual Machine Specification</a>
*/
public class LDC_W extends Instruction {
private final int constantIndex;
public LDC_W(CodeStream codeStream) {
super(codeStream);
this.constantIndex = codeStream.readUnsignedShort(this);
}
@Override
@SneakyThrows
public void execute(Frame frame) {
ConstantPool constantPool = frame.getJavaMethod().getConstantPool();
// 从常量池中获取值
Constant constant = constantPool.getConstant(constantIndex);
switch (constant.getTag()) {
case Const.CONSTANT_Integer: {
ConstantInteger constantInteger = (ConstantInteger) constant;
Object value = constantInteger.getConstantValue(constantPool);
frame.push(new StackValue(Const.T_INT, value));
break;
}
case Const.CONSTANT_Float: {
ConstantFloat constantFloat = (ConstantFloat) constant;
Object value = constantFloat.getConstantValue(constantPool);
frame.push(new StackValue(Const.T_FLOAT, value));
break;
}
case Const.CONSTANT_String: {
ConstantString constString = (ConstantString) constant;
Object value = constString.getConstantValue(constantPool);
frame.push(new StackValue(Const.T_OBJECT, value));
break;
}
default:
throw new Error("not supported LDCW type" + constant.getTag());
}
}
}

View File

@@ -0,0 +1,23 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;
/**
* Java VM opcode.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.nop"> Opcode definitions in The
* Java Virtual Machine Specification</a>
*/
public class NOP extends Instruction {
public NOP(CodeStream codeStream) {
super(codeStream);
}
@Override
public void execute(Frame frame) {
}
}

View File

@@ -0,0 +1,29 @@
package haidnor.jvm.instruction.constants;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.bcel.Const;
/**
* Java VM opcode.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.sipush"> Opcode definitions in
* The Java Virtual Machine Specification</a>
*/
public class SIPUSH extends Instruction {
private final int value;
public SIPUSH(CodeStream codeStream) {
super(codeStream);
this.value = codeStream.readShort(this);
}
@Override
public void execute(Frame frame) {
frame.push(new StackValue(Const.T_INT, value));
}
}

View File

@@ -0,0 +1,25 @@
package haidnor.jvm.instruction.control;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.util.JVMThreadHolder;
public class ARETURN extends ReturnableInstruction {
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);
}
}

View File

@@ -0,0 +1,25 @@
package haidnor.jvm.instruction.control;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.util.JVMThreadHolder;
public class DRETURN extends ReturnableInstruction {
public DRETURN(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);
}
}

View File

@@ -0,0 +1,25 @@
package haidnor.jvm.instruction.control;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.util.JVMThreadHolder;
public class FRETURN extends ReturnableInstruction {
public FRETURN(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);
}
}

View File

@@ -0,0 +1,25 @@
package haidnor.jvm.instruction.control;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.util.JVMThreadHolder;
public class IRETURN extends ReturnableInstruction {
public IRETURN(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);
}
}

Some files were not shown because too many files have changed in this diff Show More