mirror of
https://github.com/FranzHaidnor/haidnorJVM.git
synced 2026-03-13 21:43:42 +08:00
update
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
31
src/main/java/haidnor/jvm/instruction/comparisons/DCMPG.java
Normal file
31
src/main/java/haidnor/jvm/instruction/comparisons/DCMPG.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
31
src/main/java/haidnor/jvm/instruction/comparisons/DCMPL.java
Normal file
31
src/main/java/haidnor/jvm/instruction/comparisons/DCMPL.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
30
src/main/java/haidnor/jvm/instruction/comparisons/FCMPG.java
Normal file
30
src/main/java/haidnor/jvm/instruction/comparisons/FCMPG.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
30
src/main/java/haidnor/jvm/instruction/comparisons/FCMPL.java
Normal file
30
src/main/java/haidnor/jvm/instruction/comparisons/FCMPL.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
40
src/main/java/haidnor/jvm/instruction/comparisons/IFEQ.java
Normal file
40
src/main/java/haidnor/jvm/instruction/comparisons/IFEQ.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
34
src/main/java/haidnor/jvm/instruction/comparisons/IFGE.java
Normal file
34
src/main/java/haidnor/jvm/instruction/comparisons/IFGE.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
34
src/main/java/haidnor/jvm/instruction/comparisons/IFGT.java
Normal file
34
src/main/java/haidnor/jvm/instruction/comparisons/IFGT.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
34
src/main/java/haidnor/jvm/instruction/comparisons/IFLE.java
Normal file
34
src/main/java/haidnor/jvm/instruction/comparisons/IFLE.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
34
src/main/java/haidnor/jvm/instruction/comparisons/IFLT.java
Normal file
34
src/main/java/haidnor/jvm/instruction/comparisons/IFLT.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
43
src/main/java/haidnor/jvm/instruction/comparisons/IFNE.java
Normal file
43
src/main/java/haidnor/jvm/instruction/comparisons/IFNE.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
28
src/main/java/haidnor/jvm/instruction/comparisons/LCMP.java
Normal file
28
src/main/java/haidnor/jvm/instruction/comparisons/LCMP.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
29
src/main/java/haidnor/jvm/instruction/constants/BIPUSH.java
Normal file
29
src/main/java/haidnor/jvm/instruction/constants/BIPUSH.java
Normal 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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
58
src/main/java/haidnor/jvm/instruction/constants/LDC.java
Normal file
58
src/main/java/haidnor/jvm/instruction/constants/LDC.java
Normal 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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
48
src/main/java/haidnor/jvm/instruction/constants/LDC2W.java
Normal file
48
src/main/java/haidnor/jvm/instruction/constants/LDC2W.java
Normal 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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
58
src/main/java/haidnor/jvm/instruction/constants/LDC_W.java
Normal file
58
src/main/java/haidnor/jvm/instruction/constants/LDC_W.java
Normal 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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
23
src/main/java/haidnor/jvm/instruction/constants/NOP.java
Normal file
23
src/main/java/haidnor/jvm/instruction/constants/NOP.java
Normal 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) {
|
||||
}
|
||||
|
||||
}
|
||||
29
src/main/java/haidnor/jvm/instruction/constants/SIPUSH.java
Normal file
29
src/main/java/haidnor/jvm/instruction/constants/SIPUSH.java
Normal 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));
|
||||
}
|
||||
|
||||
}
|
||||
25
src/main/java/haidnor/jvm/instruction/control/ARETURN.java
Normal file
25
src/main/java/haidnor/jvm/instruction/control/ARETURN.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
25
src/main/java/haidnor/jvm/instruction/control/DRETURN.java
Normal file
25
src/main/java/haidnor/jvm/instruction/control/DRETURN.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
25
src/main/java/haidnor/jvm/instruction/control/FRETURN.java
Normal file
25
src/main/java/haidnor/jvm/instruction/control/FRETURN.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
25
src/main/java/haidnor/jvm/instruction/control/IRETURN.java
Normal file
25
src/main/java/haidnor/jvm/instruction/control/IRETURN.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package haidnor.jvm.instruction.control;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class LOOKUPSWITCH extends Instruction {
|
||||
|
||||
public LOOKUPSWITCH(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
throw new UnsupportedOperationException("LOOKUPSWITCH");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
throw new UnsupportedOperationException("LOOKUPSWITCH");
|
||||
}
|
||||
|
||||
}
|
||||
25
src/main/java/haidnor/jvm/instruction/control/LRETURN.java
Normal file
25
src/main/java/haidnor/jvm/instruction/control/LRETURN.java
Normal 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 LRETURN extends ReturnableInstruction {
|
||||
|
||||
public LRETURN(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);
|
||||
}
|
||||
|
||||
}
|
||||
28
src/main/java/haidnor/jvm/instruction/control/RET.java
Normal file
28
src/main/java/haidnor/jvm/instruction/control/RET.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package haidnor.jvm.instruction.control;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
/**
|
||||
* RET(Return)指令是 Java 虚拟机中的一条指令,用于从方法中返回并将控制流转移到调用该方法的位置。
|
||||
* <p>
|
||||
* RET 指令在早期版本的 Java 虚拟机中使用,但自从 Java SE 6 版本以后,它已经被废弃不再使用。取而代之的是通过 JSR 和 RET 指令的组合实现的子例程(subroutines)已经被新的字节码指令 invokedynamic 所取代。
|
||||
* <p>
|
||||
* RET 指令需要一个操作数,作为局部变量表(local variable table)中一个给定索引处的值。这个索引通常是由 JSR(Jump SubRoutine)指令记录的,JSR 指令在携带一个偏移量的情况下,会将指令执行的位置压入操作数栈,并跳转到指定的位置。RET 指令则使用这个记录的位置来返回。
|
||||
* <p>
|
||||
* 需要注意的是,由于 RET 指令被废弃,所以在现代的 Java 虚拟机中,解释器或即时编译器会将 RET 指令替换为其他的指令序列来实现相同的功能。
|
||||
*/
|
||||
public class RET extends Instruction {
|
||||
|
||||
public RET(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
throw new UnsupportedOperationException("RET");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
throw new UnsupportedOperationException("RET");
|
||||
}
|
||||
|
||||
}
|
||||
18
src/main/java/haidnor/jvm/instruction/control/RETURN.java
Normal file
18
src/main/java/haidnor/jvm/instruction/control/RETURN.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package haidnor.jvm.instruction.control;
|
||||
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
import haidnor.jvm.util.JVMThreadHolder;
|
||||
|
||||
public class RETURN extends ReturnableInstruction {
|
||||
|
||||
public RETURN(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
JVMThreadHolder.get().pop();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package haidnor.jvm.instruction;
|
||||
package haidnor.jvm.instruction.control;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
/**
|
||||
@@ -0,0 +1,19 @@
|
||||
package haidnor.jvm.instruction.control;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class TABLESWITCH extends Instruction {
|
||||
|
||||
public TABLESWITCH(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
throw new UnsupportedOperationException("TABLESWITCH");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
throw new UnsupportedOperationException("TABLESWITCH");
|
||||
}
|
||||
|
||||
}
|
||||
20
src/main/java/haidnor/jvm/instruction/conversions/D2F.java
Normal file
20
src/main/java/haidnor/jvm/instruction/conversions/D2F.java
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
package haidnor.jvm.instruction.conversions;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class D2F extends Instruction {
|
||||
|
||||
public D2F(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
double doubleVal = frame.popDouble();
|
||||
frame.pushFloat(Double.valueOf(doubleVal).floatValue());
|
||||
}
|
||||
|
||||
}
|
||||
19
src/main/java/haidnor/jvm/instruction/conversions/D2I.java
Normal file
19
src/main/java/haidnor/jvm/instruction/conversions/D2I.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package haidnor.jvm.instruction.conversions;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class D2I extends Instruction {
|
||||
|
||||
public D2I(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
double doubleVal = frame.popDouble();
|
||||
frame.pushInt(Double.valueOf(doubleVal).intValue());
|
||||
}
|
||||
|
||||
}
|
||||
19
src/main/java/haidnor/jvm/instruction/conversions/D2L.java
Normal file
19
src/main/java/haidnor/jvm/instruction/conversions/D2L.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package haidnor.jvm.instruction.conversions;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class D2L extends Instruction {
|
||||
|
||||
public D2L(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
double doubleVal = frame.popDouble();
|
||||
frame.pushLong(Double.valueOf(doubleVal).longValue());
|
||||
}
|
||||
|
||||
}
|
||||
19
src/main/java/haidnor/jvm/instruction/conversions/F2D.java
Normal file
19
src/main/java/haidnor/jvm/instruction/conversions/F2D.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package haidnor.jvm.instruction.conversions;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class F2D extends Instruction {
|
||||
|
||||
public F2D(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
float floatVal = frame.popFloat();
|
||||
frame.pushDouble(Float.valueOf(floatVal).doubleValue());
|
||||
}
|
||||
|
||||
}
|
||||
19
src/main/java/haidnor/jvm/instruction/conversions/F2I.java
Normal file
19
src/main/java/haidnor/jvm/instruction/conversions/F2I.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package haidnor.jvm.instruction.conversions;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class F2I extends Instruction {
|
||||
|
||||
public F2I(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
float floatVal = frame.popFloat();
|
||||
frame.pushInt(Float.valueOf(floatVal).intValue());
|
||||
}
|
||||
|
||||
}
|
||||
19
src/main/java/haidnor/jvm/instruction/conversions/F2L.java
Normal file
19
src/main/java/haidnor/jvm/instruction/conversions/F2L.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package haidnor.jvm.instruction.conversions;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class F2L extends Instruction {
|
||||
|
||||
public F2L(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
float floatVal = frame.popFloat();
|
||||
frame.pushLong(Float.valueOf(floatVal).longValue());
|
||||
}
|
||||
|
||||
}
|
||||
24
src/main/java/haidnor/jvm/instruction/conversions/I2B.java
Normal file
24
src/main/java/haidnor/jvm/instruction/conversions/I2B.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package haidnor.jvm.instruction.conversions;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
/**
|
||||
* JVM中的I2B指令是用于执行将整数类型(int)转换为字节类型(byte)的指令。该指令将一个int类型的数值从操作数栈中弹出,并将其转换为一个字节(byte)。
|
||||
* 然后,将转换后的字节值压入操作数栈顶。
|
||||
* <p>
|
||||
* byte 类型的数据是以 int 形式存在的,因此不需要做任何处理
|
||||
*/
|
||||
public class I2B extends Instruction {
|
||||
|
||||
public I2B(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
21
src/main/java/haidnor/jvm/instruction/conversions/I2C.java
Normal file
21
src/main/java/haidnor/jvm/instruction/conversions/I2C.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package haidnor.jvm.instruction.conversions;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
/**
|
||||
* char 类型的数据是以 int 形式存在的,因此不需要做任何处理
|
||||
*/
|
||||
public class I2C extends Instruction {
|
||||
|
||||
public I2C(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
19
src/main/java/haidnor/jvm/instruction/conversions/I2D.java
Normal file
19
src/main/java/haidnor/jvm/instruction/conversions/I2D.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package haidnor.jvm.instruction.conversions;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class I2D extends Instruction {
|
||||
|
||||
public I2D(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
int intVal = frame.popInt();
|
||||
frame.pushDouble(Integer.valueOf(intVal).doubleValue());
|
||||
}
|
||||
|
||||
}
|
||||
19
src/main/java/haidnor/jvm/instruction/conversions/I2F.java
Normal file
19
src/main/java/haidnor/jvm/instruction/conversions/I2F.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package haidnor.jvm.instruction.conversions;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class I2F extends Instruction {
|
||||
|
||||
public I2F(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
int intVal = frame.popInt();
|
||||
frame.pushFloat(Integer.valueOf(intVal).floatValue());
|
||||
}
|
||||
|
||||
}
|
||||
19
src/main/java/haidnor/jvm/instruction/conversions/I2L.java
Normal file
19
src/main/java/haidnor/jvm/instruction/conversions/I2L.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package haidnor.jvm.instruction.conversions;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class I2L extends Instruction {
|
||||
|
||||
public I2L(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
int intVal = frame.popInt();
|
||||
frame.pushLong(Integer.valueOf(intVal).longValue());
|
||||
}
|
||||
|
||||
}
|
||||
20
src/main/java/haidnor/jvm/instruction/conversions/I2S.java
Normal file
20
src/main/java/haidnor/jvm/instruction/conversions/I2S.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package haidnor.jvm.instruction.conversions;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class I2S extends Instruction {
|
||||
|
||||
public I2S(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
int intVal = frame.popInt();
|
||||
short shortValue = Integer.valueOf(intVal).shortValue();
|
||||
frame.pushInt(((int) shortValue));
|
||||
}
|
||||
|
||||
}
|
||||
19
src/main/java/haidnor/jvm/instruction/conversions/L2D.java
Normal file
19
src/main/java/haidnor/jvm/instruction/conversions/L2D.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package haidnor.jvm.instruction.conversions;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class L2D extends Instruction {
|
||||
|
||||
public L2D(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
long longVal = frame.popLong();
|
||||
frame.pushDouble(Long.valueOf(longVal).doubleValue());
|
||||
}
|
||||
|
||||
}
|
||||
19
src/main/java/haidnor/jvm/instruction/conversions/L2F.java
Normal file
19
src/main/java/haidnor/jvm/instruction/conversions/L2F.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package haidnor.jvm.instruction.conversions;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class L2F extends Instruction {
|
||||
|
||||
public L2F(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
long longVal = frame.popLong();
|
||||
frame.pushFloat(Long.valueOf(longVal).floatValue());
|
||||
}
|
||||
|
||||
}
|
||||
19
src/main/java/haidnor/jvm/instruction/conversions/L2I.java
Normal file
19
src/main/java/haidnor/jvm/instruction/conversions/L2I.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package haidnor.jvm.instruction.conversions;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class L2I extends Instruction {
|
||||
|
||||
public L2I(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
long longVal = frame.popLong();
|
||||
frame.pushInt(Long.valueOf(longVal).intValue());
|
||||
}
|
||||
|
||||
}
|
||||
33
src/main/java/haidnor/jvm/instruction/extended/GOTO.java
Normal file
33
src/main/java/haidnor/jvm/instruction/extended/GOTO.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package haidnor.jvm.instruction.extended;
|
||||
|
||||
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.goto"> Opcode definitions in
|
||||
* The Java Virtual Machine Specification</a>
|
||||
*/
|
||||
public class GOTO extends Instruction {
|
||||
/**
|
||||
* 下次再执行的偏移量
|
||||
*/
|
||||
private final int offSet;
|
||||
|
||||
public GOTO(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
this.offSet = codeStream.readShort(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
super.setOffSet(offSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.getIndex() + " " + this.getClass().getSimpleName() + " " + offSet;
|
||||
}
|
||||
}
|
||||
27
src/main/java/haidnor/jvm/instruction/extended/GOTO_W.java
Normal file
27
src/main/java/haidnor/jvm/instruction/extended/GOTO_W.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package haidnor.jvm.instruction.extended;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class GOTO_W extends Instruction {
|
||||
/**
|
||||
* 下次再执行的偏移量
|
||||
*/
|
||||
private final int offSet;
|
||||
|
||||
public GOTO_W(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
this.offSet = codeStream.readInt(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
super.setOffSet(offSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.getIndex() + " " + this.getClass().getSimpleName() + " " + offSet;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package haidnor.jvm.instruction.extended;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.runtime.StackValue;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class IFNONNULL extends Instruction {
|
||||
/**
|
||||
* 下次再执行的偏移量
|
||||
*/
|
||||
private final int offSet;
|
||||
|
||||
public IFNONNULL(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
this.offSet = codeStream.readShort(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
StackValue v1 = frame.pop();
|
||||
if (v1.getValue() != null) {
|
||||
super.setOffSet(offSet);
|
||||
} else {
|
||||
super.setOffSet(3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.getIndex() + " " + this.getClass().getSimpleName() + " " + offSet;
|
||||
}
|
||||
}
|
||||
33
src/main/java/haidnor/jvm/instruction/extended/IFNULL.java
Normal file
33
src/main/java/haidnor/jvm/instruction/extended/IFNULL.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package haidnor.jvm.instruction.extended;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.runtime.StackValue;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class IFNULL extends Instruction {
|
||||
/**
|
||||
* 下次再执行的偏移量
|
||||
*/
|
||||
private final int offSet;
|
||||
|
||||
public IFNULL(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
this.offSet = codeStream.readShort(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
StackValue v1 = frame.pop();
|
||||
if (v1.getValue() == null) {
|
||||
super.setOffSet(offSet);
|
||||
} else {
|
||||
super.setOffSet(3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.getIndex() + " " + this.getClass().getSimpleName() + " " + offSet;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package haidnor.jvm.instruction.extended;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class MULTIANEWARRAY extends Instruction {
|
||||
|
||||
public final int index;
|
||||
public final int dimensions;
|
||||
|
||||
public MULTIANEWARRAY(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
this.index = codeStream.readUnsignedShort(this);
|
||||
this.dimensions = codeStream.readUnsignedByte(this);
|
||||
|
||||
throw new UnsupportedOperationException("MULTIANEWARRAY");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
throw new UnsupportedOperationException("MULTIANEWARRAY");
|
||||
}
|
||||
|
||||
}
|
||||
40
src/main/java/haidnor/jvm/instruction/extended/WIDE.java
Normal file
40
src/main/java/haidnor/jvm/instruction/extended/WIDE.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package haidnor.jvm.instruction.extended;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.instruction.loads.*;
|
||||
import haidnor.jvm.instruction.math.IINC;
|
||||
import haidnor.jvm.instruction.stores.*;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
public class WIDE extends Instruction {
|
||||
|
||||
private final Instruction instruction;
|
||||
|
||||
public WIDE(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
int wideOpcode = codeStream.readShort(this);
|
||||
|
||||
switch (wideOpcode) {
|
||||
case 0x84 -> instruction = new IINC(codeStream);
|
||||
case 0x15 -> instruction = new ILOAD(codeStream);
|
||||
case 0x17 -> instruction = new FLOAD(codeStream);
|
||||
case 0x19 -> instruction = new ALOAD(codeStream);
|
||||
case 0x16 -> instruction = new LLOAD(codeStream);
|
||||
case 0x18 -> instruction = new DLOAD(codeStream);
|
||||
case 0x36 -> instruction = new ISTORE(codeStream);
|
||||
case 0x38 -> instruction = new FSTORE(codeStream);
|
||||
case 0x3a -> instruction = new ASTORE(codeStream);
|
||||
case 0x37 -> instruction = new LSTORE(codeStream);
|
||||
case 0x39 -> instruction = new DSTORE(codeStream);
|
||||
case 0xa9 -> throw new UnsupportedOperationException(); // ret, ignore
|
||||
default -> throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
instruction.execute(frame);
|
||||
}
|
||||
|
||||
}
|
||||
24
src/main/java/haidnor/jvm/instruction/loads/AALOAD.java
Normal file
24
src/main/java/haidnor/jvm/instruction/loads/AALOAD.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.rtda.Instance;
|
||||
import haidnor.jvm.rtda.InstanceArray;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
|
||||
public class AALOAD extends Instruction {
|
||||
|
||||
public AALOAD(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
int index = frame.popInt();
|
||||
InstanceArray array = (InstanceArray) frame.popRef();
|
||||
Instance item = array.items[index];
|
||||
frame.pushRef(item);
|
||||
}
|
||||
|
||||
}
|
||||
25
src/main/java/haidnor/jvm/instruction/loads/ALOAD.java
Normal file
25
src/main/java/haidnor/jvm/instruction/loads/ALOAD.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
public class ALOAD extends Instruction {
|
||||
|
||||
private final int index;
|
||||
|
||||
public ALOAD(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
this.index = codeStream.readUnsignedByte(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
Object value = frame.slotGetRef(index);
|
||||
frame.push(new StackValue(Const.T_OBJECT, value));
|
||||
}
|
||||
|
||||
}
|
||||
21
src/main/java/haidnor/jvm/instruction/loads/ALOAD_0.java
Normal file
21
src/main/java/haidnor/jvm/instruction/loads/ALOAD_0.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
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;
|
||||
|
||||
public class ALOAD_0 extends Instruction {
|
||||
|
||||
public ALOAD_0(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
Object value = frame.slotGetRef(0);
|
||||
frame.push(new StackValue(Const.T_OBJECT, value));
|
||||
}
|
||||
|
||||
}
|
||||
21
src/main/java/haidnor/jvm/instruction/loads/ALOAD_1.java
Normal file
21
src/main/java/haidnor/jvm/instruction/loads/ALOAD_1.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
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;
|
||||
|
||||
public class ALOAD_1 extends Instruction {
|
||||
|
||||
public ALOAD_1(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
Object value = frame.slotGetRef(1);
|
||||
frame.push(new StackValue(Const.T_OBJECT, value));
|
||||
}
|
||||
|
||||
}
|
||||
21
src/main/java/haidnor/jvm/instruction/loads/ALOAD_2.java
Normal file
21
src/main/java/haidnor/jvm/instruction/loads/ALOAD_2.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
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;
|
||||
|
||||
public class ALOAD_2 extends Instruction {
|
||||
|
||||
public ALOAD_2(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
Object value = frame.slotGetRef(2);
|
||||
frame.push(new StackValue(Const.T_OBJECT, value));
|
||||
}
|
||||
|
||||
}
|
||||
21
src/main/java/haidnor/jvm/instruction/loads/ALOAD_3.java
Normal file
21
src/main/java/haidnor/jvm/instruction/loads/ALOAD_3.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
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;
|
||||
|
||||
public class ALOAD_3 extends Instruction {
|
||||
|
||||
public ALOAD_3(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
Object value = frame.slotGetRef(3);
|
||||
frame.push(new StackValue(Const.T_OBJECT, value));
|
||||
}
|
||||
|
||||
}
|
||||
22
src/main/java/haidnor/jvm/instruction/loads/BALOAD.java
Normal file
22
src/main/java/haidnor/jvm/instruction/loads/BALOAD.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.rtda.BasicTypeArray;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
|
||||
public class BALOAD extends Instruction {
|
||||
|
||||
public BALOAD(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
int index = frame.popInt();
|
||||
BasicTypeArray array = (BasicTypeArray) frame.popRef();
|
||||
frame.pushInt(array.ints[index]);
|
||||
}
|
||||
|
||||
}
|
||||
22
src/main/java/haidnor/jvm/instruction/loads/CALOAD.java
Normal file
22
src/main/java/haidnor/jvm/instruction/loads/CALOAD.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.rtda.BasicTypeArray;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
|
||||
public class CALOAD extends Instruction {
|
||||
|
||||
public CALOAD(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
int index = frame.popInt();
|
||||
BasicTypeArray array = (BasicTypeArray) frame.popRef();
|
||||
frame.pushInt(array.ints[index]);
|
||||
}
|
||||
|
||||
}
|
||||
22
src/main/java/haidnor/jvm/instruction/loads/DALOAD.java
Normal file
22
src/main/java/haidnor/jvm/instruction/loads/DALOAD.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.rtda.BasicTypeArray;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
|
||||
public class DALOAD extends Instruction {
|
||||
|
||||
public DALOAD(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
int index = frame.popInt();
|
||||
BasicTypeArray array = (BasicTypeArray) frame.popRef();
|
||||
frame.pushDouble(array.doubles[index]);
|
||||
}
|
||||
|
||||
}
|
||||
25
src/main/java/haidnor/jvm/instruction/loads/DLOAD.java
Normal file
25
src/main/java/haidnor/jvm/instruction/loads/DLOAD.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
public class DLOAD extends Instruction {
|
||||
|
||||
private final int index;
|
||||
|
||||
public DLOAD(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
this.index = codeStream.readUnsignedByte(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
double value = frame.slotGetDouble(index);
|
||||
frame.push(new StackValue(Const.T_DOUBLE, value));
|
||||
}
|
||||
|
||||
}
|
||||
21
src/main/java/haidnor/jvm/instruction/loads/DLOAD_0.java
Normal file
21
src/main/java/haidnor/jvm/instruction/loads/DLOAD_0.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
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;
|
||||
|
||||
public class DLOAD_0 extends Instruction {
|
||||
|
||||
public DLOAD_0(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
double value = frame.slotGetDouble(0);
|
||||
frame.push(new StackValue(Const.T_DOUBLE, value));
|
||||
}
|
||||
|
||||
}
|
||||
21
src/main/java/haidnor/jvm/instruction/loads/DLOAD_1.java
Normal file
21
src/main/java/haidnor/jvm/instruction/loads/DLOAD_1.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
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;
|
||||
|
||||
public class DLOAD_1 extends Instruction {
|
||||
|
||||
public DLOAD_1(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
double value = frame.slotGetDouble(1);
|
||||
frame.push(new StackValue(Const.T_DOUBLE, value));
|
||||
}
|
||||
|
||||
}
|
||||
21
src/main/java/haidnor/jvm/instruction/loads/DLOAD_2.java
Normal file
21
src/main/java/haidnor/jvm/instruction/loads/DLOAD_2.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
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;
|
||||
|
||||
public class DLOAD_2 extends Instruction {
|
||||
|
||||
public DLOAD_2(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
double value = frame.slotGetDouble(2);
|
||||
frame.push(new StackValue(Const.T_DOUBLE, value));
|
||||
}
|
||||
|
||||
}
|
||||
21
src/main/java/haidnor/jvm/instruction/loads/DLOAD_3.java
Normal file
21
src/main/java/haidnor/jvm/instruction/loads/DLOAD_3.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
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;
|
||||
|
||||
public class DLOAD_3 extends Instruction {
|
||||
|
||||
public DLOAD_3(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
double value = frame.slotGetDouble(3);
|
||||
frame.push(new StackValue(Const.T_DOUBLE, value));
|
||||
}
|
||||
|
||||
}
|
||||
22
src/main/java/haidnor/jvm/instruction/loads/FALOAD.java
Normal file
22
src/main/java/haidnor/jvm/instruction/loads/FALOAD.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.rtda.BasicTypeArray;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
|
||||
public class FALOAD extends Instruction {
|
||||
|
||||
public FALOAD(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
int index = frame.popInt();
|
||||
BasicTypeArray array = (BasicTypeArray) frame.popRef();
|
||||
frame.pushFloat(array.floats[index]);
|
||||
}
|
||||
|
||||
}
|
||||
25
src/main/java/haidnor/jvm/instruction/loads/FLOAD.java
Normal file
25
src/main/java/haidnor/jvm/instruction/loads/FLOAD.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
public class FLOAD extends Instruction {
|
||||
|
||||
private final int index;
|
||||
|
||||
public FLOAD(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
this.index = codeStream.readUnsignedByte(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
float value = frame.slotGetFloat(index);
|
||||
frame.push(new StackValue(Const.T_FLOAT, value));
|
||||
}
|
||||
|
||||
}
|
||||
21
src/main/java/haidnor/jvm/instruction/loads/FLOAD_0.java
Normal file
21
src/main/java/haidnor/jvm/instruction/loads/FLOAD_0.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
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;
|
||||
|
||||
public class FLOAD_0 extends Instruction {
|
||||
|
||||
public FLOAD_0(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
float value = frame.slotGetFloat(0);
|
||||
frame.push(new StackValue(Const.T_FLOAT, value));
|
||||
}
|
||||
|
||||
}
|
||||
21
src/main/java/haidnor/jvm/instruction/loads/FLOAD_1.java
Normal file
21
src/main/java/haidnor/jvm/instruction/loads/FLOAD_1.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
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;
|
||||
|
||||
public class FLOAD_1 extends Instruction {
|
||||
|
||||
public FLOAD_1(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
float value = frame.slotGetFloat(1);
|
||||
frame.push(new StackValue(Const.T_FLOAT, value));
|
||||
}
|
||||
|
||||
}
|
||||
21
src/main/java/haidnor/jvm/instruction/loads/FLOAD_2.java
Normal file
21
src/main/java/haidnor/jvm/instruction/loads/FLOAD_2.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
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;
|
||||
|
||||
public class FLOAD_2 extends Instruction {
|
||||
|
||||
public FLOAD_2(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
float value = frame.slotGetFloat(2);
|
||||
frame.push(new StackValue(Const.T_FLOAT, value));
|
||||
}
|
||||
|
||||
}
|
||||
21
src/main/java/haidnor/jvm/instruction/loads/FLOAD_3.java
Normal file
21
src/main/java/haidnor/jvm/instruction/loads/FLOAD_3.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
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;
|
||||
|
||||
public class FLOAD_3 extends Instruction {
|
||||
|
||||
public FLOAD_3(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
float value = frame.slotGetFloat(3);
|
||||
frame.push(new StackValue(Const.T_FLOAT, value));
|
||||
}
|
||||
|
||||
}
|
||||
22
src/main/java/haidnor/jvm/instruction/loads/IALOAD.java
Normal file
22
src/main/java/haidnor/jvm/instruction/loads/IALOAD.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.rtda.BasicTypeArray;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
|
||||
public class IALOAD extends Instruction {
|
||||
|
||||
public IALOAD(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
int index = frame.popInt();
|
||||
BasicTypeArray array = (BasicTypeArray) frame.popRef();
|
||||
frame.pushInt(array.ints[index]);
|
||||
}
|
||||
|
||||
}
|
||||
25
src/main/java/haidnor/jvm/instruction/loads/ILOAD.java
Normal file
25
src/main/java/haidnor/jvm/instruction/loads/ILOAD.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
public class ILOAD extends Instruction {
|
||||
|
||||
private final int index;
|
||||
|
||||
public ILOAD(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
this.index = codeStream.readUnsignedByte(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
int value = frame.slotGetInt(index);
|
||||
frame.push(new StackValue(Const.T_INT, value));
|
||||
}
|
||||
|
||||
}
|
||||
24
src/main/java/haidnor/jvm/instruction/loads/ILOAD_0.java
Normal file
24
src/main/java/haidnor/jvm/instruction/loads/ILOAD_0.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package haidnor.jvm.instruction.loads;
|
||||
|
||||
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/se8/html/jvms-6.html#jvms-6.5.iload_n
|
||||
*/
|
||||
public class ILOAD_0 extends Instruction {
|
||||
|
||||
public ILOAD_0(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
int value = frame.slotGetInt(0);
|
||||
frame.push(new StackValue(Const.T_INT, value));
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user