⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fastcompiler.java

📁 JPC: x86 PC Hardware Emulator. 牛津大学开发的一个纯JAVA的x86系统结构硬件模拟器。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
                continue;

            affectedCount++;
            localVariableIndex = rpn.markSubtrees(localVariableIndex);
        }
        
        ByteArrayOutputStream byteCodes = new ByteArrayOutputStream();
        CountingOutputStream countingByteCodes = new CountingOutputStream(byteCodes);

        countingByteCodes.write(JavaOpcode.LDC);
        countingByteCodes.write(x86CountIndex);
        countingByteCodes.write(JavaOpcode.ISTORE);
        countingByteCodes.write(VARIABLE_EXECUTE_COUNT_INDEX);

        for (int i=0; i<externalEffects.size(); i++) {
            ProtectedModeRPNNode rpn = (ProtectedModeRPNNode) externalEffects.get(i);
	    rpn.write(countingByteCodes, cf, false);
        }
        
        int index = 0;
        ProtectedModeRPNNode[] roots = new ProtectedModeRPNNode[affectedCount];
        for (Iterator itt = currentElements.values().iterator(); itt.hasNext();) {
            ProtectedModeRPNNode rpn = (ProtectedModeRPNNode) itt.next();            
            if (rpn.getMicrocode() == -1)
                continue;
	    
	    rpn.write(countingByteCodes, cf, true);
	    roots[index++] = rpn;
        }
        
        for (int i=index-1; i>=0; i--)
	    RPNNode.writeBytecodes(countingByteCodes, cf, ProtectedModeBytecodeFragments.popCode(roots[i].getID()));
	
        countingByteCodes.write(JavaOpcode.ILOAD);
        countingByteCodes.write(VARIABLE_EXECUTE_COUNT_INDEX);
        countingByteCodes.write(JavaOpcode.IRETURN);

	AttributeInfo.CodeAttribute.ExceptionEntry[] exceptionTable = new AttributeInfo.CodeAttribute.ExceptionEntry[exceptionHandlers.size()];
	int j = 0;
	for (int i = 0; i < exceptionHandlers.size(); i++) {
	    int handlerPC = countingByteCodes.position();
	    ExceptionHandler handler = (ExceptionHandler)exceptionHandlers.get(i);
	    if (!handler.used())
		continue;
	    handler.write(countingByteCodes, cf);
	    exceptionTable[j++] = new AttributeInfo.CodeAttribute.ExceptionEntry(handler.start(), handler.end(), handlerPC, cf.addToConstantPool(ProcessorException.class));
	}

	AttributeInfo.CodeAttribute.ExceptionEntry[] et = new AttributeInfo.CodeAttribute.ExceptionEntry[j];
        System.arraycopy(exceptionTable, 0, et, 0, et.length);
        exceptionTable = et;
