![JAR search and dependency download from the Maven repository](/logo.png)
com.github.liuyehcf.framework.language.hua.runtime.MethodRuntimeInfo Maven / Gradle / Ivy
package com.github.liuyehcf.framework.language.hua.runtime;
import com.github.liuyehcf.framework.language.hua.compile.definition.model.Type;
import com.github.liuyehcf.framework.language.hua.core.IntermediateInfo;
import com.github.liuyehcf.framework.language.hua.core.MethodInfo;
import java.util.List;
import static com.github.liuyehcf.framework.common.tools.asserts.Assert.assertEquals;
/**
* 方法运行时信息,方法栈的元素
*
* @author hechenfeng
* @date 2018/6/25
*/
class MethodRuntimeInfo {
/**
* Hua编译后的中间形式
*/
private final IntermediateInfo intermediateInfo;
/**
* 方法信息
*/
private final MethodInfo methodInfo;
/**
* 操作数栈
*/
private final OperatorStack operatorStack = new OperatorStack();
/**
* 栈内存
* 第一维度:方法中有效符号的最大个数
* 第二维度:固定是8,即允许任意类型的数值
* 为什么要这样做,而不用一维数组?因为根据标志符序号来获取内存偏移量比较难,因为同一个标志符序号,在不同时刻,偏移量是不同的。例如如下代码
* {
* int i;
* int j;
* }
* {
* boolean i;
* int j;
* }
* 在上述代码中,标志符i、j分别位于两个block中,j的序号都是2,但是j的offset却是不同的
*/
private final byte[][] stackMemory;
/**
* 代码偏移量
*/
private int codeOffset = 0;
/**
* 返回值
*/
private Object result;
/**
* 是否执行完毕
*/
private boolean isFinished = false;
MethodRuntimeInfo(IntermediateInfo intermediateInfo, MethodInfo methodInfo) {
this.intermediateInfo = intermediateInfo;
this.methodInfo = methodInfo;
stackMemory = new byte[this.methodInfo.getMaxOrder()][Type.REFERENCE_TYPE_WIDTH];
}
Object run(Object[] args) {
setArgs(args);
while (!isFinished) {
methodInfo.getByteCodes().get(codeOffset).operate(new RuntimeContext(intermediateInfo, this));
}
return result;
}
private void setArgs(Object[] args) {
List paramTypeList = methodInfo.getParamTypeList();
assertEquals(args.length, paramTypeList.size(), "[SYSTEM_ERROR] - The actual parameter quantity must be consistent with the shape parameter quantity");
for (int i = 0; i < args.length; i++) {
Type paramType = paramTypeList.get(i);
if (paramType.isArrayType()) {
storeReference(i, (Reference) args[i]);
} else if (Type.TYPE_INT.equals(paramType)) {
storeInt(i, (int) args[i]);
} else if (Type.TYPE_BOOLEAN.equals(paramType)) {
storeInt(i, (int) args[i]);
}
}
}
void setResult(Object result) {
this.result = result;
}
OperatorStack getOperatorStack() {
return operatorStack;
}
void increaseCodeOffset() {
codeOffset++;
}
void setCodeOffset(int codeOffset) {
this.codeOffset = codeOffset;
}
void finishMethod() {
isFinished = true;
}
int loadInt(int order) {
return ByteUtils.loadInt(stackMemory[order], 0);
}
void storeInt(int order, int value) {
ByteUtils.storeInt(stackMemory[order], 0, value);
}
long loadLong(int order) {
return ByteUtils.loadLong(stackMemory[order], 0);
}
void storeLong(int order, long value) {
ByteUtils.storeLong(stackMemory[order], 0, value);
}
float loadFloat(int order) {
return ByteUtils.loadFloat(stackMemory[order], 0);
}
void storeFloat(int order, float value) {
ByteUtils.storeFloat(stackMemory[order], 0, value);
}
double loadDouble(int order) {
return ByteUtils.loadDouble(stackMemory[order], 0);
}
void storeDouble(int order, double value) {
ByteUtils.storeDouble(stackMemory[order], 0, value);
}
Reference loadReference(int order) {
return ByteUtils.loadReference(stackMemory[order], 0);
}
void storeReference(int order, Reference reference) {
ByteUtils.storeReference(stackMemory[order], 0, reference);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy