package minijvm.cmd; import minijvm.clz.ClassFile; import minijvm.constant.MethodRefInfo; import minijvm.engine.ExecutionResult; import minijvm.engine.JavaObject; import minijvm.engine.MethodArea; import minijvm.engine.StackFrame; import minijvm.method.Method; public class InvokeVirtualCmd extends TwoOperandCmd { public InvokeVirtualCmd(ClassFile clzFile,String opCode) { super(clzFile,opCode); } @Override public String toString() { return super.getOperandAsMethod(); } private boolean isSystemOutPrintlnMethod(String className, String methodName) { return "java/io/PrintStream".equals(className) && "println".equals(methodName); } @Override public void execute(StackFrame frame, ExecutionResult result) { MethodRefInfo methodRefInfo = (MethodRefInfo) this.getConstantInfo(this.getIndex()); String className = methodRefInfo.getClassName(); String methodName = methodRefInfo.getMethodName(); if (isSystemOutPrintlnMethod(className, methodName)) { JavaObject jo = frame.getOprandStack().pop(); String value = jo.toString(); System.err.println("--------------------" + value + "-------------------"); frame.getOprandStack().pop(); return; } JavaObject jo = frame.getOprandStack().peek(); MethodArea ma = MethodArea.getInstance(); Method m = null; String currentClassName = jo.getClassName(); while (currentClassName != null) { ClassFile cuClassFile = ma.findClassFile(currentClassName); m = cuClassFile.getMethod(methodRefInfo.getMethodName(), methodRefInfo.getParamAndReturnType()); if (m != null) { break; } else { currentClassName = cuClassFile.getSuperClassName(); } } if (m == null) { throw new RuntimeException("找不到对应的方法:" + methodRefInfo.toString()); } result.setNextAction(ExecutionResult.PAUSE_AND_RUN_NEW_FRAME); result.setNextMethod(m); } }