mirror of
https://github.com/FranzHaidnor/haidnorJVM.git
synced 2026-03-23 13:23:41 +08:00
Initial commit
This commit is contained in:
38
.gitignore
vendored
Normal file
38
.gitignore
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/libraries/
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
||||||
64
README.md
Normal file
64
README.md
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
# haidnorJVM
|
||||||
|
使用 Java17 编写的 Java 虚拟机
|
||||||
|
|
||||||
|
## 意义
|
||||||
|
1. 纸上得来终觉浅,绝知此事要躬行。只学习 JVM 机制和理论,很多时候任然觉得缺乏那种大彻大悟之感
|
||||||
|
2. 使用简单的方式实现 JVM,用于学习理解 JVM 运行原理
|
||||||
|
|
||||||
|
## 主要技术选型
|
||||||
|
* [Java 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
|
||||||
|
* [Apache Commons BCEL](https://commons.apache.org/proper/commons-bcel/)
|
||||||
|
* [Apache Commons CLI](https://commons.apache.org/proper/commons-cli/)
|
||||||
|
|
||||||
|
# 实现功能与局限性
|
||||||
|
* 支持基本数据类型数学运算
|
||||||
|
* 支持循环、条件结构代码
|
||||||
|
* 支持创建对象,访问对象
|
||||||
|
* 支持多态
|
||||||
|
* 支持访问静态方法
|
||||||
|
* 不支持多线程
|
||||||
|
* 垃圾回收依靠宿主 JVM
|
||||||
|
|
||||||
|
# 快速体验
|
||||||
|
## 你需要准备什么
|
||||||
|
1. 集成开发环境 (IDE)。你可以选择包括 IntelliJ IDEA、Spring Tools、Visual Studio Code 或 Eclipse 等等
|
||||||
|
2. JDK 17。并配置 JAVA_HOME
|
||||||
|
3. JDK 8。强烈推荐! haidnorJVM 的主要目标是运行 Java8 本版的字节码文件。(haidnorVM 没有强制要求字节码文件是 Java8 版本)
|
||||||
|
4. Maven
|
||||||
|
|
||||||
|
## 配置 haidnorJVM
|
||||||
|
### 配置日志输出级别
|
||||||
|
修改 `simplelogger.properties` 文件中的内容。配置日志输出级别,一般使用 `debug`、`info`
|
||||||
|
|
||||||
|
### 配置 rt.jar
|
||||||
|
修改 `haidnorJVM.properties` 文件中的内容。配置 rt.jar 的绝对路径,例如`rt.jar=D:/Program Files/Java/jdk1.8.0_361/jre/lib/rt.jar`
|
||||||
|
|
||||||
|
## 运行单元测试用例
|
||||||
|
打开 test 目录下的 `haidnor.jvm.test.TestJVM` 类文件。 这是 haidnorJVM 功能的主要测试类。 里面的测试方法可以解析并加载一些class字节码文件。
|
||||||
|
```java
|
||||||
|
@Test
|
||||||
|
public void test_LSUB() throws Exception {
|
||||||
|
runMainClass(LSUB.class);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
例如以上代码会加载 LSUB.class 类在 target 目录下的字节码文件,然后使用 haidnorJVM 运行其中的 main 函数。你可以使用打断点的方式看到 haidnorJVM 是如何解释运行 Java 字节码的。
|
||||||
|
值得注意的是,这种方式编译运行的字节码文件是基于 java17 版本的。
|
||||||
|
|
||||||
|
## 运行 .class 文件
|
||||||
|
1. 使用 maven 命令将项目编译打包,得到 `haidnorJVM-1.0.jar` 文件
|
||||||
|
2. 编写一个简单的程序,例如以下代码
|
||||||
|
```java
|
||||||
|
public class HelloWorld {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println("HelloWorld");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
3. 编译代码,得到 HelloWorld.class 文件。(推荐使用 JDK8 进行编译)
|
||||||
|
4. 使用 haidnorJVM 运行程序。执行命令 `java -jar haidnorJVM-1.0-SNAPSHOT.jar -class R:\HelloWorld.class`。注意需要 class 文件的绝对路径
|
||||||
|
|
||||||
|
## 运行 .jar 文件
|
||||||
|
开发中...
|
||||||
|
|
||||||
|
# 联系作者
|
||||||
|
个人微信账号: haidnor (请备注 "JVM")
|
||||||
86
pom.xml
Normal file
86
pom.xml
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>haindor.vm</groupId>
|
||||||
|
<artifactId>haidnorJVM</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- https://mvnrepository.com/artifact/commons-cli/commons-cli -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-cli</groupId>
|
||||||
|
<artifactId>commons-cli</artifactId>
|
||||||
|
<version>1.5.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.apache.bcel/bcel -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.bcel</groupId>
|
||||||
|
<artifactId>bcel</artifactId>
|
||||||
|
<version>6.7.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.26</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>2.0.7</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-simple -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-simple</artifactId>
|
||||||
|
<version>2.0.7</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.13.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>2.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<transformers>
|
||||||
|
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||||
|
<mainClass>haidnor.jvm.Main</mainClass>
|
||||||
|
</transformer>
|
||||||
|
</transformers>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
48
src/main/java/haidnor/jvm/Main.java
Normal file
48
src/main/java/haidnor/jvm/Main.java
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package haidnor.jvm;
|
||||||
|
|
||||||
|
import haidnor.jvm.classloader.ClassLoader;
|
||||||
|
import haidnor.jvm.core.JavaExecutionEngine;
|
||||||
|
import haidnor.jvm.rtda.heap.Klass;
|
||||||
|
import haidnor.jvm.rtda.heap.KlassMethod;
|
||||||
|
import haidnor.jvm.rtda.metaspace.Metaspace;
|
||||||
|
import haidnor.jvm.runtime.JvmThread;
|
||||||
|
import haidnor.jvm.util.JavaClassUtil;
|
||||||
|
import haidnor.jvm.util.JvmThreadHolder;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.cli.*;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Option jarOption = new Option("jar", true, "运行 jar 程序");
|
||||||
|
Option classOption = new Option("class", true, "运行 .class 字节码文件");
|
||||||
|
|
||||||
|
OptionGroup optionGroup = new OptionGroup();
|
||||||
|
optionGroup.addOption(jarOption).addOption(classOption);
|
||||||
|
|
||||||
|
Options options = new Options();
|
||||||
|
options.addOptionGroup(optionGroup);
|
||||||
|
|
||||||
|
CommandLineParser parser = new DefaultParser();
|
||||||
|
CommandLine cmd = parser.parse(options, args);
|
||||||
|
|
||||||
|
if (cmd.hasOption("jar")) {
|
||||||
|
String path = cmd.getOptionValue("jar");
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
if (cmd.hasOption("class")) {
|
||||||
|
String path = cmd.getOptionValue("class");
|
||||||
|
ClassLoader bootClassLoader = new ClassLoader("ApplicationClassLoader");
|
||||||
|
Klass mainMeteKlass = bootClassLoader.loadClassWithAbsolutePath(path);
|
||||||
|
KlassMethod mainKlassMethod = JavaClassUtil.getMainMethod(mainMeteKlass);
|
||||||
|
Metaspace.registerJavaClass(mainMeteKlass);
|
||||||
|
JvmThreadHolder.set(new JvmThread());
|
||||||
|
|
||||||
|
JavaExecutionEngine.callMainStaticMethod(mainKlassMethod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package haidnor.jvm.classloader;
|
||||||
|
|
||||||
|
public class BootstrapClassLoader {
|
||||||
|
|
||||||
|
}
|
||||||
82
src/main/java/haidnor/jvm/classloader/ClassLoader.java
Normal file
82
src/main/java/haidnor/jvm/classloader/ClassLoader.java
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package haidnor.jvm.classloader;
|
||||||
|
|
||||||
|
import haidnor.jvm.rtda.heap.Klass;
|
||||||
|
import haidnor.jvm.rtda.metaspace.Metaspace;
|
||||||
|
import org.apache.bcel.classfile.ClassParser;
|
||||||
|
import org.apache.bcel.classfile.JavaClass;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class ClassLoader {
|
||||||
|
|
||||||
|
public final String name;
|
||||||
|
|
||||||
|
public final static String rtJarPath;
|
||||||
|
|
||||||
|
static {
|
||||||
|
URL resource = ClassLoader.class.getResource("/");
|
||||||
|
String path = resource.getPath();
|
||||||
|
FileInputStream fis;
|
||||||
|
try {
|
||||||
|
fis = new FileInputStream(path + "/haidnorJVM.properties");
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
Properties properties = new Properties();
|
||||||
|
try {
|
||||||
|
properties.load(fis);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
rtJarPath = properties.getProperty("rt.jar");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassLoader(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param classPath 类路径,例如 haidnor/jvm/classloader/ClassLoader
|
||||||
|
*/
|
||||||
|
public Klass loadClass(String classPath) throws IOException {
|
||||||
|
ClassParser classParser;
|
||||||
|
if (classPath.startsWith("java/")) {
|
||||||
|
String rtJarPath = getRtJarPath();
|
||||||
|
|
||||||
|
if (!new File(rtJarPath).exists()) {
|
||||||
|
throw new IllegalStateException("rt.jar not found");
|
||||||
|
}
|
||||||
|
classParser = new ClassParser(rtJarPath, classPath + ".class");
|
||||||
|
} else {
|
||||||
|
URL resource = this.getClass().getResource("/");
|
||||||
|
String fileName = resource.getPath() + classPath + ".class";
|
||||||
|
classParser = new ClassParser(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
JavaClass javaClass = classParser.parse();
|
||||||
|
Klass klass = new Klass(this, javaClass);
|
||||||
|
Metaspace.registerJavaClass(klass);
|
||||||
|
return klass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Klass loadClassWithAbsolutePath(String absolutePath) throws IOException {
|
||||||
|
ClassParser classParser = new ClassParser(absolutePath);
|
||||||
|
JavaClass javaClass = classParser.parse();
|
||||||
|
Klass klass = new Klass(this, javaClass);
|
||||||
|
Metaspace.registerJavaClass(klass);
|
||||||
|
return klass;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRtJarPath() {
|
||||||
|
// String javaHome = System.getenv("JAVA_HOME");
|
||||||
|
// Path rtJarPath = Paths.get(javaHome, "jre", "lib", "rt.jar");
|
||||||
|
return rtJarPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
49
src/main/java/haidnor/jvm/core/Interpreter.java
Normal file
49
src/main/java/haidnor/jvm/core/Interpreter.java
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package haidnor.jvm.core;
|
||||||
|
|
||||||
|
import haidnor.jvm.instruction.Instruction;
|
||||||
|
import haidnor.jvm.instruction.InstructionFactory;
|
||||||
|
import haidnor.jvm.instruction.control.RETURN;
|
||||||
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.util.CodeStream;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字节码执行解释器
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class Interpreter {
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public static void executeFrame(Frame frame) {
|
||||||
|
log.debug("------------------------------ Frame START {}", frame.hashCode());
|
||||||
|
Map<Integer, Instruction> instructionMap = new HashMap<>();
|
||||||
|
|
||||||
|
// 解析方法中的字节码指令
|
||||||
|
log.debug(">>>>>>>>>>>>>>>> PARSE INST START");
|
||||||
|
CodeStream codeStream = frame.getCodeStream();
|
||||||
|
while (codeStream.available() > 0) {
|
||||||
|
Instruction instruction = InstructionFactory.creatInstruction(codeStream);
|
||||||
|
log.debug("{}", instruction);
|
||||||
|
instructionMap.put(instruction.index(), instruction);
|
||||||
|
}
|
||||||
|
log.debug(">>>>>>>>>>>>>>>> PARSE INST END");
|
||||||
|
|
||||||
|
// 执行方法中的字节码指令
|
||||||
|
// int i, 相当于程序计数器, 记录当前执行到的字节码指令的”行号“
|
||||||
|
for (int i = 0; i < frame.getCodeLength(); ) {
|
||||||
|
Instruction instruction = instructionMap.get(i);
|
||||||
|
log.debug("{}", instruction);
|
||||||
|
instruction.execute(frame);
|
||||||
|
if (instruction instanceof RETURN) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i += instruction.offSet();
|
||||||
|
}
|
||||||
|
log.debug("------------------------------ Frame End {}", frame.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
57
src/main/java/haidnor/jvm/core/JavaExecutionEngine.java
Normal file
57
src/main/java/haidnor/jvm/core/JavaExecutionEngine.java
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
package haidnor.jvm.core;
|
||||||
|
|
||||||
|
|
||||||
|
import haidnor.jvm.rtda.heap.KlassMethod;
|
||||||
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.runtime.JvmThread;
|
||||||
|
import haidnor.jvm.runtime.StackValue;
|
||||||
|
import haidnor.jvm.util.JvmThreadHolder;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.bcel.classfile.LocalVariable;
|
||||||
|
import org.apache.bcel.classfile.LocalVariableTable;
|
||||||
|
import org.apache.bcel.classfile.Method;
|
||||||
|
import org.apache.bcel.classfile.Utility;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class JavaExecutionEngine {
|
||||||
|
|
||||||
|
public static void callMainStaticMethod(KlassMethod klassMethod) {
|
||||||
|
JvmThread jvmThread = JvmThreadHolder.get();
|
||||||
|
// 每个栈帧中包含一个指向运行时常量池中该栈帧所属的方法的引用。包含这个引用的目的就是为了支持当前方法实现动态链接
|
||||||
|
// 有了这个引用,执行引擎就可以找到指定的方法,加载字节码指令
|
||||||
|
Frame frame = new Frame(jvmThread, klassMethod);
|
||||||
|
jvmThread.push(frame);
|
||||||
|
Interpreter.executeFrame(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void callMethod(Frame lastFrame, KlassMethod klassMethod) {
|
||||||
|
JvmThread jvmThread = JvmThreadHolder.get();
|
||||||
|
Frame newFrame = new Frame(jvmThread, klassMethod);
|
||||||
|
|
||||||
|
Method method = klassMethod.javaMethod;
|
||||||
|
String signature = method.getSignature();
|
||||||
|
String[] argumentTypes = Utility.methodSignatureArgumentTypes(signature);
|
||||||
|
|
||||||
|
int argumentSlotSize = argumentTypes.length;
|
||||||
|
if (!method.isStatic()) {
|
||||||
|
argumentSlotSize++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 静态方法调用传参
|
||||||
|
// 将上一个栈帧操作数栈中数据弹出,存入下一个栈帧的局部变量表中
|
||||||
|
LocalVariableTable localVariableTable = method.getLocalVariableTable();
|
||||||
|
if (localVariableTable != null) {
|
||||||
|
for (int i = argumentSlotSize - 1; i >= 0; i--) {
|
||||||
|
LocalVariable[] localVariableArr = localVariableTable.getLocalVariableTable();
|
||||||
|
LocalVariable localVariable = localVariableArr[i];
|
||||||
|
int slotIndex = localVariable.getIndex();
|
||||||
|
StackValue stackValue = lastFrame.pop();
|
||||||
|
newFrame.slotSet(slotIndex, stackValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jvmThread.push(newFrame);
|
||||||
|
Interpreter.executeFrame(newFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
40
src/main/java/haidnor/jvm/instruction/Instruction.java
Normal file
40
src/main/java/haidnor/jvm/instruction/Instruction.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package haidnor.jvm.instruction;
|
||||||
|
|
||||||
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.util.CodeStream;
|
||||||
|
|
||||||
|
public abstract class Instruction {
|
||||||
|
/**
|
||||||
|
* 指令坐在 code 数组中的索引下标
|
||||||
|
*/
|
||||||
|
private final int index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行下一个执行的偏移量
|
||||||
|
*/
|
||||||
|
private int offSet = 1;
|
||||||
|
|
||||||
|
public Instruction(CodeStream codeStream) {
|
||||||
|
this.index = codeStream.index();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void execute(Frame frame);
|
||||||
|
|
||||||
|
public int index() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int offSet() {
|
||||||
|
return this.offSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffSet(int offSet) {
|
||||||
|
this.offSet = offSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return index + " " + this.getClass().getSimpleName();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
631
src/main/java/haidnor/jvm/instruction/InstructionFactory.java
Normal file
631
src/main/java/haidnor/jvm/instruction/InstructionFactory.java
Normal file
@@ -0,0 +1,631 @@
|
|||||||
|
package haidnor.jvm.instruction;
|
||||||
|
|
||||||
|
import haidnor.jvm.instruction.comparisons.*;
|
||||||
|
import haidnor.jvm.instruction.constants.*;
|
||||||
|
import haidnor.jvm.instruction.control.*;
|
||||||
|
import haidnor.jvm.instruction.conversions.*;
|
||||||
|
import haidnor.jvm.instruction.extended.GOTO;
|
||||||
|
import haidnor.jvm.instruction.extended.GOTO_W;
|
||||||
|
import haidnor.jvm.instruction.extended.IFNONNULL;
|
||||||
|
import haidnor.jvm.instruction.extended.IFNULL;
|
||||||
|
import haidnor.jvm.instruction.loads.*;
|
||||||
|
import haidnor.jvm.instruction.math.*;
|
||||||
|
import haidnor.jvm.instruction.references.*;
|
||||||
|
import haidnor.jvm.instruction.stack.*;
|
||||||
|
import haidnor.jvm.instruction.stores.*;
|
||||||
|
import haidnor.jvm.util.CodeStream;
|
||||||
|
import org.apache.bcel.Const;
|
||||||
|
|
||||||
|
public abstract class InstructionFactory {
|
||||||
|
|
||||||
|
public static Instruction creatInstruction(CodeStream codeStream) {
|
||||||
|
int opcode = codeStream.readJavaVmOpcode();
|
||||||
|
switch (opcode) {
|
||||||
|
case Const.NOP -> {
|
||||||
|
return new NOP(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ACONST_NULL -> {
|
||||||
|
return new ACONST_NULL(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ICONST_M1 -> {
|
||||||
|
return new ICONST_M1(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ICONST_0 -> {
|
||||||
|
return new ICONST_0(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ICONST_1 -> {
|
||||||
|
return new ICONST_1(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ICONST_2 -> {
|
||||||
|
return new ICONST_2(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ICONST_3 -> {
|
||||||
|
return new ICONST_3(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ICONST_4 -> {
|
||||||
|
return new ICONST_4(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ICONST_5 -> {
|
||||||
|
return new ICONST_5(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LCONST_0 -> {
|
||||||
|
return new LCONST_0(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LCONST_1 -> {
|
||||||
|
return new LCONST_1(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FCONST_1 -> {
|
||||||
|
return new FCONST_1(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FCONST_2 -> {
|
||||||
|
return new FCONST_2(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DCONST_0 -> {
|
||||||
|
return new DCONST_0(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DCONST_1 -> {
|
||||||
|
return new DCONST_1(codeStream);
|
||||||
|
}
|
||||||
|
case Const.BIPUSH -> {
|
||||||
|
return new BIPUSH(codeStream);
|
||||||
|
}
|
||||||
|
case Const.SIPUSH -> {
|
||||||
|
return new SIPUSH(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LDC -> {
|
||||||
|
return new LDC(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LDC_W -> {
|
||||||
|
return new LDC_W(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LDC2_W -> {
|
||||||
|
return new LDC2W(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ILOAD -> {
|
||||||
|
return new ILOAD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LLOAD -> {
|
||||||
|
return new LLOAD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FLOAD -> {
|
||||||
|
return new FLOAD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DLOAD -> {
|
||||||
|
return new DLOAD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ALOAD -> {
|
||||||
|
return new ALOAD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ILOAD_0 -> {
|
||||||
|
return new ILOAD_0(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ILOAD_1 -> {
|
||||||
|
return new ILOAD_1(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ILOAD_2 -> {
|
||||||
|
return new ILOAD_2(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ILOAD_3 -> {
|
||||||
|
return new ILOAD_3(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LLOAD_0 -> {
|
||||||
|
return new LLOAD_0(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LLOAD_1 -> {
|
||||||
|
return new LLOAD_1(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LLOAD_2 -> {
|
||||||
|
return new LLOAD_2(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LLOAD_3 -> {
|
||||||
|
return new LLOAD_3(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FLOAD_0 -> {
|
||||||
|
return new FLOAD_0(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FLOAD_1 -> {
|
||||||
|
return new FLOAD_1(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FLOAD_2 -> {
|
||||||
|
return new FLOAD_2(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FLOAD_3 -> {
|
||||||
|
return new FLOAD_3(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DLOAD_0 -> {
|
||||||
|
return new DLOAD_0(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DLOAD_1 -> {
|
||||||
|
return new DLOAD_1(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DLOAD_2 -> {
|
||||||
|
return new DLOAD_2(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DLOAD_3 -> {
|
||||||
|
return new DLOAD_3(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ALOAD_0 -> {
|
||||||
|
return new ALOAD_0(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ALOAD_1 -> {
|
||||||
|
return new ALOAD_1(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ALOAD_2 -> {
|
||||||
|
return new ALOAD_2(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ALOAD_3 -> {
|
||||||
|
return new ALOAD_3(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IALOAD -> {
|
||||||
|
return new IALOAD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LALOAD -> {
|
||||||
|
return new LALOAD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FALOAD -> {
|
||||||
|
return new FALOAD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DALOAD -> {
|
||||||
|
return new DALOAD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.AALOAD -> {
|
||||||
|
return new AALOAD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.BALOAD -> {
|
||||||
|
return new BALOAD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.CALOAD -> {
|
||||||
|
return new CALOAD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.SALOAD -> {
|
||||||
|
return new SALOAD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ISTORE -> {
|
||||||
|
return new ISTORE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LSTORE -> {
|
||||||
|
return new LSTORE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FSTORE -> {
|
||||||
|
return new FSTORE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DSTORE -> {
|
||||||
|
return new DSTORE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ASTORE -> {
|
||||||
|
return new ASTORE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ISTORE_0 -> {
|
||||||
|
return new ISTORE_0(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ISTORE_1 -> {
|
||||||
|
return new ISTORE_1(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ISTORE_2 -> {
|
||||||
|
return new ISTORE_2(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ISTORE_3 -> {
|
||||||
|
return new ISTORE_3(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LSTORE_0 -> {
|
||||||
|
return new LSTORE_0(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LSTORE_1 -> {
|
||||||
|
return new LSTORE_1(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LSTORE_2 -> {
|
||||||
|
return new LSTORE_2(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LSTORE_3 -> {
|
||||||
|
return new LSTORE_3(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FSTORE_0 -> {
|
||||||
|
return new FSTORE_0(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FSTORE_1 -> {
|
||||||
|
return new FSTORE_1(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FSTORE_2 -> {
|
||||||
|
return new FSTORE_2(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FSTORE_3 -> {
|
||||||
|
return new FSTORE_3(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DSTORE_0 -> {
|
||||||
|
return new DSTORE_0(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DSTORE_1 -> {
|
||||||
|
return new DSTORE_1(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DSTORE_2 -> {
|
||||||
|
return new DSTORE_2(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DSTORE_3 -> {
|
||||||
|
return new DSTORE_3(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ASTORE_0 -> {
|
||||||
|
return new ASTORE_0(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ASTORE_1 -> {
|
||||||
|
return new ASTORE_1(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ASTORE_2 -> {
|
||||||
|
return new ASTORE_2(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ASTORE_3 -> {
|
||||||
|
return new ASTORE_3(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IASTORE -> {
|
||||||
|
return new IASTORE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LASTORE -> {
|
||||||
|
return new LASTORE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FASTORE -> {
|
||||||
|
return new FASTORE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DASTORE -> {
|
||||||
|
return new DASTORE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.AASTORE -> {
|
||||||
|
return new AASTORE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.BASTORE -> {
|
||||||
|
return new BASTORE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.CASTORE -> {
|
||||||
|
return new CASTORE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.SASTORE -> {
|
||||||
|
return new SASTORE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.POP -> {
|
||||||
|
return new POP(codeStream);
|
||||||
|
}
|
||||||
|
case Const.POP2 -> {
|
||||||
|
return new POP2(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DUP -> {
|
||||||
|
return new DUP(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DUP_X1 -> {
|
||||||
|
return new DUP_X1(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DUP_X2 -> {
|
||||||
|
return new DUP_X2(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DUP2 -> {
|
||||||
|
return new DUP2(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DUP2_X1 -> {
|
||||||
|
throw new Error("Not support JavaVM opcode DUP2_X1");
|
||||||
|
}
|
||||||
|
case Const.DUP2_X2 -> {
|
||||||
|
throw new Error("Not support JavaVM opcode DUP2_X2");
|
||||||
|
}
|
||||||
|
case Const.SWAP -> {
|
||||||
|
return new SWAP(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IADD -> {
|
||||||
|
return new IADD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LADD -> {
|
||||||
|
return new LADD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FADD -> {
|
||||||
|
return new FADD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DADD -> {
|
||||||
|
return new DADD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ISUB -> {
|
||||||
|
return new ISUB(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LSUB -> {
|
||||||
|
return new LSUB(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FSUB -> {
|
||||||
|
return new FSUB(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DSUB -> {
|
||||||
|
return new DSUB(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IMUL -> {
|
||||||
|
return new IMUL(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LMUL -> {
|
||||||
|
return new LMUL(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FMUL -> {
|
||||||
|
return new FMUL(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DMUL -> {
|
||||||
|
return new DMUL(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IDIV -> {
|
||||||
|
return new IDIV(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LDIV -> {
|
||||||
|
return new LDIV(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FDIV -> {
|
||||||
|
return new FDIV(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DDIV -> {
|
||||||
|
return new DDIV(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IREM -> {
|
||||||
|
return new IREM(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LREM -> {
|
||||||
|
return new LREM(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FREM -> {
|
||||||
|
return new FREM(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DREM -> {
|
||||||
|
return new DREM(codeStream);
|
||||||
|
}
|
||||||
|
case Const.INEG -> {
|
||||||
|
return new INEG(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LNEG -> {
|
||||||
|
return new LNEG(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FNEG -> {
|
||||||
|
return new FNEG(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DNEG -> {
|
||||||
|
return new DNEG(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ISHL -> {
|
||||||
|
return new ISHL(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LSHL -> {
|
||||||
|
return new LSHL(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ISHR -> {
|
||||||
|
return new ISHR(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LSHR -> {
|
||||||
|
return new LSHR(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IUSHR -> {
|
||||||
|
return new IUSHR(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LUSHR -> {
|
||||||
|
return new LUSHR(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IAND -> {
|
||||||
|
return new IAND(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LAND -> {
|
||||||
|
return new LAND(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IOR -> {
|
||||||
|
return new IOR(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LOR -> {
|
||||||
|
return new LOR(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IXOR -> {
|
||||||
|
return new IXOR(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LXOR -> {
|
||||||
|
return new LXOR(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IINC -> {
|
||||||
|
return new IINC(codeStream);
|
||||||
|
}
|
||||||
|
case Const.I2L -> {
|
||||||
|
return new I2L(codeStream);
|
||||||
|
}
|
||||||
|
case Const.I2F -> {
|
||||||
|
return new I2F(codeStream);
|
||||||
|
}
|
||||||
|
case Const.I2D -> {
|
||||||
|
return new I2D(codeStream);
|
||||||
|
}
|
||||||
|
case Const.L2I -> {
|
||||||
|
return new L2I(codeStream);
|
||||||
|
}
|
||||||
|
case Const.L2F -> {
|
||||||
|
return new L2F(codeStream);
|
||||||
|
}
|
||||||
|
case Const.L2D -> {
|
||||||
|
return new L2D(codeStream);
|
||||||
|
}
|
||||||
|
case Const.F2I -> {
|
||||||
|
return new F2I(codeStream);
|
||||||
|
}
|
||||||
|
case Const.F2L -> {
|
||||||
|
return new F2L(codeStream);
|
||||||
|
}
|
||||||
|
case Const.F2D -> {
|
||||||
|
return new F2D(codeStream);
|
||||||
|
}
|
||||||
|
case Const.D2I -> {
|
||||||
|
return new D2I(codeStream);
|
||||||
|
}
|
||||||
|
case Const.D2L -> {
|
||||||
|
return new D2L(codeStream);
|
||||||
|
}
|
||||||
|
case Const.D2F -> {
|
||||||
|
return new D2F(codeStream);
|
||||||
|
}
|
||||||
|
case Const.I2B -> {
|
||||||
|
return new I2B(codeStream);
|
||||||
|
}
|
||||||
|
case Const.I2C -> {
|
||||||
|
return new I2C(codeStream);
|
||||||
|
}
|
||||||
|
case Const.I2S -> {
|
||||||
|
return new I2S(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LCMP -> {
|
||||||
|
return new LCMP(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FCMPL -> {
|
||||||
|
return new FCMPL(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FCMPG -> {
|
||||||
|
return new FCMPG(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DCMPL -> {
|
||||||
|
return new DCMPL(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DCMPG -> {
|
||||||
|
return new DCMPG(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IFEQ -> {
|
||||||
|
return new IFEQ(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IFNE -> {
|
||||||
|
return new IFNE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IFLT -> {
|
||||||
|
return new IFLT(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IFGE -> {
|
||||||
|
return new IFGE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IFGT -> {
|
||||||
|
return new IFGT(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IFLE -> {
|
||||||
|
return new IFLE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IF_ICMPEQ -> {
|
||||||
|
return new IF_ICMPEQ(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IF_ICMPNE -> {
|
||||||
|
return new IF_ICMPNE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IF_ICMPLT -> {
|
||||||
|
return new IF_ICMPLT(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IF_ICMPGE -> {
|
||||||
|
return new IF_ICMPGE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IF_ICMPGT -> {
|
||||||
|
return new IF_ICMPGT(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IF_ICMPLE -> {
|
||||||
|
return new IF_ICMPLE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IF_ACMPEQ -> {
|
||||||
|
return new IF_ACMPEQ(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IF_ACMPNE -> {
|
||||||
|
return new IF_ACMPNE(codeStream);
|
||||||
|
}
|
||||||
|
case Const.GOTO -> {
|
||||||
|
return new GOTO(codeStream);
|
||||||
|
}
|
||||||
|
case Const.JSR -> {
|
||||||
|
return new JSR(codeStream);
|
||||||
|
}
|
||||||
|
case Const.RET -> {
|
||||||
|
return new RET(codeStream);
|
||||||
|
}
|
||||||
|
case Const.TABLESWITCH -> {
|
||||||
|
throw new Error("Not support JavaVM opcode TABLESWITCH");
|
||||||
|
}
|
||||||
|
case Const.LOOKUPSWITCH -> {
|
||||||
|
throw new Error("Not support JavaVM opcode LOOKUPSWITCH");
|
||||||
|
}
|
||||||
|
case Const.IRETURN -> {
|
||||||
|
return new IRETURN(codeStream);
|
||||||
|
}
|
||||||
|
case Const.LRETURN -> {
|
||||||
|
return new LRETURN(codeStream);
|
||||||
|
}
|
||||||
|
case Const.FRETURN -> {
|
||||||
|
return new FRETURN(codeStream);
|
||||||
|
}
|
||||||
|
case Const.DRETURN -> {
|
||||||
|
return new DRETURN(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ARETURN -> {
|
||||||
|
throw new Error("Not support JavaVM opcode ARETURN");
|
||||||
|
}
|
||||||
|
case Const.RETURN -> {
|
||||||
|
return new RETURN(codeStream);
|
||||||
|
}
|
||||||
|
case Const.GETSTATIC -> {
|
||||||
|
return new GETSTATIC(codeStream);
|
||||||
|
}
|
||||||
|
case Const.PUTSTATIC -> {
|
||||||
|
throw new Error("Not support JavaVM opcode PUTSTATIC");
|
||||||
|
}
|
||||||
|
case Const.GETFIELD -> {
|
||||||
|
return new GETFIELD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.PUTFIELD -> {
|
||||||
|
return new PUTFIELD(codeStream);
|
||||||
|
}
|
||||||
|
case Const.INVOKEVIRTUAL -> {
|
||||||
|
return new INVOKEVIRTUAL(codeStream);
|
||||||
|
}
|
||||||
|
case Const.INVOKESPECIAL -> {
|
||||||
|
return new INVOKESPECIAL(codeStream);
|
||||||
|
}
|
||||||
|
case Const.INVOKESTATIC -> {
|
||||||
|
return new INVOKESTATIC(codeStream);
|
||||||
|
}
|
||||||
|
case Const.INVOKEINTERFACE -> {
|
||||||
|
throw new Error("Not support JavaVM opcode INVOKEINTERFACE");
|
||||||
|
}
|
||||||
|
case Const.INVOKEDYNAMIC -> {
|
||||||
|
throw new Error("Not support JavaVM opcode INVOKEDYNAMIC");
|
||||||
|
}
|
||||||
|
case Const.NEW -> {
|
||||||
|
return new NEW(codeStream);
|
||||||
|
}
|
||||||
|
case Const.NEWARRAY -> {
|
||||||
|
return new NEWARRAY(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ANEWARRAY -> {
|
||||||
|
return new ANEWARRAY(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ARRAYLENGTH -> {
|
||||||
|
return new ARRAYLENGTH(codeStream);
|
||||||
|
}
|
||||||
|
case Const.ATHROW -> {
|
||||||
|
throw new Error("Not support JavaVM opcode ATHROW");
|
||||||
|
}
|
||||||
|
case Const.CHECKCAST -> {
|
||||||
|
return new CHECKCAST(codeStream);
|
||||||
|
}
|
||||||
|
case Const.INSTANCEOF -> {
|
||||||
|
throw new Error("Not support JavaVM opcode INSTANCEOF");
|
||||||
|
}
|
||||||
|
case Const.MONITORENTER -> {
|
||||||
|
throw new Error("Not support JavaVM opcode MONITORENTER");
|
||||||
|
}
|
||||||
|
case Const.MONITOREXIT -> {
|
||||||
|
throw new Error("Not support JavaVM opcode MONITOREXIT");
|
||||||
|
}
|
||||||
|
case Const.WIDE -> {
|
||||||
|
throw new Error("Not support JavaVM opcode WIDE");
|
||||||
|
}
|
||||||
|
case Const.MULTIANEWARRAY -> {
|
||||||
|
throw new Error("Not support JavaVM opcode MULTIANEWARRAY");
|
||||||
|
}
|
||||||
|
case Const.IFNULL -> {
|
||||||
|
return new IFNULL(codeStream);
|
||||||
|
}
|
||||||
|
case Const.IFNONNULL -> {
|
||||||
|
return new IFNONNULL(codeStream);
|
||||||
|
}
|
||||||
|
case Const.GOTO_W -> {
|
||||||
|
return new GOTO_W(codeStream);
|
||||||
|
}
|
||||||
|
case Const.JSR_W -> {
|
||||||
|
return new JSR_W(codeStream);
|
||||||
|
}
|
||||||
|
default -> throw new Error("Unknown JavaVM opcode " + opcode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
28
src/main/java/haidnor/jvm/instruction/comparisons/DCMPG.java
Normal file
28
src/main/java/haidnor/jvm/instruction/comparisons/DCMPG.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 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
28
src/main/java/haidnor/jvm/instruction/comparisons/DCMPL.java
Normal file
28
src/main/java/haidnor/jvm/instruction/comparisons/DCMPL.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 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
28
src/main/java/haidnor/jvm/instruction/comparisons/FCMPG.java
Normal file
28
src/main/java/haidnor/jvm/instruction/comparisons/FCMPG.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 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
28
src/main/java/haidnor/jvm/instruction/comparisons/FCMPL.java
Normal file
28
src/main/java/haidnor/jvm/instruction/comparisons/FCMPL.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 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
34
src/main/java/haidnor/jvm/instruction/comparisons/IFEQ.java
Normal file
34
src/main/java/haidnor/jvm/instruction/comparisons/IFEQ.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 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 ((int) v1.getValue() == 0) {
|
||||||
|
super.setOffSet(offSet);
|
||||||
|
} else {
|
||||||
|
super.setOffSet(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.index() + " " + 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.index() + " " + 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.index() + " " + 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.index() + " " + 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.index() + " " + this.getClass().getSimpleName() + " " + offSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
34
src/main/java/haidnor/jvm/instruction/comparisons/IFNE.java
Normal file
34
src/main/java/haidnor/jvm/instruction/comparisons/IFNE.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 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 ((int) v1.getValue() != 0) {
|
||||||
|
super.setOffSet(offSet);
|
||||||
|
} else {
|
||||||
|
super.setOffSet(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.index() + " " + this.getClass().getSimpleName() + " " + offSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package haidnor.jvm.instruction.comparisons;
|
||||||
|
|
||||||
|
import haidnor.jvm.instruction.Instruction;
|
||||||
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.util.CodeStream;
|
||||||
|
|
||||||
|
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.index() + " " + this.getClass().getSimpleName() + " " + offSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package haidnor.jvm.instruction.comparisons;
|
||||||
|
|
||||||
|
import haidnor.jvm.instruction.Instruction;
|
||||||
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.util.CodeStream;
|
||||||
|
|
||||||
|
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.index() + " " + this.getClass().getSimpleName() + " " + offSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
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_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.index() + " " + 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.index() + " " + 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.index() + " " + 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_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.index() + " " + 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_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.index() + " " + 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.index() + " " + 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.instruction.Instruction;
|
||||||
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.runtime.StackValue;
|
||||||
|
import haidnor.jvm.util.CodeStream;
|
||||||
|
import org.apache.bcel.Const;
|
||||||
|
|
||||||
|
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 org.apache.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 org.apache.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 org.apache.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 org.apache.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 org.apache.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 org.apache.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 org.apache.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 org.apache.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 org.apache.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 org.apache.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 org.apache.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 org.apache.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 org.apache.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 org.apache.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.instruction.Instruction;
|
||||||
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.runtime.StackValue;
|
||||||
|
import haidnor.jvm.util.CodeStream;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.apache.bcel.Const;
|
||||||
|
import org.apache.bcel.classfile.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.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.instruction.Instruction;
|
||||||
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.runtime.StackValue;
|
||||||
|
import haidnor.jvm.util.CodeStream;
|
||||||
|
import org.apache.bcel.Const;
|
||||||
|
import org.apache.bcel.classfile.Constant;
|
||||||
|
import org.apache.bcel.classfile.ConstantDouble;
|
||||||
|
import org.apache.bcel.classfile.ConstantLong;
|
||||||
|
import org.apache.bcel.classfile.ConstantPool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将 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.instruction.Instruction;
|
||||||
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.runtime.StackValue;
|
||||||
|
import haidnor.jvm.util.CodeStream;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.apache.bcel.Const;
|
||||||
|
import org.apache.bcel.classfile.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.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 org.apache.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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
26
src/main/java/haidnor/jvm/instruction/control/DRETURN.java
Normal file
26
src/main/java/haidnor/jvm/instruction/control/DRETURN.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package haidnor.jvm.instruction.control;
|
||||||
|
|
||||||
|
import haidnor.jvm.instruction.Instruction;
|
||||||
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.runtime.StackValue;
|
||||||
|
import haidnor.jvm.util.CodeStream;
|
||||||
|
import haidnor.jvm.util.JvmThreadHolder;
|
||||||
|
|
||||||
|
public class DRETURN extends Instruction {
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
26
src/main/java/haidnor/jvm/instruction/control/FRETURN.java
Normal file
26
src/main/java/haidnor/jvm/instruction/control/FRETURN.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package haidnor.jvm.instruction.control;
|
||||||
|
|
||||||
|
import haidnor.jvm.instruction.Instruction;
|
||||||
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.runtime.StackValue;
|
||||||
|
import haidnor.jvm.util.CodeStream;
|
||||||
|
import haidnor.jvm.util.JvmThreadHolder;
|
||||||
|
|
||||||
|
public class FRETURN extends Instruction {
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
26
src/main/java/haidnor/jvm/instruction/control/IRETURN.java
Normal file
26
src/main/java/haidnor/jvm/instruction/control/IRETURN.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package haidnor.jvm.instruction.control;
|
||||||
|
|
||||||
|
import haidnor.jvm.instruction.Instruction;
|
||||||
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.runtime.StackValue;
|
||||||
|
import haidnor.jvm.util.CodeStream;
|
||||||
|
import haidnor.jvm.util.JvmThreadHolder;
|
||||||
|
|
||||||
|
public class IRETURN extends Instruction {
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
26
src/main/java/haidnor/jvm/instruction/control/LRETURN.java
Normal file
26
src/main/java/haidnor/jvm/instruction/control/LRETURN.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package haidnor.jvm.instruction.control;
|
||||||
|
|
||||||
|
import haidnor.jvm.instruction.Instruction;
|
||||||
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.runtime.StackValue;
|
||||||
|
import haidnor.jvm.util.CodeStream;
|
||||||
|
import haidnor.jvm.util.JvmThreadHolder;
|
||||||
|
|
||||||
|
public class LRETURN extends Instruction {
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
19
src/main/java/haidnor/jvm/instruction/control/RETURN.java
Normal file
19
src/main/java/haidnor/jvm/instruction/control/RETURN.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package haidnor.jvm.instruction.control;
|
||||||
|
|
||||||
|
import haidnor.jvm.instruction.Instruction;
|
||||||
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.util.CodeStream;
|
||||||
|
import haidnor.jvm.util.JvmThreadHolder;
|
||||||
|
|
||||||
|
public class RETURN extends Instruction {
|
||||||
|
|
||||||
|
public RETURN(CodeStream codeStream) {
|
||||||
|
super(codeStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Frame frame) {
|
||||||
|
JvmThreadHolder.get().pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
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.index() + " " + 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.index() + " " + 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.index() + " " + 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.index() + " " + this.getClass().getSimpleName() + " " + offSet;
|
||||||
|
}
|
||||||
|
}
|
||||||
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.heap.Instance;
|
||||||
|
import haidnor.jvm.rtda.heap.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 = (Instance) array.items[index];
|
||||||
|
frame.pushRef(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
26
src/main/java/haidnor/jvm/instruction/loads/ALOAD.java
Normal file
26
src/main/java/haidnor/jvm/instruction/loads/ALOAD.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package haidnor.jvm.instruction.loads;
|
||||||
|
|
||||||
|
import haidnor.jvm.instruction.Instruction;
|
||||||
|
import haidnor.jvm.rtda.heap.Instance;
|
||||||
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.runtime.StackValue;
|
||||||
|
import haidnor.jvm.util.CodeStream;
|
||||||
|
import org.apache.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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
22
src/main/java/haidnor/jvm/instruction/loads/ALOAD_0.java
Normal file
22
src/main/java/haidnor/jvm/instruction/loads/ALOAD_0.java
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package haidnor.jvm.instruction.loads;
|
||||||
|
|
||||||
|
import haidnor.jvm.instruction.Instruction;
|
||||||
|
import haidnor.jvm.rtda.heap.Instance;
|
||||||
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.runtime.StackValue;
|
||||||
|
import haidnor.jvm.util.CodeStream;
|
||||||
|
import org.apache.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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
22
src/main/java/haidnor/jvm/instruction/loads/ALOAD_1.java
Normal file
22
src/main/java/haidnor/jvm/instruction/loads/ALOAD_1.java
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package haidnor.jvm.instruction.loads;
|
||||||
|
|
||||||
|
import haidnor.jvm.instruction.Instruction;
|
||||||
|
import haidnor.jvm.rtda.heap.Instance;
|
||||||
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.runtime.StackValue;
|
||||||
|
import haidnor.jvm.util.CodeStream;
|
||||||
|
import org.apache.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 org.apache.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 org.apache.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.heap.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.heap.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.heap.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 org.apache.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 org.apache.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 org.apache.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 org.apache.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 org.apache.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.heap.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 org.apache.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 org.apache.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 org.apache.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 org.apache.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 org.apache.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.heap.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 org.apache.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 org.apache.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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
24
src/main/java/haidnor/jvm/instruction/loads/ILOAD_1.java
Normal file
24
src/main/java/haidnor/jvm/instruction/loads/ILOAD_1.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 org.apache.bcel.Const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n
|
||||||
|
*/
|
||||||
|
public class ILOAD_1 extends Instruction {
|
||||||
|
|
||||||
|
public ILOAD_1(CodeStream codeStream) {
|
||||||
|
super(codeStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Frame frame) {
|
||||||
|
int value = frame.slotGetInt(1);
|
||||||
|
frame.push(new StackValue(Const.T_INT, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
24
src/main/java/haidnor/jvm/instruction/loads/ILOAD_2.java
Normal file
24
src/main/java/haidnor/jvm/instruction/loads/ILOAD_2.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 org.apache.bcel.Const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n
|
||||||
|
*/
|
||||||
|
public class ILOAD_2 extends Instruction {
|
||||||
|
|
||||||
|
public ILOAD_2(CodeStream codeStream) {
|
||||||
|
super(codeStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Frame frame) {
|
||||||
|
int value = frame.slotGetInt(2);
|
||||||
|
frame.push(new StackValue(Const.T_INT, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
24
src/main/java/haidnor/jvm/instruction/loads/ILOAD_3.java
Normal file
24
src/main/java/haidnor/jvm/instruction/loads/ILOAD_3.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 org.apache.bcel.Const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n
|
||||||
|
*/
|
||||||
|
public class ILOAD_3 extends Instruction {
|
||||||
|
|
||||||
|
public ILOAD_3(CodeStream codeStream) {
|
||||||
|
super(codeStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Frame frame) {
|
||||||
|
int value = frame.slotGetInt(3);
|
||||||
|
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