mirror of
https://github.com/FranzHaidnor/haidnorJVM.git
synced 2026-03-13 21:43:42 +08:00
support Exception
This commit is contained in:
@@ -12,10 +12,8 @@ import haidnor.jvm.util.CodeStream;
|
|||||||
import haidnor.jvm.util.JvmThreadHolder;
|
import haidnor.jvm.util.JvmThreadHolder;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.bcel.classfile.LocalVariable;
|
import org.apache.bcel.Const;
|
||||||
import org.apache.bcel.classfile.LocalVariableTable;
|
import org.apache.bcel.classfile.*;
|
||||||
import org.apache.bcel.classfile.Method;
|
|
||||||
import org.apache.bcel.classfile.Utility;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -94,11 +92,42 @@ public class JavaExecutionEngine {
|
|||||||
for (int i = 0; i < frame.getCodeLength(); ) {
|
for (int i = 0; i < frame.getCodeLength(); ) {
|
||||||
Instruction instruction = instructionMap.get(i);
|
Instruction instruction = instructionMap.get(i);
|
||||||
log.debug("{}│ {}", blank, instruction);
|
log.debug("{}│ {}", blank, instruction);
|
||||||
instruction.execute(frame);
|
try {
|
||||||
if (instruction instanceof RETURN || instruction instanceof ARETURN || instruction instanceof DRETURN || instruction instanceof FRETURN || instruction instanceof IRETURN) {
|
instruction.execute(frame);
|
||||||
break;
|
if (instruction instanceof RETURN || instruction instanceof ARETURN || instruction instanceof DRETURN || instruction instanceof FRETURN || instruction instanceof IRETURN) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i += instruction.offSet();
|
||||||
|
} catch (Exception exception) {
|
||||||
|
Integer handlerPC = null;
|
||||||
|
|
||||||
|
CodeException[] exceptionTable = frame.getMethod().getCode().getExceptionTable();
|
||||||
|
for (CodeException codeException : exceptionTable) {
|
||||||
|
if (codeException.getStartPC() <= i & i <= codeException.getEndPC()) {
|
||||||
|
int catchType = codeException.getCatchType();
|
||||||
|
// 0, if the handler catches any exception, otherwise it points to the exception class which is to be caught.
|
||||||
|
if (catchType == 0) {
|
||||||
|
frame.push(new StackValue(Const.T_OBJECT, exception));
|
||||||
|
handlerPC = codeException.getHandlerPC();
|
||||||
|
} else {
|
||||||
|
String exceptionClassName = frame.getConstantPoolUtil().getConstantClassClassName(catchType);
|
||||||
|
exceptionClassName = Utility.compactClassName(exceptionClassName, false);
|
||||||
|
Class<?> exceptionClass = Class.forName(exceptionClassName);
|
||||||
|
if (exceptionClass.isAssignableFrom(exception.getClass())) {
|
||||||
|
frame.push(new StackValue(Const.T_OBJECT, exception));
|
||||||
|
handlerPC = codeException.getHandlerPC();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (handlerPC != null) {
|
||||||
|
i = handlerPC;
|
||||||
|
} else {
|
||||||
|
log.debug("{}└──────────────────[{}] No Exception Handler Return!", blank, stackSize);
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
i += instruction.offSet();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("{}└──────────────────[{}] {} | {}", blank, stackSize, frame.klass.getClassName(), frame.getMethod());
|
log.debug("{}└──────────────────[{}] {} | {}", blank, stackSize, frame.klass.getClassName(), frame.getMethod());
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class ANEWARRAY extends Instruction {
|
|||||||
ConstantPool constantPool = frame.getConstantPool();
|
ConstantPool constantPool = frame.getConstantPool();
|
||||||
ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil();
|
ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil();
|
||||||
ConstantClass constantClass = constantPool.getConstant(constantClassIndex);
|
ConstantClass constantClass = constantPool.getConstant(constantClassIndex);
|
||||||
String className = constantPoolUtil.getClassName(constantClass);
|
String className = constantPoolUtil.getConstantClassClassName(constantClass);
|
||||||
|
|
||||||
Klass klass = Metaspace.getJavaClass(Utility.compactClassName(className));
|
Klass klass = Metaspace.getJavaClass(Utility.compactClassName(className));
|
||||||
if (klass == null) {
|
if (klass == null) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package haidnor.jvm.instruction.references;
|
|||||||
|
|
||||||
import haidnor.jvm.instruction.Instruction;
|
import haidnor.jvm.instruction.Instruction;
|
||||||
import haidnor.jvm.runtime.Frame;
|
import haidnor.jvm.runtime.Frame;
|
||||||
|
import haidnor.jvm.runtime.StackValue;
|
||||||
import haidnor.jvm.util.CodeStream;
|
import haidnor.jvm.util.CodeStream;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
@@ -14,7 +15,8 @@ public class ATHROW extends Instruction {
|
|||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public void execute(Frame frame) {
|
public void execute(Frame frame) {
|
||||||
|
StackValue pop = frame.pop();
|
||||||
|
throw (Exception) pop.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class INSTANCEOF extends Instruction {
|
|||||||
ConstantPool constantPool = frame.getConstantPool();
|
ConstantPool constantPool = frame.getConstantPool();
|
||||||
ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil();
|
ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil();
|
||||||
ConstantClass constantClass = constantPool.getConstant(constantClassIndex);
|
ConstantClass constantClass = constantPool.getConstant(constantClassIndex);
|
||||||
String className = constantPoolUtil.getClassName(constantClass);
|
String className = constantPoolUtil.getConstantClassClassName(constantClass);
|
||||||
className = Utility.compactClassName(className);
|
className = Utility.compactClassName(className);
|
||||||
|
|
||||||
StackValue stackValue = frame.pop();
|
StackValue stackValue = frame.pop();
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class NEW extends Instruction {
|
|||||||
ConstantPool constantPool = frame.getConstantPool();
|
ConstantPool constantPool = frame.getConstantPool();
|
||||||
ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil();
|
ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil();
|
||||||
ConstantClass constantClass = constantPool.getConstant(constantClassIndex);
|
ConstantClass constantClass = constantPool.getConstant(constantClassIndex);
|
||||||
String className = constantPoolUtil.getClassName(constantClass);
|
String className = constantPoolUtil.getConstantClassClassName(constantClass);
|
||||||
|
|
||||||
if (className.startsWith("java/")) {
|
if (className.startsWith("java/")) {
|
||||||
frame.push(new StackValue(Const.T_OBJECT, null));
|
frame.push(new StackValue(Const.T_OBJECT, null));
|
||||||
|
|||||||
@@ -42,16 +42,16 @@ public class ConstantPoolUtil {
|
|||||||
/**
|
/**
|
||||||
* 获取长类名, 例如 java/lang/String
|
* 获取长类名, 例如 java/lang/String
|
||||||
*/
|
*/
|
||||||
public String getClassName(final ConstantClass constantClass) {
|
public String getConstantClassClassName(final ConstantClass constantClass) {
|
||||||
ConstantUtf8 constantUtf8 = cp.getConstant(constantClass.getNameIndex());
|
ConstantUtf8 constantUtf8 = cp.getConstant(constantClass.getNameIndex());
|
||||||
return constantUtf8.getBytes();
|
return constantUtf8.getBytes();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 获取长类名, 例如 java/lang/String
|
* 获取长类名, 例如 java/lang/String
|
||||||
*/
|
*/
|
||||||
public String getClassName(int index) {
|
public String getConstantClassClassName(int constantClassIndex) {
|
||||||
ConstantClass constantClass = cp.getConstant(index);
|
ConstantClass constantClass = cp.getConstant(constantClassIndex);
|
||||||
return getClassName(constantClass);
|
return getConstantClassClassName(constantClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,17 +4,17 @@ package haidnor.jvm.test.demo;
|
|||||||
public class Demo7 {
|
public class Demo7 {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
String fun = fun();
|
|
||||||
System.out.println(fun);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String fun() {
|
|
||||||
String str = "hello";
|
|
||||||
try {
|
try {
|
||||||
return str;
|
String name = fun();
|
||||||
} finally {
|
System.out.println(name);
|
||||||
System.out.println("zhangsan");
|
} catch (Exception exception) {
|
||||||
|
System.out.println("计算错误");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String fun() {
|
||||||
|
System.out.println(1 / 0);
|
||||||
|
return "zhangsan";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user