//  	exceptionTable = (AttributeInfo.CodeAttribute.ExceptionEntry[]) Arrays.copyOf(exceptionTable, j);

        byte[] bytes = byteCodes.toByteArray();
        
        int[] ints = new int[bytes.length];
        for(int i = 0; i < ints.length; i++)
            ints[i] = 0xff & bytes[i];

	cf.setMethodCode("execute", ints);

	cf.setMethodExceptionTable("execute", exceptionTable);
    }

    private static void compileRealModeExecuteMethod(MicrocodeNode[] microcodes, ClassFile cf, int x86CountIndex) throws IOException
    {
        List externalEffects = new ArrayList();
        Map currentElements = new HashMap();

	List exceptionHandlers = new ArrayList();
	ExceptionHandler currentExceptionHandler = null;

        //set all initial elements to their processor values
        for (int i=0; i<PROCESSOR_ELEMENT_COUNT; i++)
            currentElements.put(new Integer(i), new RealModeRPNNode(i, null));
        
	int lastX86Position = 0;

        for (int i=0; i<microcodes.length; i++) {
            MicrocodeNode node = microcodes[i];
            int uCode = node.getMicrocode();
            
            Object[] codes = RealModeBytecodeFragments.getTargetsOf(uCode);
            if (codes == null)
                throw new IllegalStateException("Unimplemented Microcode: "+MicrocodeNode.getName(uCode));
            
            List targets = new ArrayList();
            for(int j=0; j < codes.length; j++) {               
                if (codes[j] == null)
                    continue;
                
                RealModeRPNNode rpn = new RealModeRPNNode(j, node);
                if (rpn.hasExternalEffect())
                    externalEffects.add(rpn);

		if (rpn.canThrowException()) {
		    if ((currentExceptionHandler == null) || (currentExceptionHandler.getX86Index() != rpn.getX86Index())) {
			currentExceptionHandler = new RealModeExceptionHandler(lastX86Position, rpn, new HashMap(currentElements));
			exceptionHandlers.add(currentExceptionHandler);
		    }
		    rpn.attachExceptionHandler(currentExceptionHandler);
		}

                targets.add(rpn);
                
                int[] argIds = RealModeBytecodeFragments.getOperands(j, uCode);
                if (argIds == null)
                    System.out.println("NULL IDS FOR: "+j+"  "+uCode);
                
                for (int k=0; k<argIds.length; k++) {
                    RealModeRPNNode arg = (RealModeRPNNode) currentElements.get(new Integer(argIds[k]));
                    rpn.linkTo(arg);
                }
            }
            
            for (int j=0; j<targets.size(); j++) {
                RealModeRPNNode rpn = (RealModeRPNNode) targets.get(j);
                currentElements.put(new Integer(rpn.getID()), rpn);
            }
	    	    
	    if (((i+1) < microcodes.length) && (node.getX86Position() != microcodes[i+1].getX86Position()))
		lastX86Position = node.getX86Position();
        }
        
        for (int i=PROCESSOR_ELEMENT_COUNT; i < ELEMENT_COUNT; i++)
            currentElements.remove(new Integer(i));
        
        int localVariableIndex = VARIABLE_OFFSET;
        for (int i=0; i<externalEffects.size(); i++)
	    localVariableIndex = ((RealModeRPNNode)externalEffects.get(i)).markSubtrees(localVariableIndex);
        
        int affectedCount = 0;
	for (Iterator itt = currentElements.values().iterator(); itt.hasNext();) {
            RealModeRPNNode rpn = (RealModeRPNNode) itt.next();

            if (rpn.getMicrocode() == -1)
                continue;

            affectedCount++;
            localVariableIndex = rpn.markSubtrees(localVariableIndex);
        }
        
        ByteArrayOutputStream byteCodes = new ByteArrayOutputStream();
        CountingOutputStream countingByteCodes = new CountingOutputStream(byteCodes);

        countingByteCodes.write(JavaOpcode.LDC);
        countingByteCodes.write(x86CountIndex);
        countingByteCodes.write(JavaOpcode.ISTORE);
        countingByteCodes.write(VARIABLE_EXECUTE_COUNT_INDEX);
        for (int i=0; i<externalEffects.size(); i++) {
            RealModeRPNNode rpn = (RealModeRPNNode) externalEffects.get(i);
	    rpn.write(countingByteCodes, cf, false);
        }
        
        int index = 0;
        RealModeRPNNode[] roots = new RealModeRPNNode[affectedCount];
        for (Iterator itt = currentElements.values().iterator(); itt.hasNext();) {
            RealModeRPNNode rpn = (RealModeRPNNode) itt.next();            
            if (rpn.getMicrocode() == -1)
                continue;
	    rpn.write(countingByteCodes, cf, true);
	    roots[index++] = rpn;
        }
        
        for (int i=index-1; i>=0; i--) {
	    RPNNode.writeBytecodes(countingByteCodes, cf, RealModeBytecodeFragments.popCode(roots[i].getID()));
	}
	
        countingByteCodes.write(JavaOpcode.ILOAD);
        countingByteCodes.write(VARIABLE_EXECUTE_COUNT_INDEX);
        countingByteCodes.write(JavaOpcode.IRETURN);

	AttributeInfo.CodeAttribute.ExceptionEntry[] exceptionTable = new AttributeInfo.CodeAttribute.ExceptionEntry[exceptionHandlers.size()];
	int j = 0;
	for (int i = 0; i < exceptionHandlers.size(); i++) {
	    int handlerPC = countingByteCodes.position();
	    ExceptionHandler handler = (ExceptionHandler)exceptionHandlers.get(i);
	    if (!handler.used())
		continue;
	    handler.write(countingByteCodes, cf);
	    exceptionTable[j++] = new AttributeInfo.CodeAttribute.ExceptionEntry(handler.start(), handler.end(), handlerPC, cf.addToConstantPool(ProcessorException.class));
	}

	AttributeInfo.CodeAttribute.ExceptionEntry[] et = new AttributeInfo.CodeAttribute.ExceptionEntry[j];
        System.arraycopy(exceptionTable, 0, et, 0, et.length);
        exceptionTable = et;
// 	exceptionTable = (AttributeInfo.CodeAttribute.ExceptionEntry[]) Arrays.copyOf(exceptionTable, j);

        byte[] bytes = byteCodes.toByteArray();
        
        int[] ints = new int[bytes.length];
        for(int i = 0; i < ints.length; i++)
            ints[i] = 0xff & bytes[i];

	cf.setMethodCode("execute", ints);

	cf.setMethodExceptionTable("execute", exceptionTable);
    }
    
    private static void compileX86CountMethod(ClassFile cf, int x86CountIndex)
    {
        ByteArrayOutputStream byteCodes = new ByteArrayOutputStream();
        
        byteCodes.write(JavaOpcode.LDC);
        byteCodes.write(x86CountIndex);
        byteCodes.write(JavaOpcode.IRETURN);
        
        byte[] bytes = byteCodes.toByteArray();
        
        int[] ints = new int[bytes.length];
        for(int i = 0; i < ints.length; i++)
            ints[i] = 0xff & bytes[i];
        
        cf.setMethodCode("getX86Count", ints);
    }

    private static void compileX86LengthMethod(ClassFile cf, int x86LengthIndex)
    {
        ByteArrayOutputStream byteCodes = new ByteArrayOutputStream();
        
        byteCodes.write(JavaOpcode.LDC);
        byteCodes.write(x86LengthIndex);
        byteCodes.write(JavaOpcode.IRETURN);
        
        byte[] bytes = byteCodes.toByteArray();
        
        int[] ints = new int[bytes.length];
        for(int i = 0; i < ints.length; i++)
            ints[i] = 0xff & bytes[i];
        
        cf.setMethodCode("getX86Length", ints);
    }

    private static void dumpClass(ClassFile cls)
    {
	try {
	    File dump = new File(cls.getClassName().replace('.','/') + ".class");
	    dump.getParentFile().mkdirs();
	    cls.write(new DataOutputStream(new FileOutputStream(dump)));
	} catch (Exception f) {
	    System.err.println("Attempt to save class file to disk failed: " + f);
	}
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -